Skip to content
Merged
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
12 changes: 12 additions & 0 deletions .cursor/rules/read-copilot-instructions.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
description: Read and follow .github/copilot-instructions.md for this repo
alwaysApply: true
---

Before assisting, open and read `.github/copilot-instructions.md`.
Follow it as the authoritative source for coding practices, docs style, security, and compliance for this project.

If the file is missing, say so, ask to create it, and proceed with safe defaults.
When “Copilot” is mentioned in that file, interpret it as referring to **you (Cursor)**.
Summarize the relevant sections into your working context before you act.

41 changes: 41 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "html2rss-web",
"image": "mcr.microsoft.com/devcontainers/ruby:3.4",
"features": {
"ghcr.io/devcontainers/features/git:1": {},
"ghcr.io/devcontainers/features/github-cli:1": {}
},
"customizations": {
"vscode": {
"extensions": [
"redhat.vscode-yaml",
"esbenp.prettier-vscode",
"github.copilot",
"github.copilot-chat",
"shopify.ruby-lsp"
],
"settings": {
"ruby.rubocop.executePath": "bundle exec",
"ruby.format": "rubocop",
"ruby.lint": {
"rubocop": true
},
"files.associations": {
"*.erb": "erb"
}
}
}
},
"postCreateCommand": "make setup",
"postStartCommand": "echo '🚀 html2rss-web Development Environment Ready!' && echo '' && echo '📋 Quick Start Commands:' && echo ' make dev # Start development server' && echo ' make test # Run tests' && echo ' make lint # Run linter' && echo ' make fix # Auto-fix linting issues' && echo ' make help # Show all commands' && echo '' && echo '🌐 Server will be available at: http://localhost:3000' && echo '📁 Project files are in: /workspaces/html2rss-web' && echo '' && echo '💡 Tip: Use Ctrl+C to stop the development server' && echo ''",
"forwardPorts": [
3000
],
"portsAttributes": {
"3000": {
"label": "html2rss-web",
"onAutoForward": "notify"
}
},
"remoteUser": "vscode"
}
48 changes: 48 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# html2rss-web AI Agent Instructions

## Overview

- Ruby web app that converts websites into RSS 2.0 feeds.
- Built with **Roda**, using the **html2rss** gem (+ `html2rss-configs`).
- **Principle:** _All features must work without JavaScript._ JS is only progressive enhancement.

## Core Rules

- ✅ Use **Roda routing with `hash_branch`**. Keep routes small.
- ✅ Put logic into `helpers/` or `app/`, not inline in routes.
- ✅ Validate all inputs. Pass outbound requests through **SSRF filter**.
- ✅ Add caching headers where appropriate (`Rack::Cache`).
- ✅ Errors: friendly messages for users, detailed logging internally.
- ✅ CSS: Water.css + small overrides in `public/styles.css`.
- ✅ Specs: RSpec, unit + integration, use VCR for external requests.

## Don’t

- ❌ Don’t depend on JS for core flows.
- ❌ Don’t bypass SSRF filter or weaken CSP.
- ❌ Don’t add databases, ORMs, or background jobs.
- ❌ Don’t leak stack traces or secrets in responses.

## Project Structure

- `app.rb` – main Roda app
- `app/` – core modules (config, cache, ssrf, health)
- `routes/` – route handlers (`hash_branch`)
- `helpers/` – pure helper modules (`module_function`)
- `views/` – ERB templates
- `public/` – static assets (CSS/JS, minimal)
- `config/feeds.yml` – feed definitions
- `spec/` – RSpec tests + VCR cassettes

## Environment

- `RACK_ENV` – environment
- `AUTO_SOURCE_ENABLED`, `AUTO_SOURCE_USERNAME`, `AUTO_SOURCE_PASSWORD`, `AUTO_SOURCE_ALLOWED_ORIGINS`
- `HEALTH_CHECK_USERNAME`, `HEALTH_CHECK_PASSWORD`
- `SENTRY_DSN` (optional)

## Style

- Add `# frozen_string_literal: true`
- Follow RuboCop style
- YARD doc comments for public methods
70 changes: 65 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,65 @@
tmp/*
!tmp/.keep
.yardoc
coverage
spec/examples.txt
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
# git config --global core.excludesfile '~/.gitignore_global'

# Ignore bundler config.
/.bundle

# Ignore the default SQLite database.
/db/*.sqlite3
/db/*.sqlite3-journal

# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep

# Ignore pidfiles, but keep the directory.
/tmp/pids/*
!/tmp/pids/
!/tmp/pids/.keep

# Ignore uploaded files in development.
/storage/*
!/storage/.keep

# Ignore master key for decrypting credentials and more.
/config/master.key

# Ignore environment variables
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# Ignore coverage reports
/coverage/

# Ignore VCR cassettes (they should be committed)
# /spec/fixtures/vcr_cassettes/

# Ignore IDE files
.vscode/
.idea/
*.swp
*.swo
*~

# Ignore OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Ignore rack cache
/tmp/rack-cache-*

# Ignore simplecov
/coverage/
39 changes: 39 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

.PHONY: help test lint fix setup dev clean

# Default target
help: ## Show this help message
@echo "html2rss-web Development Commands"
@echo "================================="
@echo ""
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}'

setup: ## Full development setup
@echo "Setting up development environment..."
bundle install
@if [ ! -f .env ]; then \
cp .env.example .env 2>/dev/null || echo "RACK_ENV=development" > .env; \
echo "Created .env file"; \
fi
@mkdir -p tmp/rack-cache-body tmp/rack-cache-meta
@echo "Setup complete!"

dev: ## Start development server
@echo "Starting development server..."
@echo "Server will be available at: http://localhost:3000"
@echo "Press Ctrl+C to stop"
@bin/dev

test: ## Run tests
bundle exec rspec

lint: ## Run linter
bundle exec rubocop

fix: ## Auto-fix linting issues
bundle exec rubocop -a

clean: ## Clean temporary files
@rm -rf tmp/rack-cache-* coverage/
@echo "Clean complete!"
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,45 @@ The functionality of scraping websites and building the RSS feeds is provided by

For full documentation, please see the [html2rss-web documentation](https://html2rss.github.io/web-application/).

## Development

### Quick Start with GitHub Codespaces

The easiest way to get started is using GitHub Codespaces:

1. Fork this repository
2. Click "Code" → "Codespaces" → "Create codespace on [your-username]/html2rss-web"
3. Wait for the codespace to build (it will automatically run `bundle install`)
4. The development server will be available at the forwarded port (usually 3000)

### Local Development

1. **Clone and setup:**
```bash
git clone https://github.com/html2rss/html2rss-web.git
cd html2rss-web
make setup
```

2. **Start development server:**
```bash
make dev
```

The application will be available at `http://localhost:3000`.

### Development Commands

| Command | Description |
| ------------ | --------------------------- |
| `make help` | Show all available commands |
| `make setup` | Full development setup |
| `make dev` | Start development server |
| `make test` | Run tests |
| `make lint` | Run linter |
| `make fix` | Auto-fix linting issues |
| `make clean` | Clean temporary files |

## Contributing

Contributions are welcome! Please see the [contributing guide](https://html2rss.github.io/get-involved/contributing) for more information.
Expand Down
20 changes: 20 additions & 0 deletions bin/dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# frozen_string_literal: true

# Development server startup script
set -e

# Load environment variables if .env file exists
if [ -f .env ]; then
export $(cat .env | grep -v '^#' | xargs)
fi

# Set default environment
export RACK_ENV=${RACK_ENV:-development}

echo "Starting html2rss-web in development mode..."
echo "Environment: $RACK_ENV"
echo "Port: ${PORT:-3000}"

# Start the development server
bundle exec rackup -p ${PORT:-3000} -o 0.0.0.0
36 changes: 36 additions & 0 deletions bin/setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
# frozen_string_literal: true

# Development environment setup script
set -e

echo "Setting up html2rss-web development environment..."

# Check if Ruby version is correct
ruby_version=$(ruby -v | cut -d' ' -f2 | cut -d'p' -f1)
echo "Ruby version: $ruby_version"

# Install dependencies
echo "Installing dependencies..."
bundle install

# Create .env file if it doesn't exist
if [ ! -f .env ]; then
echo "Creating .env file from .env.example..."
cp .env.example .env
echo "Please edit .env file with your configuration"
fi

# Create necessary directories
echo "Creating necessary directories..."
mkdir -p tmp/rack-cache-body
mkdir -p tmp/rack-cache-meta

# Run tests to verify setup
echo "Running tests to verify setup..."
bundle exec rspec

echo "Setup complete! You can now run:"
echo " bin/dev # Start development server"
echo " bundle exec rspec # Run tests"
echo " bundle exec rubocop # Run linter"