committing-code
Imported from alexei-led/cc-thingz/dist/claude/dev-flow/skills/committing-code.
Install
npx skills add https://github.com/alexei-led/cc-thingz/tree/master/dist/claude/dev-flow/skills/committing-code
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install alexei-led-cc-thingz@llmmart
git clone https://github.com/alexei-led/cc-thingz.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole alexei-led/cc-thingz collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Commit Changes
Group the working-tree changes by purpose and commit them as normal commits. Done
when each intended change is in one logical commit and the final git status is
shown.
Gather state
Run scripts/commit-state.sh gather. It is read-only and prints repo state,
changed paths, diff stats, suspicious paths, and recent commits. Without it, run
git status, git diff --stat, and git log --oneline -8. Read the full diff
(scripts/commit-state.sh full-diff) when the stats do not make the grouping
obvious. Treat the helper output as a hint, not proof.
Stop and report the state verbatim when there is nothing to commit, the directory is not a git repository, HEAD is detached, or a rebase or merge is in progress.
Group
- One purpose, a few files, and no suspicious paths: one commit. Do not invent a split.
- Mixed changes: group by purpose (feature, fix, refactor, docs, CI or config) from diff evidence, not filenames. Keep a change and its tests together.
- Match the message style of recent commits. Read conventions.md when there is no history to match or the user asks for a specific format.
Propose and commit
Show the plan and the evidence it rests on:
Based on: git status, diff stat, last 8 commits (style: conventional)
1. fix(validation): reject empty email
- src/validation.ts
- tests/validation.test.ts
2. docs: document the --dry-run flag
- README.md
An explicit commit request authorizes staging and committing this plan. Proceed without a second approval, and do not ask again for each group. Ask first only when the user rejects the grouping, or when the scope, sensitive content, or a history-changing action differs from what was requested.
Hard rules:
- Never stage likely secrets:
.envfiles, private keys, certificates, credential or token files, or files whose content looks like a secret. Flag each one to the user. This check does not replace a secret scanner. - If a pre-commit hook rejects a commit, report its error verbatim. Do not retry
with
--no-verifyand do not amend.
Report
Show the created commits, the final git status, and any files left uncommitted.
Files (cc-thingz)
-
references
-
conventions.md 888 B
# Commit Conventions Read when the repo has no recent commits to match, or the user asks for a format. - Use [Conventional Commits](https://www.conventionalcommits.org/) when recent history or `CONTRIBUTING.md` uses it. Pick the most specific type; use a scope only when the repo uses scopes consistently. - Mark a breaking change with `!` after the type or scope and a `BREAKING CHANGE:` footer that names the migration. - Subject: imperative, no trailing period, at most 72 characters. Wrap the body at 72 characters. - Add a body only when the reason, a side effect, a migration, or a root cause is not obvious from the diff. - In a repo without Conventional Commits, copy the style of the last five commits: capitalization, tense, length, issue references (`fixes #42`), and trailers such as `Co-authored-by:` or `Signed-off-by:`. Do not introduce a new convention.
-
-
scripts
-
commit-state.sh 3.6 KB
#!/usr/bin/env bash # Read-only git change summary for the committing-code skill. # Helps the model avoid rebuilding the same inspection shell every time. set -euo pipefail usage() { cat <<'EOF' Usage: commit-state.sh [gather|full-diff|paths|suspicious] Commands: gather Print repo state, changed paths, diff stats, suspicious paths, recent commits full-diff Print git diff against HEAD paths Print changed and untracked paths suspicious Print only suspicious paths EOF } ensure_git_repo() { git rev-parse --show-toplevel >/dev/null 2>&1 || { echo "Not a git repository" >&2 exit 2 } } repo_root() { git rev-parse --show-toplevel } branch_name() { git symbolic-ref --quiet --short HEAD 2>/dev/null || echo "DETACHED" } rebase_or_merge_state() { local git_dir git_dir=$(git rev-parse --git-dir) if [ -f "$git_dir/MERGE_HEAD" ]; then echo "merge in progress" return fi if [ -d "$git_dir/rebase-merge" ] || [ -d "$git_dir/rebase-apply" ]; then echo "rebase in progress" return fi if [ "$(branch_name)" = "DETACHED" ]; then echo "detached HEAD" return fi if [ -f "$git_dir/CHERRY_PICK_HEAD" ]; then echo "cherry-pick in progress" return fi if [ -f "$git_dir/REVERT_HEAD" ]; then echo "revert in progress" return fi if [ -f "$git_dir/BISECT_LOG" ]; then echo "bisect in progress" return fi echo "clean" } has_head() { git rev-parse --verify --quiet HEAD >/dev/null } changed_paths() { { if has_head; then git diff --name-only HEAD else git diff --cached --name-only fi git ls-files --others --exclude-standard } | awk 'NF' | sort -u } suspicious_path_names() { changed_paths | awk ' BEGIN { IGNORECASE = 1 } /(^|\/)[.]env($|[.])|\.pem$|\.key$|\.p12$|credentials|secret|password|token/ { print } ' } suspicious_content_paths() { local path changed_paths | while IFS= read -r path; do [ -f "$path" ] || continue if grep -Eiq -- '(api[_-]?key|access[_-]?token|auth[_-]?token|secret|password|private[ -]?key)' "$path"; then printf '%s\n' "$path" fi done | sort -u } suspicious_paths() { { suspicious_path_names suspicious_content_paths } | sort -u } status_short() { git status --short } shortstat() { if has_head; then git diff --shortstat HEAD || true else git diff --cached --shortstat || true fi } diff_stat() { if has_head; then git diff --stat HEAD else git diff --cached --stat fi } recent_log() { git log --oneline -8 2>/dev/null || true } gather() { ensure_git_repo local root branch state file_count suspicious_count root=$(repo_root) branch=$(branch_name) state=$(rebase_or_merge_state) file_count=$(changed_paths | awk 'NF{n++} END{print n+0}') # shellcheck disable=SC2016 suspicious_count=$(suspicious_paths | awk 'NF{n++} END{print n+0}') printf 'REPO_ROOT\n%s\n\n' "$root" printf 'BRANCH\n%s\n\n' "$branch" printf 'REPO_STATE\n%s\n\n' "$state" printf 'CHANGED_FILE_COUNT\n%s\n\n' "$file_count" printf 'STATUS_SHORT\n' status_short || true printf '\nDIFF_SHORTSTAT\n' shortstat printf '\nDIFF_STAT\n' diff_stat || true printf '\nCHANGED_PATHS\n' changed_paths || true printf '\nSUSPICIOUS_PATH_COUNT\n%s\n\n' "$suspicious_count" printf 'SUSPICIOUS_PATHS\n' suspicious_paths || true printf '\nRECENT_COMMITS\n' recent_log || true } cmd=${1:-gather} case "$cmd" in gather) gather ;; full-diff) ensure_git_repo if has_head; then git diff HEAD else git diff --cached fi ;; paths) ensure_git_repo changed_paths ;; suspicious) ensure_git_repo suspicious_paths ;; -h | --help | help) usage ;; *) echo "Error: unknown command: $cmd" >&2 usage >&2 exit 2 ;; esac
-
-
SKILL.md 2.6 KB
--- {"allowed-tools":["Bash(git status *)","Bash(git diff *)","Bash(git log *)","Bash(git show *)","Bash(git branch *)","Bash(git add *)","Bash(git commit *)","Bash(scripts/commit-state.sh *)"],"context":"fork","description":"Create normal git commits with logical grouping. Use when committing, saving changes, creating commits, or grouping work into commits. NOT for amending, rebasing, force-pushing, or rewriting history.","name":"committing-code","user-invocable":true} --- # Commit Changes Group the working-tree changes by purpose and commit them as normal commits. Done when each intended change is in one logical commit and the final `git status` is shown. ## Gather state Run `scripts/commit-state.sh gather`. It is read-only and prints repo state, changed paths, diff stats, suspicious paths, and recent commits. Without it, run `git status`, `git diff --stat`, and `git log --oneline -8`. Read the full diff (`scripts/commit-state.sh full-diff`) when the stats do not make the grouping obvious. Treat the helper output as a hint, not proof. Stop and report the state verbatim when there is nothing to commit, the directory is not a git repository, HEAD is detached, or a rebase or merge is in progress. ## Group - One purpose, a few files, and no suspicious paths: one commit. Do not invent a split. - Mixed changes: group by purpose (feature, fix, refactor, docs, CI or config) from diff evidence, not filenames. Keep a change and its tests together. - Match the message style of recent commits. Read [conventions.md](references/conventions.md) when there is no history to match or the user asks for a specific format. ## Propose and commit Show the plan and the evidence it rests on: ```text Based on: git status, diff stat, last 8 commits (style: conventional) 1. fix(validation): reject empty email - src/validation.ts - tests/validation.test.ts 2. docs: document the --dry-run flag - README.md ``` An explicit commit request authorizes staging and committing this plan. Proceed without a second approval, and do not ask again for each group. Ask first only when the user rejects the grouping, or when the scope, sensitive content, or a history-changing action differs from what was requested. Hard rules: - Never stage likely secrets: `.env` files, private keys, certificates, credential or token files, or files whose content looks like a secret. Flag each one to the user. This check does not replace a secret scanner. - If a pre-commit hook rejects a commit, report its error verbatim. Do not retry with `--no-verify` and do not amend. ## Report Show the created commits, the final `git status`, and any files left uncommitted.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.