Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:01:30 +08:00
commit 9c0b92f025
39 changed files with 9512 additions and 0 deletions

0
spec-authoring/.gitkeep Normal file
View File

125
spec-authoring/SKILL.md Normal file
View File

@@ -0,0 +1,125 @@
---
name: spec-authoring
description: Use this skill to propose changes via the Spec PR process. It uses the Gemini CLI to generate high-quality draft specifications and to analyze PR feedback, accelerating the spec-driven development workflow. Triggers include "create spec" or "propose change".
---
# Spec Authoring Skill
## Purpose
To manage the creation and refinement of feature specifications using a powerful, AI-assisted workflow. This skill leverages the **Gemini CLI** to accelerate the spec-driven development process by:
1. **Generating Drafts**: Automatically creates high-quality, multi-file draft proposals for new features.
2. **Analyzing Feedback**: Synthesizes review comments from Pull Requests into an actionable summary of recommended changes.
This approach allows developers and product managers to move from idea to an approved, implementation-ready specification with greater speed and clarity.
## When to Use
Use this skill in the following situations:
- Proposing a new feature or significant change.
- Generating a first draft of a specification for review.
- Processing and incorporating feedback from a Spec PR.
## Prerequisites
- Project initialized with SynthesisFlow structure (`docs/specs/` and `docs/changes/` directories exist).
- GitHub repository set up.
- `gh` CLI tool installed and authenticated.
- `gemini` CLI tool installed and authenticated.
## Spec PR Philosophy
**Specs as Code**: All specification changes follow the same rigor as code changes—proposed via branches, reviewed via PRs, and merged upon approval. This skill supercharges that philosophy with AI.
---
## The `propose` Command
### Purpose
Generate a comprehensive, multi-file draft proposal for a new feature from a single command.
### Workflow
#### Step 1: Define the Proposal Name
Choose a clear, descriptive name for your feature, such as "User Authentication System" or "Real-time Notifications".
#### Step 2: Run the Helper Script
Execute the script to generate the draft proposal:
```bash
bash scripts/spec-authoring.sh propose "Feature Name"
```
The script will:
1. Create a new directory in `docs/changes/feature-name/`.
2. Make three parallel calls to the **Gemini CLI** to generate drafts for `proposal.md`, `spec-delta.md`, and `tasks.md`.
- **`proposal.md`**: A high-level overview with problem statement, proposed solution, and success criteria.
- **`spec-delta.md`**: A detailed technical specification with requirements and design decisions.
- **`tasks.md`**: A preliminary breakdown of implementation tasks.
3. Save the AI-generated content into these files.
#### Step 3: Review and Refine the Drafts
The script provides you with a complete, context-aware first draft of your entire proposal. Your next step is to review and refine these documents to ensure they align with your vision before opening a Spec PR.
---
## The `update` Command
### Purpose
Intelligently process feedback from a Spec PR by using AI to analyze review comments and generate a summarized action plan.
### Workflow
#### Step 1: Identify the PR Number
Determine which Spec PR you need to update.
#### Step 2: Run the Feedback Analysis Script
Execute the script with the PR number:
```bash
bash scripts/spec-authoring.sh update PR_NUMBER
```
This command will:
1. Find the local files associated with the PR's branch.
2. Fetch all review comments from the PR.
3. Send the full content of your spec files and all the comments to the **Gemini CLI**.
4. Ask the AI to act as a reviewer and provide a summarized list of recommended changes for each file.
#### Step 3: Address the Synthesized Feedback
The script will output a clear, actionable plan that synthesizes all the reviewer feedback. Use this analysis to efficiently update your proposal files, address the comments, and push your changes for re-review.
---
## Error Handling
### Gemini CLI Issues
**Symptom**: The script fails during the `propose` or `update` commands with an error related to the `gemini` command.
**Solution**:
- Ensure the `gemini` CLI is installed and in your system's PATH.
- Verify you are authenticated (`gemini auth`).
- Check for Gemini API outages or network issues.
### Proposal Directory Already Exists
**Symptom**: The `propose` command reports that the directory already exists.
**Solution**: Choose a different name for your proposal or work with the existing one.
### Could Not Find Proposal Directory
**Symptom**: The `update` command cannot find the local files for the PR.
**Solution**: Ensure you have the correct PR branch checked out and that the local directory in `docs/changes/` matches the branch name.
## Notes
- **AI-Assisted Workflow**: This skill is designed to be a powerful assistant. It generates high-quality drafts and analyzes feedback, but the final strategic decisions and refinements are yours to make.
- **Speed and Quality**: By automating the initial drafting and feedback synthesis, this skill allows you to focus on the high-value work of design, review, and alignment.
- **Iterative Process**: Use the `propose` command to start, and the `update` command to iterate based on team feedback, creating a rapid and efficient spec development cycle.

View File

@@ -0,0 +1,180 @@
#!/bin/bash
# This script manages the authoring of specification proposals.
set -e
# --- COMMANDS ---
function propose() {
local proposal_name=$1
if [ -z "$proposal_name" ]; then
echo "Error: Proposal name not provided for 'propose' command." >&2
echo "Usage: $0 propose <proposal-name>" >&2
exit 1
fi
local dir_name=$(echo "$proposal_name" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
local proposal_dir="docs/changes/$dir_name"
echo "Generating draft specification for: $proposal_name"
if [ -d "$proposal_dir" ]; then
echo "Error: Proposal directory '$proposal_dir' already exists." >&2
exit 1
fi
mkdir -p "$proposal_dir"
echo "Generating draft files with Gemini (chained calls for better coherence)..."
# Step 1: Generate proposal.md and capture its content
echo "Step 1/3: Generating proposal.md..."
gemini -p "Generate a high-level project proposal in markdown for a feature called '${proposal_name}'. Include sections for Problem Statement, Proposed Solution, Benefits, and Success Criteria." > "$proposal_dir/proposal.md"
local proposal_content=$(cat "$proposal_dir/proposal.md")
# Step 2: Generate spec-delta.md using proposal.md as context
echo "Step 2/3: Generating spec-delta.md (using proposal as context)..."
gemini -p "Generate a detailed technical specification delta in markdown for a feature called '${proposal_name}'.
Use the following proposal as context to ensure alignment and coherence:
---
${proposal_content}
---
Based on the proposal above, create a specification delta that includes sections for:
- Overview (aligned with the proposal's problem statement and solution)
- Detailed Requirements (elaborating on the proposed solution)
- Key Design Decisions (technical choices to implement the solution)
- Potential Migration Path (if applicable)
Ensure the spec-delta directly supports and elaborates on the proposal's goals." > "$proposal_dir/spec-delta.md"
local spec_delta_content=$(cat "$proposal_dir/spec-delta.md")
# Step 3: Generate tasks.yml using both proposal.md and spec-delta.md as context
echo "Step 3/3: Generating tasks.yml (using proposal and spec-delta as context)..."
gemini -p "Generate a preliminary task breakdown in YAML format for implementing a feature called '${proposal_name}'.
Use the following proposal and specification delta as context:
**Proposal:**
---
${proposal_content}
---
**Specification Delta:**
---
${spec_delta_content}
---
Based on the proposal and spec-delta above, generate a task breakdown that follows this exact YAML structure:
epic: \"Feature: ${proposal_name}\"
tasks:
- title: \"Task: Backend API Implementation\"
description: \"Implement the core backend API endpoints and business logic for the ${proposal_name} feature.\"
labels:
type: \"feature\"
component: \"backend\"
priority: \"P0\"
- title: \"Task: Frontend UI Development\"
description: \"Create the user interface components and pages for the ${proposal_name} feature.\"
labels:
type: \"feature\"
component: \"frontend\"
priority: \"P1\"
- title: \"Task: Database Schema\"
description: \"Design and implement the database schema changes required for ${proposal_name}.\"
labels:
type: \"refactor\"
component: \"database\"
priority: \"P1\"
- title: \"Task: Testing\"
description: \"Write comprehensive unit and integration tests for the ${proposal_name} feature.\"
labels:
type: \"test\"
component: \"testing\"
priority: \"P2\"
Generate additional relevant tasks following the same structure, based on the specific requirements in the proposal and spec-delta. Each task must have title, description, and labels with type and component. The type should be one of: feature, enhancement, refactor, bug, chore, docs, test. The component should indicate which part of the system this task belongs to.
Ensure the tasks directly implement the requirements specified in the spec-delta and align with the proposal's goals." > "$proposal_dir/tasks.yml"
echo "Successfully generated draft proposal in $proposal_dir"
echo "Next step: Review and refine the generated markdown files, then open a Spec PR."
}
function update() {
local pr_number=$1
if [ -z "$pr_number" ]; then
echo "Error: Pull request number not provided for 'update' command." >&2
echo "Usage: $0 update <pr-number>" >&2
exit 1
fi
echo "Fetching PR details and synthesizing review feedback for PR #$pr_number..."
# Get the branch name from the PR
local branch_name=$(gh pr view "$pr_number" --json headRefName -q '.headRefName')
if [ -z "$branch_name" ]; then
echo "Error: Could not determine branch name for PR #$pr_number." >&2
exit 1
fi
# The directory name is derived from the branch name (e.g., spec/feature-name -> feature-name)
local dir_name=$(echo "$branch_name" | sed 's/spec\///')
local proposal_dir="docs/changes/$dir_name"
if [ ! -d "$proposal_dir" ]; then
echo "Error: Could not find proposal directory '$proposal_dir' associated with branch '$branch_name'." >&2
echo "Please ensure you have checked out the correct branch and the proposal exists." >&2
exit 1
fi
local proposal_file="$proposal_dir/proposal.md"
local spec_delta_file="$proposal_dir/spec-delta.md"
local tasks_file="$proposal_dir/tasks.yml"
# Fetch all comments
local all_comments=$(gh pr view "$pr_number" --comments)
local gemini_prompt="Here are three specification documents and a list of review comments from a Pull Request. Please analyze the feedback and suggest how to update the documents. For each document, provide a concise summary of the suggested changes.
**Original Proposal:**
@${proposal_file}
**Original Spec Delta:**
@${spec_delta_file}
**Original Tasks:**
@${tasks_file}
**Review Comments:**
${all_comments}
Based on the feedback, provide a summary of recommended changes for each file. Structure your output with headings for each file (e.g., '### Recommended Changes for proposal.md')."
echo "------------------------- GEMINI FEEDBACK ANALYSIS -------------------------"
gemini -p "$gemini_prompt"
echo "----------------------------------------------------------------------------"
echo "Use the analysis above to update the files in '$proposal_dir'."
}
# --- MAIN ---
COMMAND=$1
shift
case "$COMMAND" in
propose)
propose "$@"
;;
update)
update "$@"
;;
*)
echo "Error: Unknown command '$COMMAND'" >&2
echo "Usage: $0 {propose|update} ..." >&2
exit 1
;;
esac