feat(claude): improve ai workflow
This commit is contained in:
parent
e84a22dbcb
commit
902f0f3ad6
11 changed files with 196 additions and 33 deletions
|
|
@ -14,6 +14,10 @@ If given express permission to use git, NEVER push to a main/master branch.
|
|||
|
||||
If given express permission to use git, NEVER commit ai-related files (e.g. CLAUDE.md).
|
||||
|
||||
If given express permission to use git, ALWAYS work on a feature branch. If on
|
||||
`main` or `master`, create and switch to a branch before making changes. Branch
|
||||
naming: `type/short-description` (e.g. `fix/diagnostic-range`).
|
||||
|
||||
If given express permission to use git, ALWAYS use this commit message format:
|
||||
|
||||
type(scope): imperative summary
|
||||
|
|
@ -21,7 +25,10 @@ If given express permission to use git, ALWAYS use this commit message format:
|
|||
- Valid types: `feat` `fix` `docs` `refactor` `perf` `test` `ci` `build` `revert`
|
||||
- Scope is optional, lowercase. Subject: lowercase after colon, no trailing period, max 72 chars.
|
||||
- Body required for non-trivial commits, using `Problem:` / `Solution:` format.
|
||||
Keep each section to 2-3 sentences.
|
||||
- One logical change per commit. Refactors, formatting, and features must be separate commits.
|
||||
- Use backticks around code identifiers, function names, and file paths in
|
||||
commit messages and PR descriptions (e.g. `setup()`, `lua/oil/view.lua`).
|
||||
|
||||
If given express permission to use git, ALWAYS check for a PR template at
|
||||
`.github/pull_request_template.md` and follow it. If none exists, use
|
||||
|
|
|
|||
25
config/claude/hooks/guard.sh
Executable file
25
config/claude/hooks/guard.sh
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
INPUT=$(cat)
|
||||
CMD=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // empty')
|
||||
|
||||
if printf '%s' "$CMD" | grep -qE '\bgh\b.*\s(-R|--repo)\b'; then
|
||||
echo "Blocked: do not target other repos with -R/--repo. Run gh commands against the current repo only." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if printf '%s' "$CMD" | grep -qE '\bgh\s+issue\s+create\b'; then
|
||||
echo "Blocked: gh issue create must be run manually or explicitly approved." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if printf '%s' "$CMD" | grep -qE '\bgit\s+push\b'; then
|
||||
BRANCH=$(git branch --show-current 2>/dev/null || true)
|
||||
if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "master" ]; then
|
||||
echo "Blocked: never push directly to $BRANCH. Use a feature branch." >&2
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
|
@ -19,36 +19,43 @@ Solution: describe what this commit does
|
|||
### Body
|
||||
|
||||
Required for any non-trivial change. Use `Problem:` / `Solution:` sections.
|
||||
Wrap at 72 characters. Separate from header with a blank line.
|
||||
2-3 sentences per section, max. Wrap at 72 characters. Separate from header
|
||||
with a blank line.
|
||||
|
||||
Use backticks around code identifiers, function names, and file paths
|
||||
(e.g. `setup()`, `lua/oil/view.lua`, `FIELD_NAME`).
|
||||
|
||||
### Examples
|
||||
|
||||
Good:
|
||||
|
||||
```
|
||||
fix(lsp): correct off-by-one in diagnostic range
|
||||
fix(lsp): correct off-by-one in `diagnostic_range`
|
||||
|
||||
Problem: diagnostics highlighted one character past the actual error,
|
||||
causing confusion when multiple diagnostics appeared on adjacent tokens.
|
||||
causing confusion on adjacent tokens.
|
||||
|
||||
Solution: subtract 1 from the end column returned by the language server
|
||||
before converting to 0-indexed nvim columns.
|
||||
Solution: subtract 1 from the end column returned by the language
|
||||
server before converting to 0-indexed nvim columns.
|
||||
```
|
||||
|
||||
```
|
||||
refactor: extract repeated buffer lookup into helper
|
||||
refactor: extract repeated buffer lookup into `get_buf_entry`
|
||||
```
|
||||
|
||||
Bad:
|
||||
|
||||
```
|
||||
Fixed stuff # not imperative, vague
|
||||
feat: Add Feature. # uppercase after colon, trailing period
|
||||
Fixed stuff
|
||||
feat: Add Feature.
|
||||
fix(lsp): correct off-by-one in diagnostic range and also refactor the
|
||||
entire highlight module and add new tests # multiple concerns
|
||||
entire highlight module and add new tests
|
||||
```
|
||||
|
||||
## Branch Naming
|
||||
## Branch Rules
|
||||
|
||||
Always work on a feature branch. Never commit or push directly to `main` or
|
||||
`master`. If on the default branch, create and switch to a topic branch first.
|
||||
|
||||
```
|
||||
type/short-description
|
||||
|
|
@ -65,15 +72,15 @@ If no template exists, fall back to:
|
|||
```
|
||||
## Problem
|
||||
|
||||
<why this change is needed>
|
||||
<1-2 sentences>
|
||||
|
||||
## Solution
|
||||
|
||||
<what the change does>
|
||||
<1-2 sentences>
|
||||
```
|
||||
|
||||
Either way, write in plain prose. No bullet-point walls, no AI-style markdown
|
||||
headings beyond what the template calls for. Keep it concise and human.
|
||||
Write concise prose. No bullet-point walls, no verbose AI-style markdown.
|
||||
Use backticks for code references.
|
||||
|
||||
## Decomposition Rules
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# /commit
|
||||
# /gc
|
||||
|
||||
Create a conventional commit from staged or unstaged changes.
|
||||
|
||||
|
|
@ -26,7 +26,10 @@ Create a conventional commit from staged or unstaged changes.
|
|||
- Scope is optional, lowercase.
|
||||
- Non-trivial changes require a body with `Problem:` / `Solution:` sections,
|
||||
wrapped at 72 chars, separated from header by a blank line.
|
||||
- Keep the body tight: 2-3 sentences per section, max.
|
||||
- Trivial one-liners: header alone is fine.
|
||||
- Use backticks around code identifiers, function names, and file paths
|
||||
(e.g. `setup()`, `lua/pending/store.lua`).
|
||||
- Match the style of the recent commits from step 1.
|
||||
|
||||
4. Present the full message and ask for approval.
|
||||
51
config/claude/skills/guide/SKILL.md
Normal file
51
config/claude/skills/guide/SKILL.md
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# /guide
|
||||
|
||||
Interactive step-by-step guide for nvim plugin development tasks.
|
||||
|
||||
## Instructions
|
||||
|
||||
1. Ask the user what they want to accomplish. Gather enough context to build a
|
||||
step-by-step plan (the plugin name, the goal, any constraints).
|
||||
|
||||
2. Determine the plugin name from the current repo (basename of the working
|
||||
directory) and today's date. Run exactly one Bash command:
|
||||
|
||||
```
|
||||
basename "$(git rev-parse --show-toplevel)" && date +%Y-%m-%d
|
||||
```
|
||||
|
||||
3. Build a numbered step-by-step plan as a markdown file. Run exactly one Bash
|
||||
command:
|
||||
|
||||
```
|
||||
mkdir -p /tmp/<plugin>-<date> && cat > /tmp/<plugin>-<date>/guide.md <<'EOF'
|
||||
# <Goal>
|
||||
|
||||
Plugin: <plugin>
|
||||
Date: <date>
|
||||
Branch: <branch name to create>
|
||||
|
||||
## Steps
|
||||
|
||||
1. <step>
|
||||
2. <step>
|
||||
...
|
||||
|
||||
## Current
|
||||
|
||||
Step 1: <description>
|
||||
EOF
|
||||
```
|
||||
|
||||
4. Present step 1 to the user. Execute it. Show the result. Ask for
|
||||
confirmation before moving to the next step.
|
||||
|
||||
5. After the user confirms, update the `## Current` section in the guide to
|
||||
reflect the next step, then execute it. Repeat until all steps are done.
|
||||
|
||||
6. When all steps are complete, update the guide with a `## Done` section and
|
||||
print the path to the guide file.
|
||||
|
||||
Keep each step small and self-contained. Prefer one logical change per step.
|
||||
If a step reveals unexpected complexity, break it into sub-steps and update
|
||||
the guide before proceeding.
|
||||
|
|
@ -21,28 +21,35 @@ Create a pull request from the current branch.
|
|||
```
|
||||
## Problem
|
||||
|
||||
<why this change is needed>
|
||||
<1-2 sentences>
|
||||
|
||||
## Solution
|
||||
|
||||
<what the change does>
|
||||
<1-2 sentences>
|
||||
```
|
||||
|
||||
- Write in plain prose. No bullet walls, no AI markdown soup.
|
||||
- Write concise prose. No bullet walls, no verbose explanations.
|
||||
- Use backticks around code identifiers, function names, and file paths.
|
||||
|
||||
3. Present the title and body. Ask for approval.
|
||||
|
||||
4. After approval, run exactly one Bash command (push + create chained):
|
||||
4. After approval, if `scripts/ci.sh` exists, run it:
|
||||
```
|
||||
git push -u origin <branch> && gh pr create --title "<title>" --body "$(cat <<'EOF'
|
||||
bash scripts/ci.sh
|
||||
```
|
||||
If it fails, show the output and stop. Do NOT create the PR.
|
||||
|
||||
5. Run exactly one Bash command:
|
||||
```
|
||||
gh pr create --title "<title>" --body "$(cat <<'EOF'
|
||||
<body here>
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
Print the PR URL from the output.
|
||||
|
||||
Total: 2 Bash calls (gather + push/create). Do not run any other commands. Do
|
||||
not read files, explore code, or run additional git commands beyond what is
|
||||
listed above.
|
||||
Total: 2 Bash calls (gather + create), or 3 if CI ran. Do not run any other
|
||||
commands. Do not read files, explore code, or run additional git commands beyond
|
||||
what is listed above.
|
||||
|
||||
Never force-push, even with lease. Never target main/master as the head branch.
|
||||
|
|
|
|||
48
config/claude/skills/qpr/SKILL.md
Normal file
48
config/claude/skills/qpr/SKILL.md
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# /qpr
|
||||
|
||||
Create a pull request immediately, no approval step.
|
||||
|
||||
## Instructions
|
||||
|
||||
1. Run exactly this one Bash command:
|
||||
|
||||
```
|
||||
echo "---BRANCH---" && git branch --show-current && echo "---LOG---" && git log --oneline main..HEAD && echo "---STAT---" && git diff main...HEAD --stat && echo "---TEMPLATE---" && cat .github/pull_request_template.md 2>/dev/null || true
|
||||
```
|
||||
|
||||
If the branch is `main` or `master`, tell the user and stop.
|
||||
|
||||
2. If `scripts/ci.sh` exists, run it:
|
||||
```
|
||||
bash scripts/ci.sh
|
||||
```
|
||||
If it fails, show the output and stop.
|
||||
|
||||
3. Draft the PR (do NOT present for approval — create it immediately):
|
||||
- **Title**: `type(scope): imperative summary`, max 72 chars.
|
||||
- **Body**: if a PR template was found, fill it in. Otherwise:
|
||||
|
||||
```
|
||||
## Problem
|
||||
|
||||
<1-2 sentences>
|
||||
|
||||
## Solution
|
||||
|
||||
<1-2 sentences>
|
||||
```
|
||||
|
||||
- Use backticks around code identifiers, function names, and file paths.
|
||||
|
||||
Run exactly one Bash command:
|
||||
```
|
||||
gh pr create --title "<title>" --body "$(cat <<'EOF'
|
||||
<body here>
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
Print the PR URL from the output.
|
||||
|
||||
Total: 2-3 Bash calls. Do not run any other commands.
|
||||
|
||||
Never force-push. Never target main/master as the head branch.
|
||||
|
|
@ -61,7 +61,7 @@ local git_status = new_git_status()
|
|||
return {
|
||||
{
|
||||
'barrettruth/midnight.nvim',
|
||||
enabled = false,
|
||||
enabled = true,
|
||||
after = function()
|
||||
vim.cmd.colorscheme('midnight')
|
||||
end,
|
||||
|
|
@ -300,6 +300,6 @@ return {
|
|||
latex = { open = { 'sioyek', '--new-instance' } },
|
||||
})
|
||||
end,
|
||||
keys = { { '<leader>p', '<cmd>Preview toggle<cr>' } },
|
||||
keys = { { '<leader>p', '<cmd>Preview watch<cr>' } },
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,12 +225,14 @@ end)
|
|||
return {
|
||||
{
|
||||
'barrettruth/diffs.nvim',
|
||||
enabled = true,
|
||||
before = function()
|
||||
vim.g.diffs = {
|
||||
debug = '/tmp/diffs.log',
|
||||
fugitive = true,
|
||||
neogit = false,
|
||||
extra_filetypes = { 'diff' },
|
||||
hide_prefix = true,
|
||||
hide_prefix = false,
|
||||
highlights = {
|
||||
vim = {
|
||||
enabled = true,
|
||||
|
|
|
|||
|
|
@ -354,6 +354,19 @@ in
|
|||
"api.github.com"
|
||||
];
|
||||
tools.web_fetch = true;
|
||||
hooks = {
|
||||
PreToolUse = [
|
||||
{
|
||||
matcher = "Bash";
|
||||
hooks = [
|
||||
{
|
||||
type = "command";
|
||||
command = "${config.xdg.configHome}/claude/hooks/guard.sh";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -369,6 +382,10 @@ in
|
|||
source = config.lib.file.mkOutOfStoreSymlink "${repoDir}/config/claude/skills";
|
||||
};
|
||||
|
||||
xdg.configFile."claude/hooks" = lib.mkIf claude {
|
||||
source = config.lib.file.mkOutOfStoreSymlink "${repoDir}/config/claude/hooks";
|
||||
};
|
||||
|
||||
xdg.configFile."tmux/themes/midnight.conf".source =
|
||||
config.lib.file.mkOutOfStoreSymlink "${config.home.homeDirectory}/.config/nix/config/tmux/themes/midnight.conf";
|
||||
xdg.configFile."tmux/themes/daylight.conf".source =
|
||||
|
|
|
|||
10
scripts/mux
10
scripts/mux
|
|
@ -145,7 +145,7 @@ ai)
|
|||
;;
|
||||
code)
|
||||
require nvim
|
||||
spawn_or_focus code 'nvim -c "lua require([[config.tmux]]).run([[nvim]])"'
|
||||
spawn_or_focus code 'nvim .'
|
||||
;;
|
||||
git)
|
||||
require nvim git
|
||||
|
|
@ -153,13 +153,9 @@ git)
|
|||
if ! git -C "$pane_path" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||
tmux display-message "Not a git repository"
|
||||
else
|
||||
spawn_or_focus git 'nvim -c "lua require([[config.tmux]]).run([[git]])"'
|
||||
spawn_or_focus git 'nvim -c "Git|only"'
|
||||
fi
|
||||
;;
|
||||
run)
|
||||
require nvim
|
||||
spawn_or_focus run 'nvim -c "lua require([[config.tmux]]).run([[run]])"'
|
||||
;;
|
||||
shell)
|
||||
spawn_or_focus shell
|
||||
;;
|
||||
|
|
@ -178,7 +174,7 @@ cmd)
|
|||
action=$(printf '%s' "$result" | sed -n '2p')
|
||||
[ $rc -eq 130 ] && exit
|
||||
if [ -n "$query" ] && [ "$query" != "$action" ]; then
|
||||
tmux $query
|
||||
tmux "$query"
|
||||
elif [ -n "$action" ]; then
|
||||
case "$action" in
|
||||
switch-client) pick_session ;;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue