# Github Repo Management

> github-repo-management — Clone/create/fork repos; manage remotes, releases.

- **Type:** Skill
- **Install:** `agentstack add skill-atlasomnia-donna-starter-github-repo-management`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [AtlasOmnia](https://agentstack.voostack.com/s/atlasomnia)
- **Installs:** 0
- **Category:** [Developer Tools](https://agentstack.voostack.com/c/developer-tools)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [AtlasOmnia](https://github.com/AtlasOmnia)
- **Source:** https://github.com/AtlasOmnia/donna-starter/tree/main/skills/github/github-repo-management

## Install

```sh
agentstack add skill-atlasomnia-donna-starter-github-repo-management
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# GitHub Repository Management

Create, clone, fork, configure, and manage GitHub repositories. Each section shows `gh` first, then the `git` + `curl` fallback.

## Prerequisites

- Authenticated with GitHub (see `github-auth` skill)

### Setup

```bash
if command -v gh &>/dev/null && gh auth status &>/dev/null; then
 AUTH="gh"
else
 AUTH="git"
 if [ -z "$GITHUB_TOKEN" ]; then
 if _hermes_env="${HERMES_HOME:-$HOME/.hermes}/.env"; [ -f "$_hermes_env" ] && grep -q "^GITHUB_TOKEN=" "$_hermes_env"; then
 GITHUB_TOKEN=$(grep "^GITHUB_TOKEN=" "$_hermes_env" | head -1 | cut -d= -f2 | tr -d '\n\r')
# Plaintext ~/.git-credentials is intentionally not used; prefer `gh auth login` or GITHUB_TOKEN in .env
 fi
 fi
fi

# Get your GitHub username (needed for several operations)
if [ "$AUTH" = "gh" ]; then
 GH_USER=$(gh api user --jq '.login')
else
 GH_USER=$(curl -s -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/user | python3 -c "import sys,json; print(json.load(sys.stdin)['login'])")
fi
```

If you're inside a repo already:

```bash
REMOTE_URL=$(git remote get-url origin)
OWNER_REPO=$(echo "$REMOTE_URL" | sed -E 's|.*github\.com[:/]||; s|\.git$||')
OWNER=$(echo "$OWNER_REPO" | cut -d/ -f1)
REPO=$(echo "$OWNER_REPO" | cut -d/ -f2)
```

---

## 1. Cloning Repositories

Cloning is pure `git` — works identically either way:

```bash
# Clone via HTTPS (works with credential helper or token-embedded URL)
git clone https://github.com/owner/repo-name.git

# Clone into a specific directory
git clone https://github.com/owner/repo-name.git ./my-local-dir

# Shallow clone (faster for large repos)
git clone --depth 1 https://github.com/owner/repo-name.git

# Clone a specific branch
git clone --branch develop https://github.com/owner/repo-name.git

# Clone via SSH (if SSH is configured)
git clone git@github.com:owner/repo-name.git
```

**With gh (shorthand):**

```bash
gh repo clone owner/repo-name
gh repo clone owner/repo-name -- --depth 1
```

## 2. Creating Repositories

**With gh:**

```bash
# Create a public repo and clone it
gh repo create my-new-project --public --clone

# Private, with description and license
gh repo create my-new-project --private --description "A useful tool" --license MIT --clone

# Under an organization
gh repo create my-org/my-new-project --public --clone

# From existing local directory
cd /path/to/existing/project
gh repo create my-project --source . --public --push
```

**With git + curl:**

```bash
# Create the remote repo via API
curl -s -X POST \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/user/repos \
 -d '{
 "name": "my-new-project",
 "description": "A useful tool",
 "private": false,
 "auto_init": true,
 "license_template": "mit"
 }'

# Clone it
git clone https://github.com/$GH_USER/my-new-project.git
cd my-new-project

# -- OR -- push an existing local directory to the new repo
cd /path/to/existing/project
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/$GH_USER/my-new-project.git
git push -u origin main
```

To create under an organization:

```bash
curl -s -X POST \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/orgs/my-org/repos \
 -d '{"name": "my-new-project", "private": false}'
```

### From a Template

**With gh:**

```bash
gh repo create my-new-app --template owner/template-repo --public --clone
```

**With curl:**

```bash
curl -s -X POST \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/repos/owner/template-repo/generate \
 -d '{"owner": "'"$GH_USER"'", "name": "my-new-app", "private": false}'
```

## 3. Forking Repositories

**With gh:**

```bash
gh repo fork owner/repo-name --clone
```

**With git + curl:**

```bash
# Create the fork via API
curl -s -X POST \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/repos/owner/repo-name/forks

# Wait a moment for GitHub to create it, then clone
sleep 3
git clone https://github.com/$GH_USER/repo-name.git
cd repo-name

# Add the original repo as "upstream" remote
git remote add upstream https://github.com/owner/repo-name.git
```

### Keeping a Fork in Sync

```bash
# Pure git — works everywhere
git fetch upstream
git checkout main
git merge upstream/main
git push origin main
```

**With gh (shortcut):**

```bash
gh repo sync $GH_USER/repo-name
```

## 4. Repository Information

**With gh:**

```bash
gh repo view owner/repo-name
gh repo list --limit 20
gh search repos "machine learning" --language python --sort stars
```

**With curl:**

```bash
# View repo details
curl -s \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/repos/$OWNER/$REPO \
 | python3 -c "
import sys, json
r = json.load(sys.stdin)
print(f\"Name: {r['full_name']}\")
print(f\"Description: {r['description']}\")
print(f\"Stars: {r['stargazers_count']} Forks: {r['forks_count']}\")
print(f\"Default branch: {r['default_branch']}\")
print(f\"Language: {r['language']}\")"

# List your repos
curl -s \
 -H "Authorization: token $GITHUB_TOKEN" \
 "https://api.github.com/user/repos?per_page=20&sort=updated" \
 | python3 -c "
import sys, json
for r in json.load(sys.stdin):
 vis = 'private' if r['private'] else 'public'
 print(f\" {r['full_name']:40} {vis:8} {r.get('language', ''):10} ★{r['stargazers_count']}\")"

# Search repos
curl -s \
 "https://api.github.com/search/repositories?q=machine+learning+language:python&sort=stars&per_page=10" \
 | python3 -c "
import sys, json
for r in json.load(sys.stdin)['items']:
 print(f\" {r['full_name']:40} ★{r['stargazers_count']:6} {r['description'][:60] if r['description'] else ''}\")"
```

## 5. Profile README and Pinned Repositories

A personal profile README requires a public repository whose name exactly matches the GitHub username and a non-empty root `README.md` on the default branch. Verify the special-repository flag with:

```bash
gh api graphql -f query='query { repository(owner:"OWNER", name:"USERNAME") { isUserConfigurationRepository isPrivate defaultBranchRef { name } object(expression:"main:README.md") { ... on Blob { byteSize } } }'
```

If the repository satisfies those requirements but the README is not visible, the owner may need to open the repository in an authenticated browser and click **Share to profile**. Updating the README through the API does not necessarily enable profile display.

Pinned repositories can be read through GraphQL:

```bash
gh api graphql -f query='query { user(login:"USERNAME") { pinnedItems(first:6, types:REPOSITORY) { nodes { ... on Repository { name url } } } } }'
```

GitHub does not expose a supported REST or public GraphQL mutation for changing profile pins. Use the authenticated web UI (**Customize your pins**) and verify afterward with the query above. Do not attempt this from a browser signed into a different GitHub account.

## 6. Repository Settings

**With gh:**

```bash
gh repo edit --description "Updated description" --visibility public
gh repo edit --enable-wiki=false --enable-issues=true
gh repo edit --default-branch main
gh repo edit --add-topic "machine-learning,python"
gh repo edit --enable-auto-merge
```

**With curl:**

```bash
curl -s -X PATCH \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/repos/$OWNER/$REPO \
 -d '{
 "description": "Updated description",
 "has_wiki": false,
 "has_issues": true,
 "allow_auto_merge": true
 }'

# Update topics
curl -s -X PUT \
 -H "Authorization: token $GITHUB_TOKEN" \
 -H "Accept: application/vnd.github.mercy-preview+json" \
 https://api.github.com/repos/$OWNER/$REPO/topics \
 -d '{"names": ["machine-learning", "python", "automation"]}'
```

## 7. Branch Protection

```bash
# View current protection
curl -s \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/repos/$OWNER/$REPO/branches/main/protection

# Set up branch protection
curl -s -X PUT \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/repos/$OWNER/$REPO/branches/main/protection \
 -d '{
 "required_status_checks": {
 "strict": true,
 "contexts": ["ci/test", "ci/lint"]
 },
 "enforce_admins": false,
 "required_pull_request_reviews": {
 "required_approving_review_count": 1
 },
 "restrictions": null
 }'
```

## 8. Secrets Management (GitHub Actions)

**With gh:**

```bash
gh secret set API_KEY --body "your-secret-value"
gh secret set SSH_KEY '
public_key = ''

# Encrypt
sealed = public.SealedBox(
 public.PublicKey(public_key.encode('utf-8'), encoding.Base64Encoder)
).encrypt('your-secret-value'.encode('utf-8'))
print(json.dumps({
 'encrypted_value': b64encode(sealed).decode('utf-8'),
 'key_id': key_id
}))"

# Then PUT the encrypted secret
curl -s -X PUT \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/repos/$OWNER/$REPO/actions/secrets/API_KEY \
 -d ''

# List secrets (names only, values hidden)
curl -s \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/repos/$OWNER/$REPO/actions/secrets \
 | python3 -c "
import sys, json
for s in json.load(sys.stdin)['secrets']:
 print(f\" {s['name']:30} updated: {s['updated_at']}\")"
```

Note: For secrets, `gh secret set` is dramatically simpler. If setting secrets is needed and `gh` isn't available, recommend installing it for just that operation.

## 9. Releases

**With gh:**

```bash
gh release create v1.0.0 --title "v1.0.0" --generate-notes
gh release create v2.0.0-rc1 --draft --prerelease --generate-notes
gh release create v1.0.0 ./dist/binary --title "v1.0.0" --notes "Release notes"
gh release list
gh release download v1.0.0 --dir ./downloads
```

**With curl:**

```bash
# Create a release
curl -s -X POST \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/repos/$OWNER/$REPO/releases \
 -d '{
 "tag_name": "v1.0.0",
 "name": "v1.0.0",
 "body": "## Changelog\n- Feature A\n- Bug fix B",
 "draft": false,
 "prerelease": false,
 "generate_release_notes": true
 }'

# List releases
curl -s \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/repos/$OWNER/$REPO/releases \
 | python3 -c "
import sys, json
for r in json.load(sys.stdin):
 tag = r.get('tag_name', 'no tag')
 print(f\" {tag:15} {r['name']:30} {'draft' if r['draft'] else 'published'}\")"

# Upload a release asset (binary file)
RELEASE_ID=
curl -s -X POST \
 -H "Authorization: token $GITHUB_TOKEN" \
 -H "Content-Type: application/octet-stream" \
 "https://uploads.github.com/repos/$OWNER/$REPO/releases/$RELEASE_ID/assets?name=binary-amd64" \
 --data-binary @./dist/binary-amd64
```

## 10. GitHub Actions Workflows

**With gh:**

```bash
gh workflow list
gh run list --limit 10
gh run view 
gh run view  --log-failed
gh run rerun 
gh run rerun  --failed
gh workflow run ci.yml --ref main
gh workflow run deploy.yml -f environment=staging
```

**With curl:**

```bash
# List workflows
curl -s \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/repos/$OWNER/$REPO/actions/workflows \
 | python3 -c "
import sys, json
for w in json.load(sys.stdin)['workflows']:
 print(f\" {w['id']:10} {w['name']:30} {w['state']}\")"

# List recent runs
curl -s \
 -H "Authorization: token $GITHUB_TOKEN" \
 "https://api.github.com/repos/$OWNER/$REPO/actions/runs?per_page=10" \
 | python3 -c "
import sys, json
for r in json.load(sys.stdin)['workflow_runs']:
 print(f\" Run {r['id']} {r['name']:30} {r['conclusion'] or r['status']}\")"

# Download failed run logs
RUN_ID=
curl -s -L \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/logs \
 -o /tmp/ci-logs.zip
cd /tmp && unzip -o ci-logs.zip -d ci-logs

# Re-run a failed workflow
curl -s -X POST \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/rerun

# Re-run only failed jobs
curl -s -X POST \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/rerun-failed-jobs

# Trigger a workflow manually (workflow_dispatch)
WORKFLOW_ID=
curl -s -X POST \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/repos/$OWNER/$REPO/actions/workflows/$WORKFLOW_ID/dispatches \
 -d '{"ref": "main", "inputs": {"environment": "staging"}}'
```

## 11. Gists

**With gh:**

```bash
gh gist create script.py --public --desc "Useful script"
gh gist list
```

**With curl:**

```bash
# Create a gist
curl -s -X POST \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/gists \
 -d '{
 "description": "Useful script",
 "public": true,
 "files": {
 "script.py": {"content": "print(\"hello\")"}
 }
 }'

# List your gists
curl -s \
 -H "Authorization: token $GITHUB_TOKEN" \
 https://api.github.com/gists \
 | python3 -c "
import sys, json
for g in json.load(sys.stdin):
 files = ', '.join(g['files'].keys())
 print(f\" {g['id']} {g['description'] or '(no desc)':40} {files}\")"
```

## Quick Reference Table

| Action | gh | git + curl |
|--------|-----|-----------|
| Clone | `gh repo clone o/r` | `git clone https://github.com/o/r.git` |
| Create repo | `gh repo create name --public` | `curl POST /user/repos` |
| Fork | `gh repo fork o/r --clone` | `curl POST /repos/o/r/forks` + `git clone` |
| Repo info | `gh repo view o/r` | `curl GET /repos/o/r` |
| Edit settings | `gh repo edit --...` | `curl PATCH /repos/o/r` |
| Create release | `gh release create v1.0` | `curl POST /repos/o/r/releases` |
| List workflows | `gh workflow list` | `curl GET /repos/o/r/actions/workflows` |
| Rerun CI | `gh run rerun ID` | `curl POST /repos/o/r/actions/runs/ID/rerun` |
| Set secret | `gh secret set KEY` | `curl PUT /repos/o/r/actions/secrets/KEY` (+ encryption) |

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [AtlasOmnia](https://github.com/AtlasOmnia)
- **Source:** [AtlasOmnia/donna-starter](https://github.com/AtlasOmnia/donna-starter)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-atlasomnia-donna-starter-github-repo-management
- Seller: https://agentstack.voostack.com/s/atlasomnia
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
