Files
git.sethpc.xyz-connector/docs/superpowers/plans/2026-04-01-gitea-connector.md
T
2026-04-01 17:51:39 -04:00

804 lines
24 KiB
Markdown

# Gitea Connector Plugin — Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Build a Claude Code plugin that lets collaborators connect to Seth's Gitea instance (`git.sethpc.xyz`) with their own accounts, bundling a bash CLI, guided setup, commit conventions, and a push-reminder hook.
**Architecture:** Claude Code plugin with `.claude-plugin/plugin.json` manifest. Slash command (`/gitea-setup`) invokes an agent for interactive credential setup. Skill provides commit conventions. Hook reminds to push after commits. Bash CLI in `bin/gitea` handles all API/git operations over HTTPS to `git.sethpc.xyz`.
**Tech Stack:** Bash (CLI), Markdown with YAML frontmatter (plugin components), JSON (plugin manifest, hook config), `curl`/`jq`/`git` (CLI dependencies).
**Spec:** `docs/superpowers/specs/2026-04-01-gitea-connector-design.md`
---
## File Map
| File | Action | Responsibility |
|------|--------|----------------|
| `.claude-plugin/plugin.json` | Create | Plugin manifest — name, description, paths to commands/agents/hooks |
| `bin/gitea` | Create | Bash CLI — create, remote, push, delete, list repos. HTTPS-only to `git.sethpc.xyz`. Reads username/token/host from `~/.config/gitea/` |
| `commands/gitea-setup.md` | Create | `/gitea-setup` slash command — invokes the setup agent |
| `agents/gitea-setup.md` | Create | Interactive setup agent — dependency check, credential collection, CLI install, token validation |
| `skills/gitea-workflow/SKILL.md` | Create | Commit conventions, CLI reference, credential safety, override mechanism |
| `hooks/hooks.json` | Create | Hook configuration — PostToolUse push reminder (disabled by default) |
| `hooks/scripts/push-reminder.sh` | Create | Detects `git commit` in Bash tool output, echoes push reminder |
| `README.md` | Create | User-facing install + usage docs |
---
### Task 1: Plugin Manifest & Scaffold
**Files:**
- Create: `gitea-connector/.claude-plugin/plugin.json`
- [ ] **Step 1: Create the `.claude-plugin` directory**
```bash
mkdir -p /home/claude/bin/gitea-connector/.claude-plugin
```
- [ ] **Step 2: Write `plugin.json`**
```json
{
"name": "gitea-connector",
"version": "1.0.0",
"description": "Connect Claude Code to Seth's Gitea instance (git.sethpc.xyz) — guided setup, CLI, commit conventions, and a gentle nudge to push.",
"author": {
"name": "Seth",
"url": "https://git.sethpc.xyz"
},
"homepage": "https://git.sethpc.xyz/Seth/gitea-connector",
"repository": "https://git.sethpc.xyz/Seth/gitea-connector",
"license": "MIT",
"commands": ["./commands"],
"agents": ["./agents"],
"hooks": "./hooks/hooks.json"
}
```
- [ ] **Step 3: Create remaining directory structure**
```bash
mkdir -p /home/claude/bin/gitea-connector/{commands,agents,skills/gitea-workflow,hooks/scripts,bin}
```
- [ ] **Step 4: Init git repo**
```bash
cd /home/claude/bin/gitea-connector && git init
```
- [ ] **Step 5: Create `.gitignore`**
```
.backup/
*.swp
*.swo
```
- [ ] **Step 6: Commit scaffold**
```bash
cd /home/claude/bin/gitea-connector
git add .claude-plugin/plugin.json .gitignore
git commit -m "chore: scaffold plugin with manifest and directory structure"
```
---
### Task 2: Bash CLI (`bin/gitea`)
**Files:**
- Create: `gitea-connector/bin/gitea`
- [ ] **Step 1: Write the CLI script**
Adapted from Seth's `~/bin/gitea`. Key changes: no LAN detection, reads username from config, silly help text.
```bash
#!/usr/bin/env bash
# gitea — your friendly neighborhood Gitea CLI
# It creates repos. It pushes code. It occasionally judges your commit messages.
# Usage: gitea <command> [options]
set -euo pipefail
# --- Config ---
GITEA_HOST="git.sethpc.xyz"
if [[ -f "$HOME/.config/gitea/host" ]]; then
GITEA_HOST="$(< "$HOME/.config/gitea/host")"
GITEA_HOST="${GITEA_HOST%%[[:space:]]}"
fi
GITEA_USER=""
if [[ -f "$HOME/.config/gitea/username" ]]; then
GITEA_USER="$(< "$HOME/.config/gitea/username")"
GITEA_USER="${GITEA_USER%%[[:space:]]}"
fi
[[ -z "$GITEA_USER" ]] && { echo "ERROR: No username found. Run /gitea-setup or put your username in ~/.config/gitea/username" >&2; exit 1; }
GITEA_TOKEN="${GITEA_TOKEN:-}"
if [[ -z "$GITEA_TOKEN" && -f "$HOME/.config/gitea/token" ]]; then
GITEA_TOKEN="$(< "$HOME/.config/gitea/token")"
GITEA_TOKEN="${GITEA_TOKEN%%[[:space:]]}"
fi
[[ -z "$GITEA_TOKEN" ]] && { echo "ERROR: No token found. Run /gitea-setup or put your token in ~/.config/gitea/token" >&2; exit 1; }
API_BASE="https://${GITEA_HOST}/api/v1"
# --- Helpers ---
api() {
local method="$1" endpoint="$2"
shift 2
curl -sf -X "$method" "${API_BASE}${endpoint}" \
-H "Content-Type: application/json" \
-H "Authorization: token ${GITEA_TOKEN}" \
"$@"
}
# --- Commands ---
cmd_create() {
local name="" private=false description=""
while [[ $# -gt 0 ]]; do
case "$1" in
--private|-p) private=true; shift ;;
--public) private=false; shift ;;
--description|-d) description="$2"; shift 2 ;;
-*) echo "Unknown option: $1 (I don't know what that means and I'm too proud to guess)" >&2; exit 1 ;;
*) name="$1"; shift ;;
esac
done
[[ -z "$name" ]] && { echo "Usage: gitea create <name> [--private] [--description \"...\"]"; echo " (You forgot the name. The repo needs a name. We all need names.)" >&2; exit 1; }
local payload
payload=$(jq -n \
--arg name "$name" \
--argjson private "$private" \
--arg desc "$description" \
'{name: $name, private: $private, description: $desc, auto_init: false}')
local resp
resp=$(api POST "/user/repos" -d "$payload") || { echo "FAIL: Gitea said no. Check your token and network." >&2; exit 1; }
local html_url
html_url=$(echo "$resp" | jq -r '.html_url')
echo "Created: ${html_url}"
echo "Clone: https://${GITEA_HOST}/${GITEA_USER}/${name}.git"
echo ""
echo "Next up: 'gitea remote ${name}' to wire up your origin. You know the drill."
}
cmd_remote() {
local name="${1:-}"
[[ -z "$name" ]] && { echo "Usage: gitea remote <repo-name>"; echo " (Which repo? I can't read minds. Yet.)" >&2; exit 1; }
local url="https://${GITEA_HOST}/${GITEA_USER}/${name}.git"
git config credential.helper 'store'
local cred_file="${HOME}/.git-credentials"
local cred_entry="https://${GITEA_USER}:${GITEA_TOKEN}@${GITEA_HOST}"
if ! grep -qF "${GITEA_HOST}" "$cred_file" 2>/dev/null; then
echo "$cred_entry" >> "$cred_file"
chmod 600 "$cred_file"
fi
if git remote get-url origin &>/dev/null; then
git remote set-url origin "$url"
echo "Updated origin -> ${url}"
else
git remote add origin "$url"
echo "Added origin -> ${url}"
fi
echo "You're locked and loaded. 'gitea push' when ready."
}
cmd_push() {
local branch
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) || { echo "This isn't a git repo. I checked." >&2; exit 1; }
echo "Pushing ${branch} to origin... hold onto your bits."
git push -u origin "$branch"
}
cmd_delete() {
local name="${1:-}"
[[ -z "$name" ]] && { echo "Usage: gitea delete <repo-name>"; echo " (Delete what? Be specific. Destruction requires precision.)" >&2; exit 1; }
read -rp "Delete ${GITEA_USER}/${name}? This is permanent. No take-backs. [y/N] " confirm
[[ "$confirm" =~ ^[Yy]$ ]] || { echo "Crisis averted. Repo lives another day."; exit 0; }
if api DELETE "/repos/${GITEA_USER}/${name}"; then
echo "Deleted: ${GITEA_USER}/${name}. It's gone. Pour one out."
else
echo "FAIL: Could not delete ${GITEA_USER}/${name}. Maybe it's already gone? Maybe it's fighting back?" >&2; exit 1
fi
}
cmd_list() {
local resp
resp=$(api GET "/user/repos?limit=50&sort=updated") || { echo "FAIL: Couldn't fetch repos. Is Gitea awake?" >&2; exit 1; }
echo "$resp" | jq -r '.[] | "\(.name)\t\(if .private then "private" else "public" end)\t\(.description // "")"' | column -t -s$'\t'
}
cmd_help() {
cat <<'EOF'
gitea — your friendly neighborhood Gitea CLI
Usage: gitea <command> [options]
Commands:
create <name> [--private] [--description "..."] Bring a new repo into this world
remote <name> Wire up git origin with token auth
push Yeet current branch to origin
delete <name> Send a repo into the void (confirms first)
list Show your repos (sorted by last updated)
Examples:
gitea create my-project --private --description "Top secret stuff"
gitea remote my-project
gitea push
Config files (~/.config/gitea/):
token Your API token (required)
username Your Gitea username (required)
host Gitea host override (default: git.sethpc.xyz)
First time? Run /gitea-setup in Claude Code to get started.
EOF
}
case "${1:-help}" in
create) shift; cmd_create "$@" ;;
remote) shift; cmd_remote "$@" ;;
push) shift; cmd_push "$@" ;;
delete) shift; cmd_delete "$@" ;;
list|ls) shift; cmd_list "$@" ;;
help|--help|-h) cmd_help ;;
*) echo "Unknown command: $1 (try 'gitea help' — I promise it's helpful)" >&2; exit 1 ;;
esac
```
- [ ] **Step 2: Make it executable**
```bash
chmod +x /home/claude/bin/gitea-connector/bin/gitea
```
- [ ] **Step 3: Test CLI help output**
```bash
/home/claude/bin/gitea-connector/bin/gitea help
```
Expected: The help text prints with all commands listed and silly flavor text.
- [ ] **Step 4: Test CLI error handling (no config)**
```bash
HOME=/tmp/fakehome /home/claude/bin/gitea-connector/bin/gitea list
```
Expected: Error about missing username, exit code 1.
- [ ] **Step 5: Commit**
```bash
cd /home/claude/bin/gitea-connector
git add bin/gitea
git commit -m "feat: add gitea bash CLI with silly personality"
```
---
### Task 3: Setup Agent
**Files:**
- Create: `gitea-connector/agents/gitea-setup.md`
- [ ] **Step 1: Write the setup agent**
```markdown
---
name: gitea-setup
description: Use this agent when a user needs to connect to the Gitea instance at git.sethpc.xyz. Walks them through API key generation, stores credentials, installs the CLI, and validates everything works.
model: inherit
---
You are the Gitea Setup Wizard — part helpful guide, part chaos goblin, fully committed to getting this human connected to git.sethpc.xyz without anyone crying.
Your job: walk the user through connecting their Claude Code environment to Seth's Gitea instance. Be silly but get the job done.
## Setup Steps
Follow these steps IN ORDER. Use AskUserQuestion for each input step. Do not skip steps.
### Step 1: Dependency Check
Run these commands to verify dependencies:
```bash
command -v curl >/dev/null 2>&1 && echo "curl: OK" || echo "curl: MISSING"
command -v jq >/dev/null 2>&1 && echo "jq: OK" || echo "jq: MISSING"
command -v git >/dev/null 2>&1 && echo "git: OK" || echo "git: MISSING"
```
If anything is MISSING, tell the user what to install and stop. Be dramatic about it:
- "Oh no. You don't have `jq`. That's like showing up to a sword fight with a pool noodle. Install it with `apt install jq` (or your distro's equivalent) and run /gitea-setup again."
If all OK, proceed with enthusiasm.
### Step 2: Check for Existing Config
```bash
ls -la ~/.config/gitea/token 2>/dev/null && echo "EXISTS" || echo "NONE"
```
If EXISTS: Ask the user "You've already got Gitea credentials on file. Want to reconfigure? (This won't delete your repos, just your local config. Repos are forever. Well, until someone runs `gitea delete`.)"
If they say no, stop gracefully: "Smart. If it ain't broke, don't authenticate it."
### Step 3: Collect Username
Ask the user: "What's your Gitea username? (This is your login name at git.sethpc.xyz — not your email, not your display name, not your gamer tag.)"
Store the response for later.
### Step 4: API Key Generation
Tell the user exactly how to generate their token. Use this message:
"Time to forge your API key. Here's the quest:
1. Open **https://git.sethpc.xyz** in your browser and log in
2. Click your **profile picture** (top right corner — yes, that little circle)
3. Go to **Settings**
4. Click **Applications** in the sidebar
5. Under **Manage Access Tokens**, type `claude-code` as the token name
6. For permissions, check **repo** (Read and Write) and **user** (Read)
7. Click **Generate Token**
8. **COPY THE TOKEN NOW** — Gitea only shows it once. It's like a shooting star, except it grants repo access.
Paste the token here when you've got it."
Wait for the token via AskUserQuestion.
### Step 5: Store Credentials
Run these commands (substitute the actual username and token):
```bash
mkdir -p ~/.config/gitea
echo "USERNAME_HERE" > ~/.config/gitea/username
echo "TOKEN_HERE" > ~/.config/gitea/token
chmod 600 ~/.config/gitea/username ~/.config/gitea/token
```
Replace USERNAME_HERE and TOKEN_HERE with the actual values collected.
### Step 6: Install CLI
Copy the CLI from the plugin to ~/bin/:
```bash
mkdir -p ~/bin
cp "${CLAUDE_PLUGIN_ROOT}/bin/gitea" ~/bin/gitea
chmod +x ~/bin/gitea
```
Check if ~/bin is on PATH:
```bash
echo "$PATH" | grep -q "$HOME/bin" && echo "ON_PATH" || echo "NOT_ON_PATH"
```
If NOT_ON_PATH, tell the user: "Heads up — `~/bin` isn't on your PATH. Add this to your `~/.bashrc` or `~/.zshrc`:
```bash
export PATH=\"\$HOME/bin:\$PATH\"
```
Then restart your shell or run `source ~/.bashrc`. Otherwise `gitea` will just sit there, lonely and uncallable."
### Step 7: Validate Token
Test the token by calling the Gitea API:
```bash
curl -sf "https://git.sethpc.xyz/api/v1/user" \
-H "Authorization: token $(cat ~/.config/gitea/token)" | jq -r '.login'
```
Expected: The username they entered in Step 3.
If the returned username matches: proceed to success.
If it doesn't match: "Hmm, the token says you're `<returned>` but you told me `<entered>`. One of these is a lie. Which username is correct?" Then update ~/.config/gitea/username with their answer.
If the request fails entirely: "That token didn't work. Gitea rejected it like a bouncer with standards. Double-check:
- Did you copy the whole token? (No leading/trailing spaces?)
- Did you actually click Generate? (The token only appears once!)
- Can you reach https://git.sethpc.xyz in a browser?
Generate a new token and try /gitea-setup again."
### Step 8: Success
Print the victory message:
"You're in! Here's what just happened:
- Credentials stored in `~/.config/gitea/` (locked down, chmod 600, very secure, much wow)
- CLI installed at `~/bin/gitea`
- Token validated against git.sethpc.xyz — you are who you say you are
**Available commands:**
```
gitea create <name> [--private] [--description "..."]
gitea remote <name>
gitea push
gitea delete <name>
gitea list
```
**Quick start:**
```bash
mkdir my-project && cd my-project && git init
gitea create my-project --description "My cool thing"
gitea remote my-project
# write some code...
git add -A && git commit -m "feat: initial commit"
gitea push
```
Now go build something. The Gitea server believes in you. I believe in you. Your commits will be legendary."
```
- [ ] **Step 2: Commit**
```bash
cd /home/claude/bin/gitea-connector
git add agents/gitea-setup.md
git commit -m "feat: add interactive gitea-setup agent with guided credential flow"
```
---
### Task 4: Setup Command (`/gitea-setup`)
**Files:**
- Create: `gitea-connector/commands/gitea-setup.md`
- [ ] **Step 1: Write the slash command**
```markdown
---
name: gitea-setup
description: Connect to Seth's Gitea instance (git.sethpc.xyz) — guided API key setup
---
Launch the gitea-setup agent to walk the user through connecting to the Gitea instance at git.sethpc.xyz.
This command sets up:
1. API token credentials
2. The `gitea` CLI tool
3. Validates the connection works
Dispatch the gitea-setup agent to handle this interactively.
```
- [ ] **Step 2: Commit**
```bash
cd /home/claude/bin/gitea-connector
git add commands/gitea-setup.md
git commit -m "feat: add /gitea-setup slash command"
```
---
### Task 5: Gitea Workflow Skill
**Files:**
- Create: `gitea-connector/skills/gitea-workflow/SKILL.md`
- [ ] **Step 1: Write the skill**
```markdown
---
name: gitea-workflow
description: This skill should be used when working in a git repository with a git.sethpc.xyz remote, when the user asks to "commit", "push", "create a repo", "gitea", or when making changes to code that should be committed. Provides commit conventions, CLI reference, and credential safety rules.
---
# Gitea Workflow — Commit Conventions & CLI
You're working with a repo hosted on Seth's Gitea instance (`git.sethpc.xyz`). Here's how we roll.
## Commit Conventions (default-on, overridable)
These conventions apply unless the project's CLAUDE.md says otherwise:
- **Conventional commits:** Prefix every commit message with a type:
- `feat:` — new feature
- `fix:` — bug fix
- `docs:` — documentation only
- `refactor:` — code restructuring, no behavior change
- `test:` — adding or updating tests
- `chore:` — maintenance, tooling, deps
- **Commit immediately** — every meaningful change gets its own commit. Don't hoard changes.
- **Always push after commit** — use `gitea push` or `git push`. Code that isn't pushed is just a fancy diary entry.
- **No squashing** — every commit is a record. History is sacred (and also useful for debugging).
- **No batching unrelated changes** — one commit, one concern. If you changed the auth system AND updated the README, that's two commits.
## CLI Reference
The `gitea` CLI handles repo operations against git.sethpc.xyz:
```
gitea create <name> [--private] [--description "..."] # Create a new repo
gitea remote <name> # Set/update git origin with token auth
gitea push # Push current branch to origin
gitea delete <name> # Delete a repo (with confirmation)
gitea list # List your repos
```
For creating a new project from scratch:
```bash
mkdir my-project && cd my-project && git init
gitea create my-project --description "What it does"
gitea remote my-project
# ... write code ...
git add -A && git commit -m "feat: initial commit"
gitea push
```
## Credential Safety
**Never commit these:**
- `~/.config/gitea/token` or `~/.config/gitea/username`
- `.env` files containing secrets
- API keys, tokens, or passwords in any form
**Always ensure `.gitignore` includes:**
```
.env
.env.*
*.key
*.pem
```
If you see credentials in staged files, warn the user immediately and unstage them.
## Override Mechanism
Users can override any convention above in their project's CLAUDE.md. For example, if a project's CLAUDE.md says "squash commits before merge", follow that instead of these defaults. Project-level instructions always win.
```
- [ ] **Step 2: Commit**
```bash
cd /home/claude/bin/gitea-connector
git add skills/gitea-workflow/SKILL.md
git commit -m "feat: add gitea-workflow skill with commit conventions and CLI reference"
```
---
### Task 6: Push Reminder Hook
**Files:**
- Create: `gitea-connector/hooks/hooks.json`
- Create: `gitea-connector/hooks/scripts/push-reminder.sh`
- [ ] **Step 1: Write the hook script**
```bash
#!/usr/bin/env bash
# push-reminder.sh — nudges you to push after a commit
# Reads Bash tool output from stdin (JSON), checks if a git commit happened.
set -euo pipefail
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""')
TOOL_RESULT=$(echo "$INPUT" | jq -r '.tool_result // ""')
# Only trigger on Bash tool
[[ "$TOOL_NAME" == "Bash" ]] || exit 0
# Check if the output looks like a successful git commit
if echo "$TOOL_RESULT" | grep -qE '^\[.+\]\s+\S+'; then
echo '{"decision":"approve","systemMessage":"Commit detected! Friendly reminder: run `gitea push` to send it to git.sethpc.xyz. Unpushed commits are just really elaborate local notes."}'
else
echo '{"decision":"approve"}'
fi
```
- [ ] **Step 2: Make it executable**
```bash
chmod +x /home/claude/bin/gitea-connector/hooks/scripts/push-reminder.sh
```
- [ ] **Step 3: Write hooks.json (hook disabled by default)**
```json
{
"description": "Gitea connector hooks — push reminder after commits (opt-in)",
"hooks": {}
}
```
Note: The hook is shipped disabled. To enable, users update `hooks.json` to:
```json
{
"description": "Gitea connector hooks — push reminder after commits",
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/push-reminder.sh",
"timeout": 5
}
]
}
]
}
}
```
Document this in the README (Task 7).
- [ ] **Step 4: Commit**
```bash
cd /home/claude/bin/gitea-connector
git add hooks/hooks.json hooks/scripts/push-reminder.sh
git commit -m "feat: add push-reminder hook (opt-in, disabled by default)"
```
---
### Task 7: README
**Files:**
- Create: `gitea-connector/README.md`
- [ ] **Step 1: Write the README**
```markdown
# gitea-connector
A Claude Code plugin for connecting to Seth's Gitea instance at `git.sethpc.xyz`. Sets up your credentials, installs a CLI, and teaches Claude Code your commit conventions — so you can focus on writing code instead of remembering how to push it.
## Install
Add this plugin to your Claude Code setup:
```bash
claude plugin add /path/to/gitea-connector
```
Or clone it:
```bash
git clone https://git.sethpc.xyz/Seth/gitea-connector.git
claude plugin add ./gitea-connector
```
## Setup
Run `/gitea-setup` in Claude Code. It'll walk you through everything:
1. Checks you have `curl`, `jq`, and `git` (the holy trinity)
2. Guides you through generating an API token on git.sethpc.xyz
3. Stores your credentials securely in `~/.config/gitea/`
4. Installs the `gitea` CLI to `~/bin/`
5. Validates your connection
The whole thing takes about 2 minutes. Less if you type fast.
## CLI Usage
After setup, you have the `gitea` command:
```bash
gitea create my-project --private --description "Top secret stuff"
gitea remote my-project # wire up git origin
gitea push # push current branch
gitea list # see your repos
gitea delete old-project # delete (with confirmation)
```
## Commit Conventions
The plugin teaches Claude Code these conventions (override in your project's CLAUDE.md):
- **Conventional commits:** `feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `chore:`
- **Commit immediately** — don't hoard changes
- **Always push** — unpushed commits are just elaborate local notes
- **No squashing** — history is sacred
- **One concern per commit** — no bundling unrelated changes
## Push Reminder Hook (opt-in)
Want a nudge after every commit? Edit `hooks/hooks.json` in the plugin directory:
```json
{
"description": "Gitea connector hooks — push reminder after commits",
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/push-reminder.sh",
"timeout": 5
}
]
}
]
}
}
```
## Config Files
All stored in `~/.config/gitea/`:
| File | Purpose |
|------|---------|
| `token` | Your Gitea API token |
| `username` | Your Gitea username |
| `host` | (Optional) Host override, defaults to `git.sethpc.xyz` |
## Requirements
- `curl`, `jq`, `git`
- A Gitea account on `git.sethpc.xyz` (talk to Seth)
- Claude Code
```
- [ ] **Step 2: Commit**
```bash
cd /home/claude/bin/gitea-connector
git add README.md
git commit -m "docs: add README with install, setup, and usage instructions"
```
---
### Task 8: Create Gitea Repo & Push
**Files:**
- No new files
- [ ] **Step 1: Create the Gitea repo**
```bash
cd /home/claude/bin/gitea-connector
~/bin/gitea create gitea-connector --description "Claude Code plugin for connecting to Seth's Gitea instance"
```
- [ ] **Step 2: Set remote**
```bash
cd /home/claude/bin/gitea-connector
~/bin/gitea remote gitea-connector
```
- [ ] **Step 3: Push all commits**
```bash
cd /home/claude/bin/gitea-connector
~/bin/gitea push
```
Expected: All commits pushed to `https://git.sethpc.xyz/Seth/gitea-connector`.