Add Claude Code hooks and new-credential skill

Hooks:
- PreToolUse: block direct edits to credential files (99-claude, etc.)
- PostToolUse: auto-run shellcheck after editing bash.d scripts

Skill:
- /new-credential: scaffolds a credential file pair (.example template +
  real file), adds to .gitignore, sets permissions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2026-03-06 12:52:56 +01:00
commit ed82cebd16
4 changed files with 130 additions and 0 deletions

View file

@ -0,0 +1,50 @@
---
name: new-credential
description: Create a new bash.d credential file with .example template, .gitignore entry, and correct permissions
user-invocable: true
disable-model-invocation: true
arguments:
- name: name
description: "Short name for the credential (e.g. 'openai', 'stripe')"
required: true
- name: var
description: "Environment variable name to export (e.g. 'OPENAI_API_KEY')"
required: true
---
Create a new credential file pair in ~/.bash.d/ following the project conventions.
## Steps
1. **Create the `.example` template** at `99-$name.example` (mode 644):
```bash
# shellcheck shell=bash
# <Description of what this credential is for>
# Copy to 99-$name and fill in your token, then: chmod 700 99-$name
require_private "${BASH_SOURCE[0]}"
export $var=your-token-here
```
2. **Create the real credential file** at `99-$name` (mode 700):
```bash
# shellcheck shell=bash
# NOTE: Contains credentials - ensure file permissions remain 600/700
require_private "${BASH_SOURCE[0]}"
export $var=your-token-here
```
3. **Add `99-$name` to `.gitignore`** (append to the existing credential list)
4. **Set permissions**: `chmod 700 99-$name`
5. **Validate both files**: `shellcheck 99-$name.example 99-$name`
6. **Remind the user** to edit `99-$name` and fill in the real secret value
## Rules
- The `.example` template must NOT contain real secrets — use `your-token-here` as placeholder
- The real credential file must have mode `700`
- Both files must start with `# shellcheck shell=bash`
- Both files must call `require_private "${BASH_SOURCE[0]}"` as the first functional line
- Only the `.example` file should be staged in git — verify `99-$name` is gitignored