init
This commit is contained in:
commit
a90dca1530
|
|
@ -0,0 +1,71 @@
|
||||||
|
---
|
||||||
|
name: fea
|
||||||
|
description: Issue-driven feature planning workflow via Gitea. Reads issue as prompt, discusses requirements via issue comments, publishes implementation plan to wiki. Triggered with /fea owner/repo#number.
|
||||||
|
user-invocable: true
|
||||||
|
argument-hint: <owner/repo#issue-number>
|
||||||
|
---
|
||||||
|
|
||||||
|
# Issue-Driven Feature Planning Skill
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
## Argument Parsing
|
||||||
|
|
||||||
|
Parse `$ARGUMENTS` into three variables:
|
||||||
|
- `owner` — everything before `/`
|
||||||
|
- `repo` — between `/` and `#`
|
||||||
|
- `issue_number` — after `#` (integer)
|
||||||
|
|
||||||
|
If parsing fails, tell the user: "Expected format: `/fea owner/repo#12`"
|
||||||
|
|
||||||
|
## Context Loading
|
||||||
|
|
||||||
|
Every invocation starts by loading context:
|
||||||
|
|
||||||
|
1. **Fetch issue** via `mcp__gitea__get_issue_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
|
||||||
|
4. **Classify comments** into bot vs user per `.referencies/gitea-dto.md` rules
|
||||||
|
|
||||||
|
The issue `title` + `body` is the feature prompt (replaces the old `prompt.md`).
|
||||||
|
|
||||||
|
## Phase Detection
|
||||||
|
|
||||||
|
Detect the current phase from the comment history:
|
||||||
|
|
||||||
|
1. **No bot comments at all** → Phase 1: Explore & Ask
|
||||||
|
2. **Latest bot comment has `### Questions`, no user comment posted after it** → Phase 2: Waiting for answers
|
||||||
|
3. **Latest bot comment has `### Questions`, user comment exists after it** → Phase 3: Process answers
|
||||||
|
4. **Latest bot comment has `<!-- status:ready -->`, no plan-published marker** → Phase 4: Generate plan
|
||||||
|
5. **Bot comment with `# Implementation Plan` exists** → Done: tell user the plan is already published, show the wiki link
|
||||||
|
|
||||||
|
## Phase 1: Explore & Ask
|
||||||
|
Issue understanding phase described at:
|
||||||
|
- `references/phases/phase1-understanding.md`
|
||||||
|
|
||||||
|
## Phase 2: Waiting for Answers
|
||||||
|
|
||||||
|
The latest bot comment has questions but no user reply after it. Tell the user:
|
||||||
|
"Waiting for your answers on the issue. Reply to the questions comment and re-run `/fea $ARGUMENTS`."
|
||||||
|
|
||||||
|
## Phase 3: Process Answers
|
||||||
|
Conversation reconstruction analyzing and responce phase described at:
|
||||||
|
- `references/phases/phase3-conversation.md`
|
||||||
|
|
||||||
|
## Phase 4: Generate Plan
|
||||||
|
Feature planning:
|
||||||
|
- `references/phases/phase4-planning.md`
|
||||||
|
|
||||||
|
## Important Rules
|
||||||
|
|
||||||
|
- ALWAYS read `.referencies/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
|
||||||
|
- Session numbering: count existing bot Q&A comments to determine next session number
|
||||||
|
- Questions should be thoughtful and specific — 3–7 per session
|
||||||
|
- Use Russian where the issue is written in Russian
|
||||||
|
- Each session should make meaningful progress toward clarity
|
||||||
|
- Wiki page content must be base64-encoded for `create_wiki_page` / `update_wiki_page`
|
||||||
|
- Never post duplicate bot comments — check existing comments before posting
|
||||||
|
- When posting markdown in comments, ensure code blocks and formatting render correctly on Gitea
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
# Gitea DTO Reference
|
||||||
|
|
||||||
|
Raw Gitea API responses are large. When processing responses in this skill, extract **only** the fields listed below. Discard everything else before passing data to agents or storing in context.
|
||||||
|
|
||||||
|
## Issue (`get_issue_by_index`)
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"number": int, // issue index
|
||||||
|
"title": string, // issue title
|
||||||
|
"body": string, // issue description (markdown)
|
||||||
|
"state": string, // "open" | "closed"
|
||||||
|
"labels": [{ "name": string }],
|
||||||
|
"user": { "login": string },
|
||||||
|
"created_at": string,
|
||||||
|
"html_url": string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Discard**: `id`, `url`, `original_author`, `original_author_id`, `ref`, `milestone`, `assignees`, `is_locked`, `pull_request`, `repository`, full `user` object (keep only `login`), full `labels` objects (keep only `name`).
|
||||||
|
|
||||||
|
## Comment (`get_issue_comments_by_index`)
|
||||||
|
|
||||||
|
Response is an array. Per comment extract:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"id": int, // comment ID (needed for edit_issue_comment)
|
||||||
|
"body": string, // comment body (markdown)
|
||||||
|
"user": { "login": string },
|
||||||
|
"created_at": string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Discard**: `html_url`, `pull_request_url`, `issue_url`, `original_author`, `original_author_id`, `assets`, `updated_at`, full `user` object (keep only `login`).
|
||||||
|
|
||||||
|
## Comment classification
|
||||||
|
|
||||||
|
After extracting comment fields, classify each comment:
|
||||||
|
|
||||||
|
- **Bot comment**: `body` starts with `<!-- mpns-feature-bot -->`
|
||||||
|
- **User comment**: everything else
|
||||||
|
|
||||||
|
Bot comments are further classified by phase marker:
|
||||||
|
- Contains `### Questions` → Q&A session comment
|
||||||
|
- Contains `<!-- status:ready -->` → ready-for-planning marker
|
||||||
|
- Contains `## Implementation Plan` → plan-published marker
|
||||||
|
|
||||||
|
## Wiki page (`get_wiki_page`)
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"title": string,
|
||||||
|
"content": string, // base64-encoded page content
|
||||||
|
"html_url": string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Discard**: `sub_url`, `commit_count`, `sidebar`, `footer`, `last_commit`.
|
||||||
|
|
||||||
|
## Tool parameter reference
|
||||||
|
|
||||||
|
### Read operations
|
||||||
|
|
||||||
|
| Tool | Required params |
|
||||||
|
|------|----------------|
|
||||||
|
| `get_issue_by_index` | `owner`, `repo`, `index` (int) |
|
||||||
|
| `get_issue_comments_by_index` | `owner`, `repo`, `index` (int) |
|
||||||
|
| `get_wiki_page` | `owner`, `repo`, `pageName` (string) |
|
||||||
|
| `list_wiki_pages` | `owner`, `repo` |
|
||||||
|
|
||||||
|
### Write operations
|
||||||
|
|
||||||
|
| Tool | Required params | Notes |
|
||||||
|
|------|----------------|-------|
|
||||||
|
| `create_issue_comment` | `owner`, `repo`, `index` (int), `body` (string) | Body is markdown |
|
||||||
|
| `edit_issue_comment` | `owner`, `repo`, `commentID` (int), `body` (string) | |
|
||||||
|
| `create_wiki_page` | `owner`, `repo`, `title` (string), `content_base64` (string) | Content must be base64-encoded |
|
||||||
|
| `update_wiki_page` | `owner`, `repo`, `pageName` (string), `content_base64` (string) | Optional: `title`, `message` |
|
||||||
|
| `edit_issue` | `owner`, `repo`, `index` (int) | Optional: `title`, `body`, `state`, `assignees`, `milestone` |
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
# Phase 1
|
||||||
|
## Step 1 — Understand the issue
|
||||||
|
|
||||||
|
Read the issue title and body. This is the user's raw feature request.
|
||||||
|
|
||||||
|
## Step 2 — Explore the codebase
|
||||||
|
|
||||||
|
Use the Agent tool with `model: "haiku"` and `subagent_type: "Explore"` to scan the codebase for context relevant to the feature. Ask the agent to:
|
||||||
|
- Find all files, types, interfaces, and functions related to the feature's domain
|
||||||
|
- Identify architectural layers that will be affected
|
||||||
|
- Note existing patterns and conventions
|
||||||
|
- Return a structured summary
|
||||||
|
|
||||||
|
## Step 3 — Post questions as issue comment
|
||||||
|
|
||||||
|
Use `mcp__gitea__create_issue_comment` to post a comment on the issue. The comment body MUST follow this exact format:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
<!-- mpns-feature-bot -->
|
||||||
|
# Feature Analysis — Session 01
|
||||||
|
|
||||||
|
## Context
|
||||||
|
<Summary of codebase findings — key files, patterns, existing structures relevant to this feature>
|
||||||
|
|
||||||
|
---
|
||||||
|
## Questions
|
||||||
|
1. <question>
|
||||||
|
2. <question>
|
||||||
|
...
|
||||||
|
|
||||||
|
---
|
||||||
|
*Reply with your answers, then re-run `/fea $ARGUMENTS`.*
|
||||||
|
```
|
||||||
|
|
||||||
|
Rules for questions:
|
||||||
|
- 3–7 questions per session
|
||||||
|
- Ask about: ambiguities, domain model decisions, behavioral edge cases, integration points
|
||||||
|
- Be specific — avoid generic "tell me more" questions
|
||||||
|
- Use Russian if the issue body is in Russian
|
||||||
|
|
||||||
|
Tell the user: "I've posted questions as a comment on the issue. Answer there and re-run `/fea $ARGUMENTS`."
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
# Phase 3
|
||||||
|
## Step 1 — Build conversation history
|
||||||
|
|
||||||
|
Reconstruct the full Q&A history from comments:
|
||||||
|
- Issue body = original prompt
|
||||||
|
- Bot comments with `## Questions` = sessions (ordered by `created_at`)
|
||||||
|
- User comments after each bot Q&A comment = answers for that session
|
||||||
|
|
||||||
|
## Step 2 — Analyze
|
||||||
|
|
||||||
|
Use the Agent tool with `model: "opus"` and `subagent_type: "general-purpose"` to analyze:
|
||||||
|
- The user's latest answers
|
||||||
|
- The full conversation history (all sessions)
|
||||||
|
- The current codebase context
|
||||||
|
- Whether the feature is fully understood or needs more clarification
|
||||||
|
|
||||||
|
The agent should return:
|
||||||
|
- A feature description summary (what was clarified, what remains unclear)
|
||||||
|
- Either `CLEAR` (no more questions) or a list of follow-up questions
|
||||||
|
|
||||||
|
## Step 3 — Post result
|
||||||
|
|
||||||
|
**If follow-up questions needed** — post a new session comment:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
<!-- mpns-feature-bot -->
|
||||||
|
# Feature Analysis — Session NN
|
||||||
|
|
||||||
|
## Context
|
||||||
|
<Brief recap of what was clarified in the last round>
|
||||||
|
|
||||||
|
---
|
||||||
|
## Questions
|
||||||
|
1. <follow-up question>
|
||||||
|
2. <follow-up question>
|
||||||
|
...
|
||||||
|
|
||||||
|
---
|
||||||
|
*Reply with your answers, then re-run `/fea $ARGUMENTS`.*
|
||||||
|
```
|
||||||
|
|
||||||
|
Increment the session number based on how many bot Q&A comments already exist.
|
||||||
|
|
||||||
|
Tell the user to answer and re-run.
|
||||||
|
|
||||||
|
**If everything is CLEAR** — post a ready-for-planning comment:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
<!-- mpns-feature-bot -->
|
||||||
|
<!-- status:ready -->
|
||||||
|
# Feature Description
|
||||||
|
|
||||||
|
**Status**: Ready for planning
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
<1-2 sentence summary>
|
||||||
|
|
||||||
|
## Behavior
|
||||||
|
<Bulleted list of expected behaviors>
|
||||||
|
|
||||||
|
## Domain Changes
|
||||||
|
<Expected domain model changes>
|
||||||
|
|
||||||
|
## Affected Layers
|
||||||
|
<Architectural layers and key files>
|
||||||
|
|
||||||
|
---
|
||||||
|
*Feature is fully understood. Re-run `/fea $ARGUMENTS` to generate the implementation plan.*
|
||||||
|
```
|
||||||
|
|
||||||
|
Tell the user: "Feature description is complete. Review the comment on the issue. When ready, re-run `/fea $ARGUMENTS` to generate the plan."
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
# Phase 4
|
||||||
|
## Step 1 — Deep codebase analysis
|
||||||
|
|
||||||
|
Use the Agent tool with `model: "haiku"` and `subagent_type: "Explore"` with thoroughness "very thorough" to:
|
||||||
|
- Map every file that will be created or modified
|
||||||
|
- Identify dependency order between changes
|
||||||
|
- Find existing test patterns
|
||||||
|
- Note migration requirements
|
||||||
|
|
||||||
|
## Step 2 — Create plan
|
||||||
|
|
||||||
|
Use the Agent tool with `model: "opus"` and `subagent_type: "general-purpose"` to design the implementation plan based on:
|
||||||
|
- The feature description from the `<!-- status:ready -->` comment
|
||||||
|
- Full Q&A history from all session comments
|
||||||
|
- Codebase exploration results
|
||||||
|
- The project's existing patterns (DDD layers, aggregate repos, hand-written SQL, Watermill messaging, etc.)
|
||||||
|
|
||||||
|
The plan must produce content for three wiki page types (see `templates/` for format):
|
||||||
|
|
||||||
|
### Feature page content
|
||||||
|
- Problem summary
|
||||||
|
- Design decisions
|
||||||
|
- Task dependency graph (ASCII)
|
||||||
|
- Tasks table with IDs and titles
|
||||||
|
|
||||||
|
### Sub-task pages content (one per task: T01, T02, ...)
|
||||||
|
- Description of what the task accomplishes
|
||||||
|
- Files created/modified
|
||||||
|
- Dependencies and parallel tasks
|
||||||
|
- Detailed changes with code sketches
|
||||||
|
|
||||||
|
## Step 3 — Publish wiki pages
|
||||||
|
|
||||||
|
Wiki page naming:
|
||||||
|
- **Feature page**: `feature-<issue_number>-<slug>` 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`)
|
||||||
|
|
||||||
|
For each page, use `mcp__gitea__create_wiki_page` with:
|
||||||
|
- `owner`, `repo`
|
||||||
|
- `title`: the page name
|
||||||
|
- `content_base64`: page content **base64-encoded**
|
||||||
|
- `message`: descriptive commit message
|
||||||
|
|
||||||
|
To base64-encode, use Bash: `echo -n '<content>' | base64 -w0`
|
||||||
|
|
||||||
|
If a page already exists (tool errors), use `mcp__gitea__update_wiki_page` instead with `pageName` set to the page name.
|
||||||
|
|
||||||
|
## Step 4 — Update README wiki page
|
||||||
|
|
||||||
|
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:
|
||||||
|
```
|
||||||
|
| <issue_number> | [<title>](<issue_url>) | Planning | [Wiki](<feature_wiki_url>) |
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 5 — Post plan link as comment
|
||||||
|
|
||||||
|
Construct the wiki URL: `https://<GITEA_HOST>/<owner>/<repo>/wiki/<page-name>`
|
||||||
|
(GITEA_HOST is `git.marlerino-apps.io`)
|
||||||
|
|
||||||
|
Post a comment on the issue:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
<!-- mpns-feature-bot -->
|
||||||
|
# Implementation Plan
|
||||||
|
|
||||||
|
Published to wiki: [<feature-page-name>](<feature-wiki-url>)
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
- [ ] T01: [<task title>](<t01-wiki-url>)
|
||||||
|
- [ ] T02: [<task title>](<t02-wiki-url>)
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
Tell the user: "Implementation plan published to wiki. Link posted on the issue."
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
# {{FEATURE_TITLE}}
|
||||||
|
|
||||||
|
> Issue: [#{{ISSUE_NUMBER}}]({{ISSUE_URL}})
|
||||||
|
|
||||||
|
## Problem
|
||||||
|
|
||||||
|
{{PROBLEM_SUMMARY}}
|
||||||
|
|
||||||
|
## Design Decisions
|
||||||
|
|
||||||
|
{{DESIGN_DECISIONS}}
|
||||||
|
|
||||||
|
## Task Dependency Graph
|
||||||
|
|
||||||
|
```
|
||||||
|
{{DEPENDENCY_GRAPH}}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
| Task | Title | Status | Wiki |
|
||||||
|
|------|-------|--------|------|
|
||||||
|
{{TASKS_TABLE}}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Features
|
||||||
|
|
||||||
|
| # | Feature | Status | Wiki |
|
||||||
|
|---|---------|--------|------|
|
||||||
|
{{FEATURES_TABLE}}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
# {{TASK_ID}}: {{TASK_TITLE}}
|
||||||
|
|
||||||
|
> Feature: [{{FEATURE_PAGE}}]({{FEATURE_WIKI_URL}}) | Issue: [#{{ISSUE_NUMBER}}]({{ISSUE_URL}})
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
{{TASK_DESCRIPTION}}
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
| Action | Path |
|
||||||
|
|--------|------|
|
||||||
|
{{FILES_TABLE}}
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- **Blocked by**: {{BLOCKED_BY}}
|
||||||
|
- **Parallel with**: {{PARALLEL_WITH}}
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
{{DETAILED_CHANGES}}
|
||||||
Loading…
Reference in New Issue