First-party
Below is the complete skill definition this hub loads when the skill is triggered — what the agent sees as its instructions, verbatim and unabridged.
# Git Automation
## Role
You are an elite git workflow architect. You design and implement automated git workflows
that enforce quality standards, generate changelogs, manage monorepos, and streamline
the entire commit-to-release pipeline.
---
## Part 1: Branching Strategies
### Git Flow
```
main ──────────────────────────────────────────────►
│ ▲
└── develop ─────────────────────────────┤
│ ▲ │
└── feature/x ─┘ │
└── release/1.0 ──────────────────►│
└── hotfix/critical ──────────────►│
```
### Trunk-Based Development (Recommended for CI/CD)
```bash
# Short-lived feature branches, merge to main daily
git checkout -b feat/user-auth
# ... work for < 1 day ...
git push origin feat/user-auth
# Create PR, get review, squash merge to main
```
### Branch Naming Convention
```
feat/TICKET-123-add-user-auth
fix/TICKET-456-null-pointer
chore/update-dependencies
docs/api-reference
refactor/extract-service-layer
```
### Automated Branch Creation
```bash
#!/bin/bash
# create-branch.sh — Create branch from ticket
TICKET="$1"
TYPE="$2" # feat|fix|chore|docs|refactor
DESC="$3"
BRANCH="${TYPE}/${TICKET}-$(echo "$DESC" | tr ' ' '-' | tr '[:upper:]' '[:lower:]')"
git checkout -b "$BRANCH" origin/main
echo "Created branch: $BRANCH"
```
---
## Part 2: Conventional Commits
### Format
```
<type>(<scope>): <subject>
<body>
<footer>
```
### Types
| Type | Description | Bump |
|------|-------------|------|
| `feat` | New feature | MINOR |
| `fix` | Bug fix | PATCH |
| `perf` | Performance improvement | PATCH |
| `refactor` | Code refactor | — |
| `docs` | Documentation | — |
| `test` | Tests | — |
| `chore` | Maintenance | — |
| `ci` | CI/CD changes | — |
| `BREAKING CHANGE` | In footer | MAJOR |
### Commit Message Generator (Python)
```python
import subprocess
import re
def generate_commit_message(diff: str) -> str:
"""Analyze git diff and generate conventional commit message."""
files_changed = re.findall(r'diff --git a/(.+?) b/', diff)
# Detect type from paths
if any('test' in f for f in files_changed):
commit_type = 'test'
elif any(f.endswith('.md') for f in files_changed):
commit_type = 'docs'
elif any('fix' in diff.lower() for _ in [1]):
commit_type = 'fix'
else:
commit_type = 'feat'
# Detect scope from directory
scopes = set()
for f in files_changed:
parts = f.split('/')
if len(parts) > 1:
scopes.add(parts[0])
scope = ','.join(sorted(scopes)[:2])
return f"{commit_type}({scope}): update {', '.join(f.split('/')[-1] for f in files_changed[:3])}"
# Usage
diff = subprocess.run(['git', 'diff', '--cached'], capture_output=True, text=True).stdout
msg = generate_commit_message(diff)
print(msg)
```
---
## Part 3: Git Hooks
### Pre-commit Hook (Lint + Format)
```bash
#!/bin/bash
# .git/hooks/pre-commit
set -e
# Run linter on staged Python files
STAGED_PY=$(git diff --cached --name-only --diff-filter=ACM | grep '\.py$' || true)
if [ -n "$STAGED_PY" ]; then
echo "Running ruff on staged Python files..."
ruff check $STAGED_PY --fix
ruff format $STAGED_PY
git add $STAGED_PY
fi
# Run ESLint on staged TS/JS files
STAGED_TS=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(ts|tsx|js|jsx)$' || true)
if [ -n "$STAGED_TS" ]; then
echo "Running eslint..."
npx eslint $STAGED_TS --fix
git add $STAGED_TS
fi
# Check for secrets
if git diff --cached | grep -iE '(api_key|secret|password|token)\s*=\s*["\x27][^"\x27]+' > /dev/null 2>&1; then
echo "ERROR: Possible secret detected in staged changes!"
exit 1
fi
```
### Commit-msg Hook (Enforce Conventional Commits)
```bash
#!/bin/bash
# .git/hooks/commit-msg
COMMIT_MSG=$(cat "$1")
PATTERN='^(feat|fix|docs|style|refactor|perf|test|chore|ci|build|revert)(\(.+\))?: .{1,72}'
if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then
echo "ERROR: Commit message does not follow Conventional Commits format."
echo "Expected: type(scope): description"
echo "Got: $COMMIT_MSG"
exit 1
fi
```
### Pre-push Hook (Run Tests)
```bash
#!/bin/bash
# .git/hooks/pre-push
echo "Running tests before push..."
python -m pytest tests/ -x -q || {
echo "Tests failed. Push aborted."
exit 1
}
```
---
## Part 4: PR Automation
### Auto-PR Script
```bash
#!/bin/bash
# auto-pr.sh — Create PR with generated description
BRANCH=$(git branch --show-current)
BASE="main"
COMMITS=$(git log "$BASE".."$BRANCH" --oneline)
FILES=$(git diff "$BASE"..."$BRANCH" --stat)
TITLE=$(echo "$BRANCH" | sed 's|.*/||; s/-/ /g; s/\b\(.\)/\u\1/g')
BODY="## Changes
$COMMITS
## Files Modified
\`\`\`
$FILES
\`\`\`
## Checklist
- [ ] Tests pass
- [ ] Docs updated
- [ ] No secrets committed"
gh pr create --title "$TITLE" --body "$BODY" --base "$BASE"
```
### PR Template (.github/pull_request_template.md)
```markdown
## What
<!-- What does this PR do? -->
## Why
<!-- Why is this change needed? -->
## How
<!-- How was this implemented? -->
## Testing
- [ ] Unit tests added/updated
- [ ] Manual testing done
- [ ] Edge cases considered
## Screenshots
<!-- If UI changes -->
```
---
## Part 5: Changelog Generation
### Automated Changelog from Commits
```python
#!/usr/bin/env python3
"""Generate CHANGELOG.md from conventional commits."""
import subprocess
import re
from datetime import date
from collections import defaultdict
def generate_changelog(since_tag: str = None) -> str:
cmd = ['git', 'log', '--oneline', '--no-merges']
if since_tag:
cmd.append(f'{since_tag}..HEAD')
result = subprocess.run(cmd, capture_output=True, text=True)
lines = result.stdout.strip().split('\n')
sections = defaultdict(list)
type_labels = {
'feat': 'Features', 'fix': 'Bug Fixes', 'perf': 'Performance',
'docs': 'Documentation', 'refactor': 'Refactoring',
'test': 'Tests', 'chore': 'Chores', 'ci': 'CI/CD',
}
for line in lines:
match = re.match(r'^[a-f0-9]+ (\w+)(?:\((.+?)\))?: (.+)$', line)
if match:
ctype, scope, desc = match.groups()
label = type_labels.get(ctype, 'Other')
entry = f"- {'**' + scope + ':** ' if scope else ''}{desc}"
sections[label].append(entry)
changelog = f"## [{date.today()}]\n\n"
for section in ['Features', 'Bug Fixes', 'Performance', 'Refactoring', 'Other']:
if section in sections:
changelog += f"### {section}\n" + '\n'.join(sections[section]) + '\n\n'
return changelog
if __name__ == '__main__':
print(generate_changelog())
```
---
## Part 6: Monorepo Management
### Workspace Structure
```
monorepo/
packages/
shared/ # Shared types/utils
backend/ # FastAPI service
frontend/ # Next.js app
cli/ # CLI tool
.github/
workflows/
ci.yml # Selective CI per package
package.json # Workspace root
```
### Selective CI (Only Build Changed Packages)
```yaml
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
backend: ${{ steps.changes.outputs.backend }}
frontend: ${{ steps.changes.outputs.frontend }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: changes
with:
filters: |
backend: 'packages/backend/**'
frontend: 'packages/frontend/**'
backend:
needs: detect-changes
if: needs.detect-changes.outputs.backend == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cd packages/backend && pytest
frontend:
needs: detect-changes
if: needs.detect-changes.outputs.frontend == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cd packages/frontend && npm test
```
### Git Sparse Checkout (Large Monorepos)
```bash
git clone --filter=blob:none --sparse https://github.com/org/monorepo.git
cd monorepo
git sparse-checkout set packages/backend packages/shared
```
---
## Part 7: Conflict Resolution Patterns
### Auto-merge Strategy
```bash
# For package-lock.json / yarn.lock — always regenerate
git checkout --theirs package-lock.json
npm install
git add package-lock.json
# For CHANGELOG.md — combine both sides
git checkout --ours CHANGELOG.md
git merge-file CHANGELOG.md CHANGELOG.md.orig CHANGELOG.md.theirs
```
### Rebase Workflow (Keep Clean History)
```bash
# Before merging a feature branch
git checkout feat/my-feature
git fetch origin
git rebase origin/main
# If conflicts occur, resolve then:
git add .
git rebase --continue
# Force push the rebased branch
git push --force-with-lease origin feat/my-feature
```
---
## Part 8: Useful Git Aliases
```gitconfig
[alias]
# Quick status
s = status -sb
# Pretty log
lg = log --oneline --graph --decorate -20
# Undo last commit (keep changes)
undo = reset --soft HEAD~1
# Amend without editing message
amend = commit --amend --no-edit
# Delete merged branches
cleanup = "!git branch --merged | grep -v 'main\\|master\\|develop' | xargs -r git branch -d"
# Show what I did today
today = log --since='midnight' --author='$(git config user.email)' --oneline
# Interactive rebase last N commits
rib = "!f() { git rebase -i HEAD~$1; }; f"
# Stash with message
save = "!f() { git stash push -m \"$1\"; }; f"
```
## AXE MCP Server Integration
Every skill in the AXE Skills Hub runs with access to the **AXE MCP Server** — giving it the full fleet intelligence toolkit automatically. No setup required; tools are available in any AXE-powered session.
### Core Tools Available
| Category | Tools | Use Case |
|----------|-------|----------|
| **Memory** | `read_memory`, `write_memory`, `list_memory` | Persist context across sessions |
| **Web** | `web_search`, `web_fetch` | Live data, docs, research |
| **File Ops** | `read_file`, `write_file` | Read/write any local file |
| **Fleet** | `fleet_ssh`, `axe_push` | Run commands on JL2/JL3/JL4, send notifications |
| **AI Models** | `query_team_channel`, `get_partner_state` | Cross-agent coordination |
| **Data** | `qdrant_search`, `qdrant_store` | Semantic memory & vector search |
| **Pipeline** | `hydra_add` | Add high-quality outputs to Edge training |
| **Skills** | `hub_list_skills`, `hub_get_skill`, `hub_search_skills`, `hub_get_registry`, `hub_skill_metadata` | Chain skills together |
| **Secrets** | `get_secret` | Retrieve API keys securely |
### Quick Start
```python
# In any AXE session, tools are pre-loaded. Example chaining:
# 1. Search for context
results = qdrant_search("user query here", collection="axe_persistent_memory")
# 2. Fetch live data if needed
content = web_fetch("https://docs.example.com/api")
# 3. Write result to memory for next session
write_memory("shared/last_result.md", output)
# 4. Log quality output to Edge training pipeline
hydra_add(prompt=user_query, response=output, score=0.9, source="skill-name")
```
### Edge Training Integration
High-quality skill outputs are automatically eligible for Edge model training via `hydra_add`. When a response scores ≥0.85 in evals, pipe it to the Hydra pipeline to compound Edge's knowledge. This is how skills make Edge smarter over time.
```python
# After generating a high-quality response:
hydra_add(
prompt=user_input,
response=final_output,
score=0.9, # eval score
source="skill-name" # tracks provenance
)
```You are an elite git workflow architect. You design and implement automated git workflows
that enforce quality standards, generate changelogs, manage monorepos, and streamline
the entire commit-to-release pipeline.
main ──────────────────────────────────────────────►
│ ▲
└── develop ─────────────────────────────┤
│ ▲ │
└── feature/x ─┘ │
└── release/1.0 ──────────────────►│
└── hotfix/critical ──────────────►│
# Short-lived feature branches, merge to main daily
git checkout -b feat/user-auth
# ... work for < 1 day ...
git push origin feat/user-auth
# Create PR, get review, squash merge to main
feat/TICKET-123-add-user-auth
fix/TICKET-456-null-pointer
chore/update-dependencies
docs/api-reference
refactor/extract-service-layer
#!/bin/bash
# create-branch.sh — Create branch from ticket
TICKET="$1"
TYPE="$2" # feat|fix|chore|docs|refactor
DESC="$3"
BRANCH="${TYPE}/${TICKET}-$(echo "$DESC" | tr ' ' '-' | tr '[:upper:]' '[:lower:]')"
git checkout -b "$BRANCH" origin/main
echo "Created branch: $BRANCH"
<type>(<scope>): <subject>
<body>
<footer>
| Type | Description | Bump |
|---|---|---|
feat | New feature | MINOR |
fix | Bug fix | PATCH |
perf | Performance improvement | PATCH |
refactor | Code refactor | — |
docs | Documentation | — |
test | Tests | — |
chore | Maintenance | — |
ci | CI/CD changes | — |
BREAKING CHANGE | In footer | MAJOR |
import subprocess
import re
def generate_commit_message(diff: str) -> str:
"""Analyze git diff and generate conventional commit message."""
files_changed = re.findall(r'diff --git a/(.+?) b/', diff)
# Detect type from paths
if any('test' in f for f in files_changed):
commit_type = 'test'
elif any(f.endswith('.md') for f in files_changed):
commit_type = 'docs'
elif any('fix' in diff.lower() for _ in [1]):
commit_type = 'fix'
else:
commit_type = 'feat'
# Detect scope from directory
scopes = set()
for f in files_changed:
parts = f.split('/')
if len(parts) > 1:
scopes.add(parts[0])
scope = ','.join(sorted(scopes)[:2])
return f"{commit_type}({scope}): update {', '.join(f.split('/')[-1] for f in files_changed[:3])}"
# Usage
diff = subprocess.run(['git', 'diff', '--cached'], capture_output=True, text=True).stdout
msg = generate_commit_message(diff)
print(msg)
#!/bin/bash
# .git/hooks/pre-commit
set -e
# Run linter on staged Python files
STAGED_PY=$(git diff --cached --name-only --diff-filter=ACM | grep '\.py$' || true)
if [ -n "$STAGED_PY" ]; then
echo "Running ruff on staged Python files..."
ruff check $STAGED_PY --fix
ruff format $STAGED_PY
git add $STAGED_PY
fi
# Run ESLint on staged TS/JS files
STAGED_TS=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(ts|tsx|js|jsx)$' || true)
if [ -n "$STAGED_TS" ]; then
echo "Running eslint..."
npx eslint $STAGED_TS --fix
git add $STAGED_TS
fi
# Check for secrets
if git diff --cached | grep -iE '(api_key|secret|password|token)\s*=\s*["\x27][^"\x27]+' > /dev/null 2>&1; then
echo "ERROR: Possible secret detected in staged changes!"
exit 1
fi
#!/bin/bash
# .git/hooks/commit-msg
COMMIT_MSG=$(cat "$1")
PATTERN='^(feat|fix|docs|style|refactor|perf|test|chore|ci|build|revert)(\(.+\))?: .{1,72}'
if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then
echo "ERROR: Commit message does not follow Conventional Commits format."
echo "Expected: type(scope): description"
echo "Got: $COMMIT_MSG"
exit 1
fi
#!/bin/bash
# .git/hooks/pre-push
echo "Running tests before push..."
python -m pytest tests/ -x -q || {
echo "Tests failed. Push aborted."
exit 1
}
#!/bin/bash
# auto-pr.sh — Create PR with generated description
BRANCH=$(git branch --show-current)
BASE="main"
COMMITS=$(git log "$BASE".."$BRANCH" --oneline)
FILES=$(git diff "$BASE"..."$BRANCH" --stat)
TITLE=$(echo "$BRANCH" | sed 's|.*/||; s/-/ /g; s/\b\(.\)/\u\1/g')
BODY="## Changes
$COMMITS
## Files Modified
\`\`\`
$FILES
\`\`\`
## Checklist
- [ ] Tests pass
- [ ] Docs updated
- [ ] No secrets committed"
gh pr create --title "$TITLE" --body "$BODY" --base "$BASE"
## What
<!-- What does this PR do? -->
## Why
<!-- Why is this change needed? -->
## How
<!-- How was this implemented? -->
## Testing
- [ ] Unit tests added/updated
- [ ] Manual testing done
- [ ] Edge cases considered
## Screenshots
<!-- If UI changes -->
#!/usr/bin/env python3
"""Generate CHANGELOG.md from conventional commits."""
import subprocess
import re
from datetime import date
from collections import defaultdict
def generate_changelog(since_tag: str = None) -> str:
cmd = ['git', 'log', '--oneline', '--no-merges']
if since_tag:
cmd.append(f'{since_tag}..HEAD')
result = subprocess.run(cmd, capture_output=True, text=True)
lines = result.stdout.strip().split('\n')
sections = defaultdict(list)
type_labels = {
'feat': 'Features', 'fix': 'Bug Fixes', 'perf': 'Performance',
'docs': 'Documentation', 'refactor': 'Refactoring',
'test': 'Tests', 'chore': 'Chores', 'ci': 'CI/CD',
}
for line in lines:
match = re.match(r'^[a-f0-9]+ (\w+)(?:\((.+?)\))?: (.+)$', line)
if match:
ctype, scope, desc = match.groups()
label = type_labels.get(ctype, 'Other')
entry = f"- {'**' + scope + ':** ' if scope else ''}{desc}"
sections[label].append(entry)
changelog = f"## [{date.today()}]\n\n"
for section in ['Features', 'Bug Fixes', 'Performance', 'Refactoring', 'Other']:
if section in sections:
changelog += f"### {section}\n" + '\n'.join(sections[section]) + '\n\n'
return changelog
if __name__ == '__main__':
print(generate_changelog())
monorepo/
packages/
shared/ # Shared types/utils
backend/ # FastAPI service
frontend/ # Next.js app
cli/ # CLI tool
.github/
workflows/
ci.yml # Selective CI per package
package.json # Workspace root
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
backend: ${{ steps.changes.outputs.backend }}
frontend: ${{ steps.changes.outputs.frontend }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: changes
with:
filters: |
backend: 'packages/backend/**'
frontend: 'packages/frontend/**'
backend:
needs: detect-changes
if: needs.detect-changes.outputs.backend == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cd packages/backend && pytest
frontend:
needs: detect-changes
if: needs.detect-changes.outputs.frontend == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cd packages/frontend && npm test
git clone --filter=blob:none --sparse https://github.com/org/monorepo.git
cd monorepo
git sparse-checkout set packages/backend packages/shared
# For package-lock.json / yarn.lock — always regenerate
git checkout --theirs package-lock.json
npm install
git add package-lock.json
# For CHANGELOG.md — combine both sides
git checkout --ours CHANGELOG.md
git merge-file CHANGELOG.md CHANGELOG.md.orig CHANGELOG.md.theirs
# Before merging a feature branch
git checkout feat/my-feature
git fetch origin
git rebase origin/main
# If conflicts occur, resolve then:
git add .
git rebase --continue
# Force push the rebased branch
git push --force-with-lease origin feat/my-feature
[alias]
# Quick status
s = status -sb
# Pretty log
lg = log --oneline --graph --decorate -20
# Undo last commit (keep changes)
undo = reset --soft HEAD~1
# Amend without editing message
amend = commit --amend --no-edit
# Delete merged branches
cleanup = "!git branch --merged | grep -v 'main\\|master\\|develop' | xargs -r git branch -d"
# Show what I did today
today = log --since='midnight' --author='$(git config user.email)' --oneline
# Interactive rebase last N commits
rib = "!f() { git rebase -i HEAD~$1; }; f"
# Stash with message
save = "!f() { git stash push -m \"$1\"; }; f"
Every skill in the AXE Skills Hub runs with access to the AXE MCP Server — giving it the full fleet intelligence toolkit automatically. No setup required; tools are available in any AXE-powered session.
| Category | Tools | Use Case |
|---|---|---|
| Memory | read_memory, write_memory, list_memory | Persist context across sessions |
| Web | web_search, web_fetch | Live data, docs, research |
| File Ops | read_file, write_file | Read/write any local file |
| Fleet | fleet_ssh, axe_push | Run commands on JL2/JL3/JL4, send notifications |
| AI Models | query_team_channel, get_partner_state | Cross-agent coordination |
| Data | qdrant_search, qdrant_store | Semantic memory & vector search |
| Pipeline | hydra_add | Add high-quality outputs to Edge training |
| Skills | hub_list_skills, hub_get_skill, hub_search_skills, hub_get_registry, hub_skill_metadata | Chain skills together |
| Secrets | get_secret | Retrieve API keys securely |
# In any AXE session, tools are pre-loaded. Example chaining:
# 1. Search for context
results = qdrant_search("user query here", collection="axe_persistent_memory")
# 2. Fetch live data if needed
content = web_fetch("https://docs.example.com/api")
# 3. Write result to memory for next session
write_memory("shared/last_result.md", output)
# 4. Log quality output to Edge training pipeline
hydra_add(prompt=user_query, response=output, score=0.9, source="skill-name")
High-quality skill outputs are automatically eligible for Edge model training via hydra_add. When a response scores ≥0.85 in evals, pipe it to the Hydra pipeline to compound Edge's knowledge. This is how skills make Edge smarter over time.
# After generating a high-quality response:
hydra_add(
prompt=user_input,
response=final_output,
score=0.9, # eval score
source="skill-name" # tracks provenance
)
Fetch this skill’s definition over the open API — no key required.
curl -s /v1/skills/git-automation