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
15 changes: 15 additions & 0 deletions .claude/hooks/post-edit-lint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash
# Auto-format Python files after Edit/Write operations using Taskfile
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

if [ -z "$FILE_PATH" ]; then
exit 0
fi

case "$FILE_PATH" in
*.py)
task lint-file FILE="$FILE_PATH" 2>/dev/null
;;
esac
exit 0
26 changes: 26 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PROJECT_DIR}/.claude/hooks/post-edit-lint.sh"
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "INPUT=$(cat); CMD=$(echo \"$INPUT\" | jq -r '.tool_input.command // empty'); case \"$CMD\" in *'git push --force'*|*'git push -f '*|*'--no-verify'*) echo 'BLOCKED: Force push and --no-verify are not allowed in this project.' >&2; exit 2;; esac; exit 0"
}
]
}
]
}
}
78 changes: 78 additions & 0 deletions .claude/skills/code-reviewer/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
name: code-reviewer
description: Review code changes for best practices, complexity, compatibility, and gaps
user-invocable: true
argument-hint: "[git ref range or 'staged', defaults to develop..HEAD]"
context: fork
agent: general-purpose
allowed-tools: Read, Bash, Grep, Glob
---

# Code Reviewer Skill

Perform a read-only review of code changes for best practices compliance, complexity, compatibility, and gaps.

## Target

Review changes in: `$ARGUMENTS` (default: `develop..HEAD`)

If `$ARGUMENTS` is `staged`, review `git diff --cached` instead.

## Review Checklist

### 1. Best Practices Compliance

Check against the project's `/developer` standards:

- [ ] Docstrings with `Args:`, `Raises:`, `Returns:` on all new/modified functions
- [ ] Pydantic `Field(description=...)` usage on new model fields
- [ ] Complete type hints on all function signatures
- [ ] Tests written for new functionality
- [ ] Documentation updated for user-facing changes

### 2. Complexity Flags

Flag any of these patterns:

- Functions longer than 30 lines
- Nesting deeper than 3 levels
- Functions with more than 5 parameters
- Overly complex conditional logic

### 3. Compatibility Checks

Verify compliance with project constraints:

- Python 3.9+ compatibility (no walrus operator in critical paths, no `match` statements)
- Pydantic v1 API only (no `model_validator`, `model_config`, `ConfigDict`)
- No new dependencies added without justification
- `requests` library patterns (no `httpx`, `aiohttp` unless justified)

### 4. Gap Analysis

Identify missing pieces:

- Missing error handling for API calls (HTTP errors, timeouts, connection errors)
- Missing edge case tests (empty responses, malformed data, error codes)
- Missing docs for user-facing changes
- Missing validation on user inputs

## Output Format

Produce a structured review with three severity levels:

### Blockers
Must be fixed before merging. Include file path, line number, and clear description.

### Warnings
Should be addressed but not blocking. Include file path, line number, and suggestion.

### Suggestions
Nice-to-have improvements. Include file path and brief description.

## Rules

- **DO NOT modify any files** — this is a read-only review
- Read the actual diff/changed files to give specific, line-level feedback
- Consider the full context of each change, not just the diff
- Be constructive — suggest fixes, not just problems
33 changes: 33 additions & 0 deletions .claude/skills/commit/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
name: commit
description: Create a conventional commit from staged changes without Co-Authored-By
user-invocable: true
argument-hint: "[optional hint for commit scope/message]"
---

# Commit Skill

Create a well-formatted conventional commit from currently staged changes.

## Instructions

1. Run `git status` and `git diff --cached` to review staged changes.
2. If nothing is staged, inform the user and **stop**.
3. Run `git log --oneline -5` to check recent commit message style.
4. Generate a conventional commit message following this format:
```
<type>(<scope>): <description>
```
Where `<type>` is one of: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`, `ci`, `build`, `perf`.
5. If `$ARGUMENTS` is provided, use it as a hint for the commit scope or message content.
6. **CRITICAL: NEVER add `Co-Authored-By` lines to the commit message.**
7. Create the commit using HEREDOC format:
```bash
git commit -m "$(cat <<'EOF'
<type>(<scope>): <description>

<optional body with details>
EOF
)"
```
8. Show `git log --oneline -1` to confirm the commit was created successfully.
64 changes: 64 additions & 0 deletions .claude/skills/consistency-reviewer/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
name: consistency-reviewer
description: Review codebase for CLEAN code practices and DRY violations
user-invocable: true
argument-hint: "[file or directory to review, defaults to gns3fy/]"
context: fork
agent: general-purpose
allowed-tools: Read, Bash, Grep, Glob
---

# Consistency Reviewer Skill

Perform a read-only review of the codebase for CLEAN code practices and DRY violations.

## Target

Review: `$ARGUMENTS` (default: `gns3fy/`)

## CLEAN Code Checklist

Evaluate each principle and report findings:

- **C**ohesion: Does each function/class have a single, clear responsibility?
- **L**oose coupling: Are dependencies between components minimized?
- **E**ncapsulation: Is internal state properly hidden behind interfaces?
- **A**ssertive: Do objects manage their own data (tell, don't ask)?
- **N**onredundant: Are there DRY violations? (HEAVY FOCUS on this)

## DRY Analysis (Primary Focus)

Look specifically for:

1. **Duplicated code blocks** in `gns3fy/gns3fy.py` (~2200 lines) — similar methods across Node, Link, Project classes
2. **Repeated API call patterns** that could be abstracted into a shared helper
3. **Copy-paste patterns** across the core classes (e.g., similar `get()`, `update()`, `delete()` implementations)
4. **Repeated test setup** in `tests/` that could become shared fixtures or base classes

## Output Format

Produce a structured report with three severity levels:

### Critical
Issues that actively cause maintenance burden or bugs. Include:
- File path and line numbers
- Description of the violation
- Suggested improvement

### Recommended
Improvements that would meaningfully reduce complexity. Include:
- File path and line numbers
- Description of the pattern
- Suggested refactoring approach

### Nice-to-Have
Minor style or organization improvements. Include:
- File path and line numbers
- Brief description

## Rules

- **DO NOT modify any files** — this is a read-only review
- Include specific file paths and line numbers for every finding
- Focus on actionable, concrete improvements rather than abstract advice
- Consider the project's constraints: Pydantic v1, Python 3.9+, requests-based HTTP
45 changes: 45 additions & 0 deletions .claude/skills/create-pr/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
name: create-pr
description: Create a descriptive GitHub PR with summary and test plan using gh CLI
user-invocable: true
argument-hint: "[base branch, defaults to develop]"
---

# Create PR Skill

Create a well-structured GitHub Pull Request using the `gh` CLI.

## Instructions

1. Determine the base branch:
- Use `$ARGUMENTS` if provided, otherwise default to `develop`.
2. Gather context by running:
- `git log <base>..HEAD --oneline` — all commits in this branch
- `git diff <base>...HEAD --stat` — changed files summary
- `git branch --show-current` — current branch name
3. Push the branch if needed: `git push -u origin HEAD`
4. **Analyze ALL commits** (not just the latest) to understand the full scope of changes.
5. Create the PR using `gh pr create`:
- **Title**: Under 70 characters, descriptive of the overall change
- **Body** using this template:

```markdown
## Summary
- <1-3 bullet points describing what changed and why>

## Changes
- <key file modifications and their purpose>

## Test plan
- [ ] <specific testing steps relevant to the changes>
```

6. Use a HEREDOC to pass the body to ensure correct formatting:
```bash
gh pr create --title "..." --body "$(cat <<'EOF'
## Summary
...
EOF
)"
```
7. Return the PR URL when done.
91 changes: 91 additions & 0 deletions .claude/skills/developer/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
name: developer
description: Implement features following strict coding best practices with docs and tests
user-invocable: true
argument-hint: "<description of what to implement>"
---

# Developer Skill

Implement the requested feature or change following strict coding standards for gns3fy.

## Task

Implement: `$ARGUMENTS`

## Coding Standards (MANDATORY)

### Pydantic v1 (CRITICAL)
- Use `from pydantic.dataclasses import dataclass` and `from pydantic import validator`
- Use `Field(description="...", example=...)` for self-documenting model fields
- **NEVER** use Pydantic v2 APIs (`model_validator`, `model_config`, `ConfigDict`, etc.)
- Config class: `validate_assignment=True`, `extra="ignore"`

### Type Hints
- Use `typing` module: `Optional`, `Any`, `Dict`, `List`
- All function signatures must have complete type annotations

### Style
- Line length: 120 characters max
- PascalCase for classes, snake_case for functions/methods, UPPER_SNAKE_CASE for constants
- Private methods: single underscore prefix (`_create_session`)
- Formatter/linter: ruff (enforced in CI)

## Documentation (MANDATORY — No Exceptions)

### Every Function Must Have:
```python
def method_name(self, param: str) -> Optional[Dict]:
"""Short description of what it does.

Args:
param: Description of the parameter

Raises:
ValueError: When param is invalid

Returns:
Dictionary with response data, or None if not found
"""
```

### Every Class Must Have:
```python
@dataclass(config=Config)
class ClassName:
"""Short description of the class.

Attributes:
attr_name: Description of the attribute

Examples:
```python
obj = ClassName(connector=conn, attr_name="value")
obj.get()
```
"""
```

### Inline Comments
- Add comments for non-obvious logic, API quirks, or workarounds
- Do NOT add comments that just restate the code

## Testing (First-Class Citizen)

- Aim for complete coverage of all new code paths
- Class-based tests following `TestClassName` pattern
- Use `requests-mock` for HTTP mocking
- JSON fixtures go in `tests/data/`
- Follow existing mock patterns (`Gns3ConnectorMock`, `Gns3ConnectorMockStopped`, etc.)
- Use the existing `post_put_matcher()` for dynamic POST/PUT responses

## Workflow

1. Read existing code to understand patterns and conventions
2. Implement the feature following all standards above
3. Write comprehensive tests
4. Run `task lint` — fix any issues
5. Run `task test-only` — ensure all tests pass
6. Update documentation if adding/changing public APIs:
- README.md for new user-facing features
- Docstrings for pydoc-markdown to pick up
22 changes: 22 additions & 0 deletions .claude/skills/lint/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
name: lint
description: Run ruff linting and formatting checks, auto-fix issues
user-invocable: true
argument-hint: "[--check-only]"
---

# Lint Skill

Run the project's linting and formatting pipeline, optionally auto-fixing issues.

## Instructions

1. Run `task lint` to check the current state of linting and formatting (includes security rules via ruff `S` rules).
2. If `$ARGUMENTS` contains `--check-only`, report the results and **stop** — do not fix anything.
3. Otherwise, run `task lint-fix` to auto-fix all fixable issues.
4. Re-run `task lint` to confirm everything is clean.
5. Run `task security` for deeper secret/credential scanning.
6. Report a summary of:
- What was fixed (if anything)
- Any remaining issues that require manual attention
- Security scan findings (if any)
Loading
Loading