Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 4 additions & 94 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,102 +8,12 @@ on:

jobs:
validate:
name: Validate Plugin Structure
name: Validate Plugin
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Validate plugin.json
run: |
if ! python3 -c "import json; json.load(open('src/dot-claude-plugin/plugin.json'))"; then
echo "Error: plugin.json is not valid JSON"
exit 1
fi
echo "plugin.json is valid"

- name: Check required files exist
run: |
required_files=(
"src/dot-claude-plugin/plugin.json"
"src/commands/lookagain.md"
"src/agents/lookagain-reviewer.md"
"src/skills/lookagain-output-format/SKILL.md"
"README.md"
"LICENSE"
"CHANGELOG.md"
)

missing=0
for file in "${required_files[@]}"; do
if [[ ! -f "$file" ]]; then
echo "Missing: $file"
missing=1
else
echo "Found: $file"
fi
done

if [[ $missing -eq 1 ]]; then
exit 1
fi

- name: Validate plugin.json references
run: |
# Check that referenced commands, agents, skills exist
commands=$(python3 -c "import json; print('\n'.join(json.load(open('src/dot-claude-plugin/plugin.json')).get('commands', [])))")
agents=$(python3 -c "import json; print('\n'.join(json.load(open('src/dot-claude-plugin/plugin.json')).get('agents', [])))")
skills=$(python3 -c "import json; print('\n'.join(json.load(open('src/dot-claude-plugin/plugin.json')).get('skills', [])))")

errors=0

for cmd in $commands; do
if [[ ! -f "src/commands/$cmd.md" ]]; then
echo "Error: Command '$cmd' referenced but src/commands/$cmd.md not found"
errors=1
fi
done

for agent in $agents; do
if [[ ! -f "src/agents/$agent.md" ]]; then
echo "Error: Agent '$agent' referenced but src/agents/$agent.md not found"
errors=1
fi
done

for skill in $skills; do
if [[ ! -f "src/skills/$skill/SKILL.md" ]]; then
echo "Error: Skill '$skill' referenced but src/skills/$skill/SKILL.md not found"
errors=1
fi
done

if [[ $errors -eq 1 ]]; then
exit 1
fi

echo "All plugin.json references are valid"

- name: Test package script
run: |
chmod +x scripts/package.sh
./scripts/package.sh

# Verify output structure
if [[ ! -d "dist/lookagain/.claude" ]]; then
echo "Error: dist/lookagain/.claude not created"
exit 1
fi

if [[ ! -d "dist/lookagain/.claude-plugin" ]]; then
echo "Error: dist/lookagain/.claude-plugin not created"
exit 1
fi

if ! ls dist/lookagain-v*.zip 1>/dev/null 2>&1; then
echo "Error: zip archive not created"
exit 1
fi

echo "Package script completed successfully"
- name: Run tests
run: make test
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Validate tag matches plugin version
run: |
Expand Down Expand Up @@ -48,10 +48,10 @@ jobs:
fi

# Write to file to preserve newlines
echo "$changelog" > release_notes.md
printf '%s\n' "$changelog" > release_notes.md

- name: Create GitHub Release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
with:
body_path: release_notes.md
files: dist/lookagain-v*.zip
Expand Down
78 changes: 78 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Contributing to lookagain

## Development Setup

1. Clone the repository:
```bash
git clone https://github.com/HartBrook/lookagain.git
cd lookagain
```

2. Ensure you have [Claude Code](https://claude.ai/code) installed.

## Project Structure

```
lookagain/
├── src/
│ ├── commands/ # Plugin commands
│ │ └── again.md # Main orchestrator
│ ├── agents/ # Subagent definitions
│ │ └── lookagain-reviewer.md
│ ├── skills/ # Output format specs
│ │ └── lookagain-output-format/
│ ├── dot-claude-plugin/ # Plugin manifest (becomes .claude-plugin/)
│ └── dot-claude/ # Claude settings (becomes .claude/)
├── scripts/
│ ├── package.sh # Build script
│ └── test.sh # Plugin validation tests
├── dist/ # Build output (git-ignored)
└── Makefile
```

## Development Workflow

### Build and Test Locally

```bash
# Build and start Claude Code with the plugin loaded
make dev

# Or just build without starting
make build

# Clean build artifacts
make clean

# Show all available commands
make help
```

`make dev` builds the plugin and starts a new Claude Code session with it loaded. Test with `/look:again`.

### Making Changes

1. Edit files in `src/`
2. Run `make dev` to rebuild and start Claude Code with the plugin
3. Test with `/look:again`
4. Exit and repeat

### Key Files

- **[src/commands/again.md](src/commands/again.md)**: Main orchestrator logic. Controls pass execution, auto-fixing, and aggregation.
- **[src/agents/lookagain-reviewer.md](src/agents/lookagain-reviewer.md)**: Reviewer subagent. Defines how individual review passes work.
- **[src/skills/lookagain-output-format/SKILL.md](src/skills/lookagain-output-format/SKILL.md)**: JSON output format specification.
- **[src/dot-claude-plugin/plugin.json](src/dot-claude-plugin/plugin.json)**: Plugin metadata and version.

## Pull Requests

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/my-feature`)
3. Make your changes
4. Test locally with `make dev`
5. Commit with a clear message
6. Open a pull request

## Versioning

Update the version in `src/dot-claude-plugin/plugin.json` when making releases.
20 changes: 20 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.PHONY: help build test dev clean

help: ## Show this help
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}'

build: ## Build the plugin (creates dist/)
@./scripts/package.sh

test: ## Run plugin validation tests
@./scripts/test.sh

dev: build ## Build and start Claude Code with plugin loaded
@echo ""
@echo "Starting Claude Code with plugin loaded..."
@echo ""
@claude --plugin-dir ./dist/lookagain

clean: ## Remove build artifacts
@rm -rf dist/
@echo "Cleaned dist/"
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ A single code review pass catches ~60-70% of issues. Running multiple independen

```
┌─────────────────────────────────────────────────────┐
│ /lookagain
│ /look:again
│ │
│ ┌───────────────────────────────────────────┐ │
│ │ Orchestrator (main agent) │ │
Expand Down Expand Up @@ -45,19 +45,19 @@ A single code review pass catches ~60-70% of issues. Running multiple independen

```bash
# Basic: 3 review passes with auto-fix for must_fix issues
/lookagain
/look:again

# More passes for critical code
/lookagain passes=5
/look:again passes=5

# Review specific directory
/lookagain target=src/auth
/look:again target=src/auth

# Disable auto-fix (review only)
/lookagain auto-fix=false
/look:again auto-fix=false

# Increase max passes for stubborn issues
/lookagain passes=3 max-passes=10
/look:again passes=3 max-passes=10
```

## How It Works
Expand Down
5 changes: 2 additions & 3 deletions scripts/package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
DIST_DIR="$PROJECT_ROOT/dist"

# Get version from plugin.json
VERSION=$(grep -o '"version": *"[^"]*"' "$PROJECT_ROOT/src/dot-claude-plugin/plugin.json" | cut -d'"' -f4)
VERSION=$(python3 -c "import json; print(json.load(open('$PROJECT_ROOT/src/dot-claude-plugin/plugin.json'))['version'])")

if [[ -z "$VERSION" ]]; then
echo "Error: Could not extract version from plugin.json"
Expand All @@ -35,8 +35,7 @@ cp "$PROJECT_ROOT/LICENSE" "$DIST_DIR/lookagain/"
cp "$PROJECT_ROOT/CHANGELOG.md" "$DIST_DIR/lookagain/"

# Create zip archive
cd "$DIST_DIR"
zip -r "lookagain-v$VERSION.zip" lookagain
(cd "$DIST_DIR" && zip -r "lookagain-v$VERSION.zip" lookagain)

echo ""
echo "Build complete:"
Expand Down
Loading