wiki as a repo
This commit is contained in:
parent
a90dca1530
commit
ebccd4aa97
23
SKILL.md
23
SKILL.md
|
|
@ -9,7 +9,10 @@ argument-hint: <owner/repo#issue-number>
|
||||||
|
|
||||||
You orchestrate a multi-phase feature planning workflow using Gitea issues and wiki. The argument `$ARGUMENTS` is in the format `owner/repo#number` (e.g. `pushok/mpns#12`).
|
You orchestrate a multi-phase feature planning workflow using Gitea issues and wiki. The argument `$ARGUMENTS` is in the format `owner/repo#number` (e.g. `pushok/mpns#12`).
|
||||||
|
|
||||||
Read `.claude/skills/fea/referencies/gitea-dto.md` before every invocation — it defines which fields to extract from Gitea responses and how to classify comments.
|
Read `.claude/skills/fea/references/gitea-dto.md` before every invocation — it defines which fields to extract from Gitea responses and how to classify comments.
|
||||||
|
Read `.claude/skills/fea/references/auth.md` for credential setup — agents must authenticate themselves using project-level `.claude/.env`.
|
||||||
|
Read `.claude/skills/fea/references/tea-cli.md` when MCP tools fail — `tea` CLI is the fallback for all Gitea operations.
|
||||||
|
Read `.claude/skills/fea/references/wiki-git.md` for wiki operations — wiki is a git repo cloned into `.wiki/` subfolder.
|
||||||
|
|
||||||
## Argument Parsing
|
## Argument Parsing
|
||||||
|
|
||||||
|
|
@ -20,14 +23,24 @@ Parse `$ARGUMENTS` into three variables:
|
||||||
|
|
||||||
If parsing fails, tell the user: "Expected format: `/fea owner/repo#12`"
|
If parsing fails, tell the user: "Expected format: `/fea owner/repo#12`"
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
Before any Gitea operation, ensure credentials are available:
|
||||||
|
|
||||||
|
1. Check for `.claude/.env` — if missing, create it with empty values (see `references/auth.md`), add to `.gitignore`, tell user to fill in credentials, and **stop**
|
||||||
|
2. Load credentials: `set -a; source .claude/.env; set +a` — if any value is empty, tell user to fill in `.claude/.env` and **stop**
|
||||||
|
3. Verify `tea` login exists: `tea login list` — if not, run `tea login add` per `references/auth.md`
|
||||||
|
|
||||||
## Context Loading
|
## Context Loading
|
||||||
|
|
||||||
Every invocation starts by loading context:
|
Every invocation starts by loading context:
|
||||||
|
|
||||||
1. **Fetch issue** via `mcp__gitea__get_issue_by_index` with `owner`, `repo`, `index=issue_number`
|
1. **Fetch issue** via `mcp__gitea__get_issue_by_index` with `owner`, `repo`, `index=issue_number`
|
||||||
|
- If MCP fails, fallback: `tea api GET /repos/$owner/$repo/issues/$issue_number`
|
||||||
2. **Fetch comments** via `mcp__gitea__get_issue_comments_by_index` with `owner`, `repo`, `index=issue_number`
|
2. **Fetch comments** via `mcp__gitea__get_issue_comments_by_index` with `owner`, `repo`, `index=issue_number`
|
||||||
3. **Extract fields** per `.referencies/gitea-dto.md` — discard everything else
|
- If MCP fails, fallback: `tea api GET /repos/$owner/$repo/issues/$issue_number/comments`
|
||||||
4. **Classify comments** into bot vs user per `.referencies/gitea-dto.md` rules
|
3. **Extract fields** per `references/gitea-dto.md` — discard everything else
|
||||||
|
4. **Classify comments** into bot vs user per `references/gitea-dto.md` rules
|
||||||
|
|
||||||
The issue `title` + `body` is the feature prompt (replaces the old `prompt.md`).
|
The issue `title` + `body` is the feature prompt (replaces the old `prompt.md`).
|
||||||
|
|
||||||
|
|
@ -60,12 +73,12 @@ Feature planning:
|
||||||
|
|
||||||
## Important Rules
|
## Important Rules
|
||||||
|
|
||||||
- ALWAYS read `.referencies/gitea-dto.md` and extract only listed fields — do not pass raw Gitea JSON to agents
|
- ALWAYS read `references/gitea-dto.md` and extract only listed fields — do not pass raw Gitea JSON to agents
|
||||||
- Bot comments MUST start with `<!-- mpns-feature-bot -->` on the very first line
|
- Bot comments MUST start with `<!-- mpns-feature-bot -->` on the very first line
|
||||||
- Session numbering: count existing bot Q&A comments to determine next session number
|
- Session numbering: count existing bot Q&A comments to determine next session number
|
||||||
- Questions should be thoughtful and specific — 3–7 per session
|
- Questions should be thoughtful and specific — 3–7 per session
|
||||||
- Use Russian where the issue is written in Russian
|
- Use Russian where the issue is written in Russian
|
||||||
- Each session should make meaningful progress toward clarity
|
- Each session should make meaningful progress toward clarity
|
||||||
- Wiki page content must be base64-encoded for `create_wiki_page` / `update_wiki_page`
|
- Wiki pages are written as markdown files in `.wiki/` and published via git push (see `references/wiki-git.md`)
|
||||||
- Never post duplicate bot comments — check existing comments before posting
|
- Never post duplicate bot comments — check existing comments before posting
|
||||||
- When posting markdown in comments, ensure code blocks and formatting render correctly on Gitea
|
- When posting markdown in comments, ensure code blocks and formatting render correctly on Gitea
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
# Authentication
|
||||||
|
|
||||||
|
Agents need Gitea credentials to work autonomously via both MCP tools and the `tea` CLI fallback.
|
||||||
|
|
||||||
|
## Credential Source
|
||||||
|
|
||||||
|
Credentials are stored in a **project-level** `.claude/.env` file (never in global env, to avoid overriding user's personal credentials).
|
||||||
|
|
||||||
|
### Required variables
|
||||||
|
|
||||||
|
```
|
||||||
|
GITEA_HOST=https://git.marlerino-apps.io
|
||||||
|
GITEA_ACCESS_TOKEN=<api-token>
|
||||||
|
GITEA_USER=<username>
|
||||||
|
GITEA_PASS=<password>
|
||||||
|
```
|
||||||
|
|
||||||
|
- `GITEA_ACCESS_TOKEN` — primary auth method (API token, used by MCP and `tea`)
|
||||||
|
- `GITEA_USER` / `GITEA_PASS` — fallback for basic auth when token is unavailable
|
||||||
|
|
||||||
|
### Bootstrap
|
||||||
|
|
||||||
|
If `.claude/.env` does not exist, create it with empty values as a template:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p .claude
|
||||||
|
cat > .claude/.env << 'EOF'
|
||||||
|
GITEA_HOST=
|
||||||
|
GITEA_ACCESS_TOKEN=
|
||||||
|
GITEA_USER=
|
||||||
|
GITEA_PASS=
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
Then tell the user: "Created `.claude/.env` — please fill in your Gitea credentials and re-run."
|
||||||
|
Stop execution — do not proceed without credentials.
|
||||||
|
|
||||||
|
Also ensure `.claude/.env` is in `.gitignore`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
grep -qxF '.claude/.env' .gitignore 2>/dev/null || echo '.claude/.env' >> .gitignore
|
||||||
|
```
|
||||||
|
|
||||||
|
### Loading credentials
|
||||||
|
|
||||||
|
Before any Gitea operation, load credentials:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
set -a; source .claude/.env; set +a
|
||||||
|
```
|
||||||
|
|
||||||
|
After loading, verify values are non-empty. If any required variable is empty, tell the user to fill in `.claude/.env` and stop.
|
||||||
|
|
||||||
|
### tea CLI login
|
||||||
|
|
||||||
|
If `tea` is not yet logged in for this project, authenticate using loaded credentials:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tea login add \
|
||||||
|
--name project \
|
||||||
|
--url "$GITEA_HOST" \
|
||||||
|
--token "$GITEA_ACCESS_TOKEN" \
|
||||||
|
--user "$GITEA_USER"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
- `.claude/.env` MUST be in `.gitignore` — never commit credentials
|
||||||
|
- Agents bootstrap `.claude/.env` automatically if missing, but never fill in credential values themselves
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
# Phase 4
|
# Phase 4
|
||||||
|
|
||||||
## Step 1 — Deep codebase analysis
|
## Step 1 — Deep codebase analysis
|
||||||
|
|
||||||
Use the Agent tool with `model: "haiku"` and `subagent_type: "Explore"` with thoroughness "very thorough" to:
|
Use the Agent tool with `model: "haiku"` and `subagent_type: "Explore"` with thoroughness "very thorough" to:
|
||||||
|
|
@ -29,40 +30,59 @@ The plan must produce content for three wiki page types (see `templates/` for fo
|
||||||
- Dependencies and parallel tasks
|
- Dependencies and parallel tasks
|
||||||
- Detailed changes with code sketches
|
- Detailed changes with code sketches
|
||||||
|
|
||||||
## Step 3 — Publish wiki pages
|
## Step 3 — Clone/pull wiki repo
|
||||||
|
|
||||||
|
Follow `references/wiki-git.md` setup instructions:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
set -a; source .claude/.env; set +a
|
||||||
|
WIKI_URL="https://${GITEA_USER}:${GITEA_ACCESS_TOKEN}@${GITEA_HOST#https://}/${owner}/${repo}.wiki.git"
|
||||||
|
|
||||||
|
if [ -d .wiki/.git ]; then
|
||||||
|
git -C .wiki pull --rebase
|
||||||
|
else
|
||||||
|
git clone "$WIKI_URL" .wiki 2>/dev/null || {
|
||||||
|
mkdir -p .wiki && git -C .wiki init && git -C .wiki remote add origin "$WIKI_URL"
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 4 — Write wiki pages
|
||||||
|
|
||||||
Wiki page naming:
|
Wiki page naming:
|
||||||
- **Feature page**: `feature-<issue_number>-<slug>` where `<slug>` is kebab-case issue title (max 40 chars)
|
- **Feature page**: `feature-<issue_number>-<slug>.md` where `<slug>` is kebab-case issue title (max 40 chars)
|
||||||
- **Sub-task pages**: `feature-<issue_number>-<slug>-t<NN>` (e.g. `feature-12-user-auth-t01`)
|
- **Sub-task pages**: `feature-<issue_number>-<slug>-t<NN>.md` (e.g. `feature-12-user-auth-t01.md`)
|
||||||
|
|
||||||
For each page, use `mcp__gitea__create_wiki_page` with:
|
Write all pages as markdown files in `.wiki/` using the Write tool:
|
||||||
- `owner`, `repo`
|
- Feature page from `templates/feature.md`
|
||||||
- `title`: the page name
|
- Each sub-task page from `templates/subtask.md`
|
||||||
- `content_base64`: page content **base64-encoded**
|
|
||||||
- `message`: descriptive commit message
|
|
||||||
|
|
||||||
To base64-encode, use Bash: `echo -n '<content>' | base64 -w0`
|
## Step 5 — Update Home wiki page
|
||||||
|
|
||||||
If a page already exists (tool errors), use `mcp__gitea__update_wiki_page` instead with `pageName` set to the page name.
|
If `.wiki/Home.md` does not exist, create it using `templates/readme.md` format with the current feature as the first row.
|
||||||
|
|
||||||
## Step 4 — Update README wiki page
|
If it exists, read it and append a new row for this feature to the table.
|
||||||
|
|
||||||
Check if a `README` wiki page exists via `mcp__gitea__get_wiki_page` (`pageName: "README"`).
|
|
||||||
|
|
||||||
- If it does not exist, create it using the `templates/readme.md` format with the current feature as the first row.
|
|
||||||
- If it exists, decode its content, append a new row for this feature to the table, and update it.
|
|
||||||
|
|
||||||
Feature table row format:
|
Feature table row format:
|
||||||
```
|
```
|
||||||
| <issue_number> | [<title>](<issue_url>) | Planning | [Wiki](<feature_wiki_url>) |
|
| <issue_number> | [<title>](<issue_url>) | Planning | [Wiki](<feature_wiki_url>) |
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 5 — Post plan link as comment
|
## Step 6 — Publish wiki
|
||||||
|
|
||||||
Construct the wiki URL: `https://<GITEA_HOST>/<owner>/<repo>/wiki/<page-name>`
|
Commit and push all pages atomically:
|
||||||
(GITEA_HOST is `git.marlerino-apps.io`)
|
|
||||||
|
|
||||||
Post a comment on the issue:
|
```bash
|
||||||
|
git -C .wiki add -A
|
||||||
|
git -C .wiki commit -m "feat(wiki): publish plan for issue #${issue_number}"
|
||||||
|
git -C .wiki push -u origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 7 — Post plan link as comment
|
||||||
|
|
||||||
|
Construct wiki URLs: `https://$GITEA_HOST/$owner/$repo/wiki/<page-name>` (page-name = filename without `.md`).
|
||||||
|
|
||||||
|
Post a comment on the issue via `mcp__gitea__create_issue_comment` (or `tea` fallback):
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
<!-- mpns-feature-bot -->
|
<!-- mpns-feature-bot -->
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
# tea CLI — Gitea CLI Fallback
|
||||||
|
|
||||||
|
`tea` is a CLI tool for Gitea. Use it as a backup when MCP tools fail or are unavailable.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- `tea` must be installed (`brew install tea` or `go install gitea.com/gitea/tea@latest`)
|
||||||
|
- Authenticated via `tea login add` (see `references/auth.md`)
|
||||||
|
|
||||||
|
## Common Operations
|
||||||
|
|
||||||
|
### Issues
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List issues
|
||||||
|
tea issues --repo owner/repo
|
||||||
|
|
||||||
|
# View issue details
|
||||||
|
tea issues --repo owner/repo 12
|
||||||
|
|
||||||
|
# Search issues
|
||||||
|
tea issues --repo owner/repo --state open --labels bug
|
||||||
|
|
||||||
|
# Create issue comment
|
||||||
|
tea comment --repo owner/repo 12 "comment body"
|
||||||
|
```
|
||||||
|
|
||||||
|
### API fallback (raw)
|
||||||
|
|
||||||
|
When a specific `tea` subcommand doesn't exist, use the raw API:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# GET request
|
||||||
|
tea api GET /repos/{owner}/{repo}/issues/{index}
|
||||||
|
|
||||||
|
# POST request
|
||||||
|
tea api POST /repos/{owner}/{repo}/issues/{index}/comments --body '{"body": "text"}'
|
||||||
|
|
||||||
|
# Wiki pages
|
||||||
|
tea api GET /repos/{owner}/{repo}/wiki/pages
|
||||||
|
tea api GET /repos/{owner}/{repo}/wiki/page/{pageName}
|
||||||
|
tea api POST /repos/{owner}/{repo}/wiki/new --body '{"title":"page","content_base64":"..."}'
|
||||||
|
tea api PATCH /repos/{owner}/{repo}/wiki/page/{pageName} --body '{"content_base64":"..."}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Debugging
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check current login
|
||||||
|
tea login list
|
||||||
|
|
||||||
|
# Test connectivity
|
||||||
|
tea api GET /version
|
||||||
|
|
||||||
|
# View repo info
|
||||||
|
tea repos --repo owner/repo
|
||||||
|
```
|
||||||
|
|
||||||
|
## When to Use tea vs MCP
|
||||||
|
|
||||||
|
| Scenario | Preferred |
|
||||||
|
|----------|-----------|
|
||||||
|
| Normal workflow | MCP tools (`mcp__gitea__*`) |
|
||||||
|
| MCP server down / unreachable | `tea` CLI |
|
||||||
|
| Investigating errors / debugging | `tea api` for raw responses |
|
||||||
|
| Bulk operations / scripting | `tea` CLI in Bash |
|
||||||
|
|
@ -0,0 +1,105 @@
|
||||||
|
# Wiki as Git Repository
|
||||||
|
|
||||||
|
Gitea wikis are backed by bare git repos at `<repo-url>.wiki.git`. Instead of using the API (base64 encoding, one page at a time), we clone the wiki repo as a project subfolder and work with plain markdown files.
|
||||||
|
|
||||||
|
## Wiki directory
|
||||||
|
|
||||||
|
The wiki is cloned into `.wiki/` at the project root:
|
||||||
|
|
||||||
|
```
|
||||||
|
project-root/
|
||||||
|
├── .claude/.env
|
||||||
|
├── .wiki/ ← wiki git repo
|
||||||
|
│ ├── Home.md
|
||||||
|
│ ├── feature-12-user-auth.md
|
||||||
|
│ ├── feature-12-user-auth-t01.md
|
||||||
|
│ └── ...
|
||||||
|
└── src/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Setup (once per project)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
set -a; source .claude/.env; set +a
|
||||||
|
|
||||||
|
WIKI_URL="https://${GITEA_USER}:${GITEA_ACCESS_TOKEN}@${GITEA_HOST#https://}/${owner}/${repo}.wiki.git"
|
||||||
|
|
||||||
|
if [ -d .wiki/.git ]; then
|
||||||
|
git -C .wiki pull --rebase
|
||||||
|
else
|
||||||
|
git clone "$WIKI_URL" .wiki
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
If the wiki repo doesn't exist yet (first wiki page), initialize it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p .wiki && cd .wiki
|
||||||
|
git init
|
||||||
|
git remote add origin "$WIKI_URL"
|
||||||
|
echo "# Wiki" > Home.md
|
||||||
|
git add Home.md
|
||||||
|
git commit -m "init wiki"
|
||||||
|
git push -u origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
## Writing pages
|
||||||
|
|
||||||
|
Just write markdown files in `.wiki/`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Write a page (filename = page name on Gitea)
|
||||||
|
cat > .wiki/feature-12-user-auth.md << 'EOF'
|
||||||
|
# User Authentication
|
||||||
|
...
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
Page naming rules:
|
||||||
|
- Filename (without `.md`) = wiki page name
|
||||||
|
- Use kebab-case: `feature-12-user-auth.md`
|
||||||
|
- Sub-tasks: `feature-12-user-auth-t01.md`
|
||||||
|
- Home/index: `Home.md`
|
||||||
|
|
||||||
|
## Publishing
|
||||||
|
|
||||||
|
After writing all pages, commit and push in one go:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd .wiki
|
||||||
|
git add -A
|
||||||
|
git commit -m "feat(wiki): publish plan for issue #12"
|
||||||
|
git push
|
||||||
|
```
|
||||||
|
|
||||||
|
This is atomic — all pages appear at once, unlike the API approach.
|
||||||
|
|
||||||
|
## Reading pages
|
||||||
|
|
||||||
|
Just read files from `.wiki/`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat .wiki/feature-12-user-auth.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Wiki URL construction
|
||||||
|
|
||||||
|
Page URLs on Gitea: `https://$GITEA_HOST/$owner/$repo/wiki/$page-name`
|
||||||
|
|
||||||
|
Where `$page-name` is the filename without `.md`.
|
||||||
|
|
||||||
|
## .gitignore
|
||||||
|
|
||||||
|
Add `.wiki/` to the project's `.gitignore` — it's a separate repo, not part of the main project:
|
||||||
|
|
||||||
|
```
|
||||||
|
.wiki/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advantages over API
|
||||||
|
|
||||||
|
- No base64 encoding
|
||||||
|
- Write multiple pages, publish atomically
|
||||||
|
- Read/edit pages with standard file tools (Read, Edit, Write)
|
||||||
|
- Full git history for wiki changes
|
||||||
|
- Works offline, push when ready
|
||||||
Loading…
Reference in New Issue