Skip to content

Commit 0f6fcb3

Browse files
committed
Initial commit
0 parents  commit 0f6fcb3

File tree

21 files changed

+3148
-0
lines changed

21 files changed

+3148
-0
lines changed

.claude/rules/testing.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Testing
2+
3+
This project uses [Bats](https://github.com/bats-core/bats-core) (Bash Automated Testing System) for testing the shell scripts.
4+
5+
## Running Tests
6+
7+
```bash
8+
# Run all tests
9+
bats tests/
10+
11+
# Run specific test file
12+
bats tests/install.bats
13+
bats tests/sync.bats
14+
bats tests/validation.bats
15+
16+
# Run with verbose output (show test names)
17+
bats --tap tests/
18+
```
19+
20+
## Test Structure
21+
22+
```
23+
tests/
24+
├── test_helper.bash # Shared setup/teardown and utilities
25+
├── install.bats # Tests for install.sh
26+
├── sync.bats # Tests for sync.sh commands
27+
└── validation.bats # Tests for skills validation
28+
```
29+
30+
## Writing Tests
31+
32+
### Test File Format
33+
34+
```bash
35+
#!/usr/bin/env bats
36+
37+
load 'test_helper'
38+
39+
setup() {
40+
setup_test_env
41+
}
42+
43+
teardown() {
44+
teardown_test_env
45+
}
46+
47+
@test "description of what this tests" {
48+
# Arrange
49+
create_fake_skill "my-skill"
50+
51+
# Act
52+
run_install
53+
54+
# Assert
55+
assert_symlink "$FAKE_HOME/.claude/skills/my-skill" "$FAKE_REPO/skills/my-skill"
56+
}
57+
```
58+
59+
### Key Conventions
60+
61+
1. **Always use the test environment** - Call `setup_test_env` in setup and `teardown_test_env` in teardown
62+
2. **Use helper functions** - Use `run_install`, `run_sync`, `create_fake_skill`, etc. from test_helper.bash
63+
3. **Test in isolation** - Tests use temp directories (`$FAKE_HOME`, `$FAKE_REPO`) and never touch real config
64+
65+
### Available Test Helpers
66+
67+
**Environment:**
68+
- `setup_test_env` - Creates isolated temp directories
69+
- `teardown_test_env` - Cleans up temp directories
70+
- `$FAKE_HOME` - Temp directory simulating user's home
71+
- `$FAKE_REPO` - Temp directory simulating the repo
72+
73+
**Creating Test Data:**
74+
- `create_fake_skill "name"` - Creates a valid skill with SKILL.md
75+
- `create_invalid_skill "name"` - Creates skill without frontmatter
76+
- `create_skill_no_md "name"` - Creates skill without SKILL.md
77+
- `create_fake_agent "name"` - Creates an agent file
78+
- `create_fake_rule "name"` - Creates a rule file
79+
- `create_fake_settings` - Creates settings.json
80+
- `create_fake_statusline` - Creates statusline.sh
81+
82+
**Running Scripts:**
83+
- `run_install [args]` - Runs install.sh in test environment
84+
- `run_sync [args]` - Runs sync.sh in test environment
85+
86+
**Assertions:**
87+
- `assert_symlink "path" "expected_target"` - Verifies symlink exists and points to target
88+
- `assert_regular_file "path"` - Verifies file exists and is not a symlink
89+
- `assert_dir "path"` - Verifies directory exists
90+
- `assert_backup_exists` - Verifies a backup was created
91+
- `assert_manifest_operation "op"` - Verifies manifest contains operation
92+
93+
**Backup Helpers:**
94+
- `get_latest_backup` - Returns name of most recent backup
95+
96+
### Testing Tips
97+
98+
1. **Test both success and failure cases** - Verify error messages and exit codes
99+
2. **Test dry-run mode** - Ensure `--dry-run` doesn't modify anything
100+
3. **Test idempotency** - Running the same command twice should work
101+
4. **Group related tests** - Use comment headers to organize test sections
102+
103+
## Adding New Tests
104+
105+
When adding new functionality to install.sh or sync.sh:
106+
107+
1. Add tests to the appropriate .bats file
108+
2. Add any new helper functions to test_helper.bash
109+
3. Run `bats tests/` to verify all tests pass
110+
4. Consider edge cases (missing files, conflicts, dry-run)
111+
112+
## CI Integration
113+
114+
Tests run automatically on push/PR via GitHub Actions. See `.github/workflows/test.yml`.
115+
116+
The workflow:
117+
1. Runs on `macos-latest` (matches dev environment)
118+
2. Installs bats-core via Homebrew
119+
3. Runs all tests with `bats tests/`
120+
4. Validates all skills with `./sync.sh validate`
121+
122+
To run locally before pushing:
123+
```bash
124+
bats tests/ && ./sync.sh validate
125+
```

.claude/rules/workflows.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Workflows
2+
3+
## Setting up on a new machine
4+
5+
```bash
6+
git clone git@github.com:brianlovin/claude-config.git ~/Developer/claude-config
7+
cd ~/Developer/claude-config
8+
./install.sh
9+
```
10+
11+
Creates symlinks from `~/.claude/` to this repo. Local-only items are preserved.
12+
13+
### Dry-run mode
14+
15+
Preview what would happen without making changes:
16+
17+
```bash
18+
./install.sh --dry-run
19+
```
20+
21+
### Handling conflicts
22+
23+
If a local file differs from the repo version, you'll be prompted:
24+
- `[r]` Use repo version (backs up local first)
25+
- `[l]` Keep local version (skip this item)
26+
- `[d]` Show diff between versions
27+
- `[q]` Quit
28+
29+
Use `--force` to automatically use repo versions (still creates backups).
30+
31+
## Sync status legend
32+
33+
```bash
34+
./sync.sh
35+
```
36+
37+
Shows status grouped by type (Skills, Agents, Rules):
38+
39+
- `` synced (symlinked to this repo)
40+
- `` local only (not in repo)
41+
- `` conflict (exists in both - run `./install.sh` to fix)
42+
- `` external (symlinked elsewhere)
43+
44+
## Adding items to sync across machines
45+
46+
```bash
47+
./sync.sh add skill <name> # Add a skill directory
48+
./sync.sh add agent <name> # Add an agent file (without .md extension)
49+
./sync.sh add rule <name> # Add a rule file (without .md extension)
50+
./sync.sh push
51+
```
52+
53+
Copies the item to repo, replaces local with symlink, prompts for commit.
54+
55+
Skills are validated before adding - must have SKILL.md with `name` and `description` in frontmatter.
56+
57+
## Removing items from repo
58+
59+
```bash
60+
./sync.sh remove skill <name>
61+
./sync.sh remove agent <name>
62+
./sync.sh remove rule <name>
63+
./sync.sh push
64+
```
65+
66+
Removes from repo but keeps local copy.
67+
68+
## Backups and undo
69+
70+
All destructive operations create timestamped backups in `.backup/`.
71+
72+
```bash
73+
./sync.sh backups # List available backups
74+
./sync.sh undo # Restore from last backup
75+
./sync.sh undo --dry-run # Preview what would be restored
76+
```
77+
78+
## Validating skills
79+
80+
Check that all skills have valid SKILL.md files:
81+
82+
```bash
83+
./sync.sh validate
84+
```
85+
86+
Skills must have frontmatter with `name` and `description`:
87+
88+
```yaml
89+
---
90+
name: my-skill
91+
description: What this skill does
92+
---
93+
```
94+
95+
## Dry-run mode
96+
97+
Preview any command without making changes:
98+
99+
```bash
100+
./sync.sh --dry-run add skill my-skill
101+
./sync.sh -n remove agent my-agent
102+
./install.sh --dry-run
103+
```
104+
105+
## Keeping items local-only
106+
107+
Any item in `~/.claude/` that isn't symlinked stays local. The install script only creates symlinks for what's in this repo—it never deletes local files.
108+
109+
Use this for work-specific or experimental items.
110+
111+
## Directory structure
112+
113+
```
114+
~/.claude/
115+
├── skills/ # Skill directories (each has SKILL.md)
116+
├── agents/ # Subagent markdown files
117+
├── rules/ # Rule markdown files
118+
├── settings.json
119+
└── statusline.sh
120+
```

.github/workflows/test.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
runs-on: macos-latest
12+
steps:
13+
- name: Checkout
14+
uses: actions/checkout@v4
15+
16+
- name: Install bats
17+
run: brew install bats-core
18+
19+
- name: Run tests
20+
run: bats tests/
21+
22+
- name: Validate skills
23+
run: ./sync.sh validate

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.backup/
2+
.DS_Store

CLAUDE.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Claude Config
2+
3+
Personal Claude Code settings, skills, agents, and rules, synced across machines via symlinks.
4+
5+
## Commands
6+
7+
```bash
8+
./install.sh # Set up symlinks (run after cloning)
9+
./install.sh --dry-run # Preview what would be done
10+
./sync.sh # Show sync status
11+
./sync.sh add <type> <name> # Add a local item to repo
12+
./sync.sh remove <type> <name> # Remove item from repo (keeps local)
13+
./sync.sh pull # Pull latest and reinstall symlinks
14+
./sync.sh push # Commit and push changes
15+
./sync.sh undo # Restore from last backup
16+
./sync.sh validate # Validate all skills
17+
./sync.sh backups # List available backups
18+
bats tests/ # Run tests
19+
```
20+
21+
Types: `skill`, `agent`, `rule`
22+
23+
## Testing
24+
25+
Tests use Bats. Run `bats tests/` to execute all tests. Tests run in isolated temp directories.
26+
27+
See [.claude/rules/testing.md](.claude/rules/testing.md) for testing conventions.
28+
29+
## Key Files
30+
31+
- `install.sh` - Creates symlinks from ~/.claude to this repo
32+
- `sync.sh` - Manages syncing items between local and repo
33+
- `tests/` - Bats test suite
34+
35+
For detailed workflows, see [.claude/rules/workflows.md](.claude/rules/workflows.md).

0 commit comments

Comments
 (0)