Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 49 additions & 46 deletions .github/workflows/gemini-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
steps:
- name: 'Mint identity token'
id: 'mint_identity_token'
if: |-
if: -|
${{ vars.APP_ID }}
uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b' # ratchet:actions/create-github-app-token@v2
with:
Expand All @@ -45,10 +45,10 @@ jobs:
env:
GITHUB_TOKEN: '${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}'
ISSUE_NUMBER: '${{ github.event.pull_request.number || github.event.issue.number }}'
MESSAGE: |-
MESSAGE: -|
🤖 Hi @${{ github.actor }}, I've received your request, and I'm working on it now! You can track my progress [in the logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for more details.
REPOSITORY: '${{ github.repository }}'
run: |-
run: -|
gh issue comment "${ISSUE_NUMBER}" \
--body "${MESSAGE}" \
--repo "${REPOSITORY}"
Expand All @@ -61,6 +61,7 @@ jobs:
id: 'gemini_pr_review'
env:
GITHUB_TOKEN: '${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}'
GITHUB_PERSONAL_ACCESS_TOKEN: '${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}'
ISSUE_TITLE: '${{ github.event.pull_request.title || github.event.issue.title }}'
ISSUE_BODY: '${{ github.event.pull_request.body || github.event.issue.body }}'
PULL_REQUEST_NUMBER: '${{ github.event.pull_request.number || github.event.issue.number }}'
Expand All @@ -79,54 +80,56 @@ jobs:
use_gemini_code_assist: '${{ vars.GOOGLE_GENAI_USE_GCA }}'
use_vertex_ai: '${{ vars.GOOGLE_GENAI_USE_VERTEXAI }}'
upload_artifacts: '${{ vars.UPLOAD_ARTIFACTS }}'
settings: |-
settings: -|
{
"model": {
"maxSessionTurns": 25
},
"telemetry": {
"enabled": true,
"target": "local",
"outfile": ".gemini/telemetry.log"
},
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server:v0.18.0"
],
"includeTools": [
"add_comment_to_pending_review",
"create_pending_pull_request_review",
"pull_request_read",
"submit_pending_pull_request_review"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
"model": {
"maxSessionTurns": 25
},
"telemetry": {
"enabled": true,
"target": "local",
"outfile": ".gemini/telemetry.log"
},
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server:v0.18.0"
],
"includeTools": [
"add_comment_to_pending_review",
"create_pending_pull_request_review",
"pull_request_read",
"submit_pending_pull_request_review"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}"
}
}
},
"tools": {
"core": [
"run_shell_command(cat)",
"run_shell_command(echo)",
"run_shell_command(grep)",
"run_shell_command(head)",
"run_shell_command(tail)"
]
}
}
},
"tools": {
"core": [
"run_shell_command(cat)",
"run_shell_command(echo)",
"run_shell_command(grep)",
"run_shell_command(head)",
"run_shell_command(tail)"
]
}
}
prompt: '/gemini-review'

- name: 'Run Gemini security analysis review'
uses: 'google-github-actions/run-gemini-cli@main' # ratchet:exclude
id: 'gemini_security_analysis'
env:
GITHUB_TOKEN: '${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}'
GITHUB_PERSONAL_ACCESS_TOKEN: '${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}'
ISSUE_TITLE: '${{ github.event.pull_request.title || github.event.issue.title }}'
ISSUE_BODY: '${{ github.event.pull_request.body || github.event.issue.body }}'
PULL_REQUEST_NUMBER: '${{ github.event.pull_request.number || github.event.issue.number }}'
Expand All @@ -145,11 +148,11 @@ jobs:
use_gemini_code_assist: '${{ vars.GOOGLE_GENAI_USE_GCA }}'
use_vertex_ai: '${{ vars.GOOGLE_GENAI_USE_VERTEXAI }}'
upload_artifacts: '${{ vars.UPLOAD_ARTIFACTS }}'
extensions: |
extensions: -|
[
"https://github.com/gemini-cli-extensions/security.git"
]
settings: |-
settings: -|
{
"model": {
"maxSessionTurns": 100
Expand Down Expand Up @@ -177,7 +180,7 @@ jobs:
"submit_pending_pull_request_review"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
"GITHUB_PERSONAL_ACCESS_TOKEN": "${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}"
}
}
},
Expand All @@ -191,4 +194,4 @@ jobs:
]
}
}
prompt: '/security:analyze-github-pr'
prompt: '/security:analyze-github-pr'
58 changes: 58 additions & 0 deletions IMPLEMENTATION_PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Implementation Plan - North Pole Wishlist

## Phase 0: Git Setup
- [x] Check if the current directory is an initialized git repository.
- [x] If it is, create and checkout a new feature branch named "north-pole-wishlist".

## Phase 1: Environment & Project Setup
- [x] Initialize the Python environment (virtualenv) and install Flask, Flask-SQLAlchemy, and Flask-Migrate.
- [x] Create `requirements.txt` with necessary dependencies.
- [x] Create the project structure (`app/`, `instance/`, `migrations/`).
- [x] Implement `config.py` with configuration classes (Development, Production) and environment variable handling.
- [x] Create the application factory in `app/__init__.py`.
- [x] Create a basic route in `app/routes.py` and a base template to verify the server runs.

## Phase 2: Database Models & Migration
- [x] Configure `Flask-SQLAlchemy` in `app/__init__.py`.
- [x] Create `app/models.py` and define the `GiftIdea` model using SQLAlchemy 2.0 style.
- [x] Define the `Vote` model in `app/models.py`.
- [x] Define the `Comment` model in `app/models.py`.
- [x] Initialize database migrations (`flask db init`, `flask db migrate`, `flask db upgrade`) to create the SQLite database.
- [x] Create a seed script (`seed.py`) to populate the database with initial sample data for testing.

## Phase 3: Core Backend Logic (Gift Management)
- [x] Implement the `POST /gift/new` route in `app/routes.py` for gift submission.
- [x] Create the form template `app/templates/create_gift.html`.
- [x] Implement input validation for gift submission (title length, category validation).
- [x] Implement the `GET /` route (Landing Page) to fetch and display gifts.
- [x] Implement sorting logic (Popular, Top Rated, New) and category filtering in the `GET /` route.

## Phase 4: Frontend Implementation (Bootstrap 5 & Theming)
- [x] Setup `base.html` with Bootstrap 5 CDN and custom CSS file structure (`app/static/css/style.css`).
- [x] Implement the custom color palette (Santa Red, Forest Green, Snow White) in `style.css`.
- [x] Import and apply Google Fonts (*Mountains of Christmas*, *Lato/Roboto*).
- [x] Create or source the Hero Image (Santa's Sleigh) and add it to the Landing Page.
- [x] Style the Gift Cards to display title, description, category, and score.
- [x] Add festive icons (snowflakes/stars) for the rating display.

## Phase 5: Engagement Features (Voting & Comments)
- [x] Implement the `POST /gift/<id>/vote` API endpoint to handle JSON payloads.
- [x] Add JavaScript to the frontend to handle AJAX voting requests and update the UI dynamically.
- [x] Implement the `POST /gift/<id>/comment` route to handle comment submission.
- [x] Create the comment section in the gift detail view (or modal).
- [x] Validate comment content (length check) and default author name logic.
- [x] Ensure comments are displayed in chronological order.

## Phase 6: Final Polish & Cleanup
- [x] Review all pages for responsiveness on mobile devices.
- [x] Verify validation error messages are displayed correctly to the user (Flash messages).
- [x] Optimize database queries (e.g., eager loading relationships if needed).
- [x] Run a final manual test of the entire user flow: Submit Gift -> Vote -> Comment -> Filter/Sort.

## Phase 7: Completion & Version Control
- [ ] Verify application functionality.
- [ ] Create a `README.md` file explaining the application functions, how to interact with them, the architecture, file breakdown and how to run and test it locally.
- [ ] Add all changes to the repository (`git add .`).
- [ ] Commit the changes (`git commit -m "Complete implementation of North Pole Wishlist"`).
- [ ] Push the feature branch to the remote repository, creating a branch with the same name in the remote repository, using the Gemini CLI github MCP server.
- [ ] Open a pull request for the feature branch using the Gemini CLI github MCP server, leave it open for review, don't merge it.
146 changes: 52 additions & 94 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,94 +1,52 @@
# Spec-Driven Development w Gemini CLI

This repo has some basic assets to experiment **Spec-Driven Development** using the Gemini CLI. You will act as a developer going from a raw Functional Specification to a deployed Pull Request in a single session.

## Assets

* `.gemini/commands/`: Contains configuration files for custom commands (`techspec`, `plan`, `build`).
* `GEMINI.md`: Contains project rules and guidelines.
* `.github/workflows`: Contains CI workflow.
* **No application code**.

## Requirements

The `GEMINI.md` configuration and custom commands require the following extensions:
* **Google Workspace**
* **Nano Banana**
* **GitHub**

---

## Step 1: The Architect Phase (/techspec)

**Goal:** Transform a Functional Spec (Google Doc) into a Technical Spec (Google Doc).

1. **Command:**
```
/techspec "Name of your functional specs doc" "Your desired technology stack and requirements"
```

2. **What Happens:**
* The agent searches your Drive for the doc.
* It reads the requirements.
* It generates a **Technical Specification** including Data Models, API Routes, and Architecture based on your inputs.
* **Output:** It creates a *new* Google Doc titled "Technical Specification - Application name" and gives you the link.

---

## Step 2: The Planning Phase (/plan)

**Goal:** Break the Technical Spec down into an atomic Implementation Plan.

1. **Command:**
```
/plan "Name of your Tech spec doc"
```
*(Use the exact name of the doc generated in Step 1)*

2. **What Happens:**
* The agent reads the Tech Spec.
* It creates a local file `IMPLEMENTATION_PLAN.md`.
* It breaks the project into phases (e.g., Setup, Backend, Frontend, Polish).
* It defines the Git strategy.

---

## Step 3: The Build Phase (/build)

**Goal:** Execute the plan and write the code.

1. **Command:**
```
/build IMPLEMENTATION_PLAN.md "Name of your Tech spec doc"
```

2. **What Happens (Iterative):**
* **Execution:** The agent iterates through the plan, initializing the project structure and writing the application code.
* **Visuals:** It generates necessary visual assets (images, icons) as defined in the spec.
* **Progress:** It updates `IMPLEMENTATION_PLAN.md` as tasks are completed.

---

## Step 4: Final Delivery

**Goal:** Push the code and open a Pull Request.

1. **Action:**
The `/build` command's final phase usually covers this, or you can manually instruct the agent to finalize the project.

2. **What Happens:**
* The agent runs final checks (linting/formatting).
* It creates a `README.md` for the new application.
* It commits all changes.
* It pushes the feature branch to GitHub.
* It uses the GitHub extension to **Open a Pull Request**.

---

## Summary of Commands

| Step | Command | Input | Output |
| :--- | :--- | :--- | :--- |
| **1. Spec** | `/techspec` | Functional Doc (Drive) | Tech Spec (Drive) |
| **2. Plan** | `/plan` | Tech Spec (Drive) | `IMPLEMENTATION_PLAN.md` |
| **3. Build** | `/build` | Plan + Tech Spec | Code, Assets, App |
# North Pole Wishlist

A community-driven platform to discover, share, and curate the best holiday gift ideas.

## Features

- **Gift Ideas**: Submit and browse gift suggestions with categories.
- **Voting**: Rate gifts on a 5-snowflake scale ("Naughty or Nice").
- **Comments**: Discuss gift ideas with the community.
- **Sorting & Filtering**: Find the best gifts by Popularity, Rating, or Category.
- **Festive Theme**: A fully immersive Christmas design.

## Architecture

- **Backend**: Python Flask
- **Database**: SQLite with SQLAlchemy 2.0 (ORM)
- **Frontend**: Bootstrap 5 + Jinja2 Templates
- **Theme**: Custom CSS with Google Fonts (*Mountains of Christmas*)

## Setup & Run

1. **Clone the repository**
2. **Create a virtual environment**:
```bash
python3 -m venv venv
source venv/bin/activate
```
3. **Install dependencies**:
```bash
pip install -r requirements.txt
```
4. **Initialize the database**:
```bash
flask db upgrade
python seed.py # Optional: Seed with sample data
```
5. **Run the application**:
```bash
python run.py
```
6. Open `http://127.0.0.1:5000` in your browser.

## File Structure

- `app/`: Application source code.
- `models.py`: Database models.
- `routes.py`: API and view routes.
- `templates/`: HTML templates.
- `static/`: CSS and Images.
- `migrations/`: Database migration scripts.
- `config.py`: Configuration settings.
- `run.py`: Entry point.
Binary file added __pycache__/config.cpython-313.pyc
Binary file not shown.
Binary file added __pycache__/run.cpython-313.pyc
Binary file not shown.
16 changes: 16 additions & 0 deletions app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from flask import Flask
from config import DevelopmentConfig
from app.extensions import db, migrate

def create_app(config_class=DevelopmentConfig):
app = Flask(__name__)
app.config.from_object(config_class)

db.init_app(app)
migrate.init_app(app, db)

from app import models # Import models here to register them
from app import routes
app.register_blueprint(routes.bp)

return app
Binary file added app/__pycache__/__init__.cpython-313.pyc
Binary file not shown.
Binary file added app/__pycache__/extensions.cpython-313.pyc
Binary file not shown.
Binary file added app/__pycache__/models.cpython-313.pyc
Binary file not shown.
Binary file added app/__pycache__/routes.cpython-313.pyc
Binary file not shown.
9 changes: 9 additions & 0 deletions app/extensions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from sqlalchemy.orm import DeclarativeBase

class Base(DeclarativeBase):
pass

db = SQLAlchemy(model_class=Base)
migrate = Migrate()
Loading