{"owner":"PBH-BTN","repo":"PeerBanHelper","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":[".github/copilot-instructions.md",".github/skills/openspec-archive-change/SKILL.md"],"skills":{".github/copilot-instructions.md":"# PeerBanHelper Development Instructions\n\nAlways reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.\n\nPeerBanHelper is a Java-based BitTorrent client protection application with a Vue.js web interface. It automatically bans unwelcome, leeching, and abnormal BT clients with support for custom rules and GeoIP-based blocking.\n\n## Prerequisites and Setup\n\nInstall required dependencies in this exact order:\n\n1. **Install Java 21 using SDKMAN**:\n   ```bash\n   curl -s \"https://get.sdkman.io\" | bash\n   source \"/home/runner/.sdkman/bin/sdkman-init.sh\"\n   sdk install java 21.0.4-tem\n   ```\n   - Java 21 is REQUIRED. The application is compiled on Java 21 and designed to run on Java 23.\n   - Do NOT use Java 17 or other versions - the build will fail or have runtime issues.\n\n2. **Install pnpm globally**:\n   ```bash\n   npm install -g pnpm\n   ```\n   - pnpm >=9.0.0 is required for the WebUI build (specified in package.json engines).\n   - Node.js >=20.0.0 is required.\n\n## Building the Application\n\nALWAYS source the SDKMAN environment before any build commands:\n```bash\nsource \"/home/runner/.sdkman/bin/sdkman-init.sh\"\n```\n\n### Complete Build Process (Recommended)\n\nUse the provided build script for the complete build:\n```bash\n./build.sh\n```\n- **NEVER CANCEL**: Build takes 45-60 seconds. NEVER CANCEL. Set timeout to 120+ seconds.\n- This script handles both WebUI and Maven builds automatically.\n- Creates a complete executable JAR with all dependencies.\n\n### Manual Build Steps (if needed)\n\nIf you need to build components separately:\n\n1. **WebUI Build** (must be done first):\n   ```bash\n   cd webui\n   pnpm install  # Takes ~5 seconds\n   pnpm run build  # Takes ~35 seconds. NEVER CANCEL. Set timeout to 120+ seconds.\n   cd ..\n   cp -r webui/dist src/main/resources/static\n   ```\n\n2. **Maven Build** (after WebUI is built):\n   ```bash\n   mvn -B clean package --file pom.xml\n   ```\n   - **NEVER CANCEL**: Build takes 2-3 minutes. NEVER CANCEL. Set timeout to 300+ seconds.\n   - Downloads many dependencies on first run.\n   - Creates `target/PeerBanHelper.jar` and `target/libraries/` directory.\n\n## Testing and Validation\n\n### No Unit Tests Available\n- `mvn test` reports \"No tests to run\" - this project does not have unit tests.\n- `pnpm run test` is not available in the WebUI.\n\n### Linting\nRun WebUI linting to validate code quality:\n```bash\ncd webui\npnpm run lint  # Takes ~10 seconds\n```\n- ALWAYS run linting before committing changes.\n- Fix any errors reported by prettier and eslint.\n\n### Manual Validation Scenarios\n\nALWAYS validate the application manually after making changes:\n\n1. **Start the Application**:\n   ```bash\n   source \"/home/runner/.sdkman/bin/sdkman-init.sh\"\n   java -Dpbh.nogui=true -jar target/PeerBanHelper.jar\n   ```\n   - Application starts on port 9898 by default.\n   - Takes ~6-10 seconds to start up completely.\n   - Downloads GeoIP databases on first run (this is normal).\n\n2. **Test Web Interface**:\n   ```bash\n   curl -I http://localhost:9898/\n   # Should return HTTP/1.1 200 OK\n   ```\n\n3. **Test API Endpoint**:\n   ```bash\n   curl -s http://localhost:9898/api/general/status\n   # Should return JSON with initialization message for fresh installs\n   ```\n\n4. **Complete User Scenario**:\n   - Navigate to `http://localhost:9898` in a browser.\n   - Complete the OOBE (Out of Box Experience) initialization wizard.\n   - Add a BitTorrent client configuration.\n   - Verify the dashboard loads and shows statistics.\n\n## Docker Build and Testing\n\n### Docker Build\n```bash\ndocker build -f Dockerfile . --tag peerbanhelper-test\n```\n- **NEVER CANCEL**: Build takes 3-4 minutes. NEVER CANCEL. Set timeout to 600+ seconds.\n- Uses multi-stage build: WebUI build, Maven build, then runtime container.\n\n### Docker Testing\n```bash\ndocker run --rm -p 9899:9898 peerbanhelper-test\n# Test with: curl -I http://localhost:9899/\n```\n\n## Key Project Structure\n\n### Backend (Java/Maven)\n- **Main class**: `com.ghostchu.peerbanhelper.MainJumpLoader`\n- **Source**: `src/main/java/` (444 Java source files)\n- **Resources**: `src/main/resources/` (contains config, translations, static files)\n- **Build output**: `target/PeerBanHelper.jar` + `target/libraries/`\n- **No test source directory** - this project has no unit tests\n\n### Frontend (Vue.js/TypeScript)\n- **Source**: `webui/src/`\n- **Package manager**: pnpm (required, npm is not supported)\n- **Build tool**: Vite\n- **Output**: `webui/dist/` → copied to `src/main/resources/static/`\n\n### Configuration Files\n- **Maven**: `pom.xml` (Java 21, 444 source files, extensive dependencies)\n- **WebUI**: `webui/package.json` (Vue 3, TypeScript, ArcoDesign UI library)\n- **Docker**: `Dockerfile` (multi-stage with Node.js and Maven)\n- **Build script**: `build.sh` (automates WebUI + Maven build)\n\n## Common Issues and Solutions\n\n### Build Failures\n- **Missing Java 21**: Ensure you've sourced SDKMAN and installed Java 21.0.4-tem\n- **pnpm not found**: Install pnpm globally with `npm install -g pnpm`\n- **WebUI build before Maven**: Always build WebUI first, Maven depends on the static files\n\n### Runtime Issues\n- **Port conflicts**: Default port 9898, use `-Dpbh.port=8080` to change\n- **GeoIP download failures**: Normal on first run, requires internet connection\n- **Initialization required**: Fresh installs need OOBE setup via WebUI\n\n## Development Workflow\n\n1. **Make Code Changes**: Edit Java/TypeScript source files\n2. **Build**: Run `./build.sh` to build everything\n3. **Lint**: Run `cd webui && pnpm run lint` for frontend changes\n4. **Test**: Start application and validate functionality manually\n5. **Validate**: Test both direct JAR and Docker container deployment\n\n## Command Reference\n\n### Essential Commands (with timeouts)\n```bash\n# Complete build (timeout: 120s)\n./build.sh\n\n# WebUI only (timeout: 120s)\ncd webui && pnpm install && pnpm run build\n\n# Maven only (timeout: 300s)\nsource \"/home/runner/.sdkman/bin/sdkman-init.sh\" && mvn -B clean package --file pom.xml\n\n# Docker build (timeout: 600s)\ndocker build -f Dockerfile . --tag peerbanhelper-test\n\n# Start application for testing\nsource \"/home/runner/.sdkman/bin/sdkman-init.sh\" && java -Dpbh.nogui=true -jar target/PeerBanHelper.jar\n```\n\n### Validation Commands\n```bash\n# Lint WebUI\ncd webui && pnpm run lint\n\n# Test web interface\ncurl -I http://localhost:9898/\n\n# Test API\ncurl -s http://localhost:9898/api/general/status\n```\n\n## Critical Reminders\n\n- **ALWAYS** source SDKMAN before Java/Maven commands: `source \"/home/runner/.sdkman/bin/sdkman-init.sh\"`\n- **NEVER CANCEL** long-running builds - they are expected to take several minutes\n- **ALWAYS** build WebUI before Maven when building manually\n- **ALWAYS** run linting before committing frontend changes\n- **ALWAYS** manually validate application functionality after changes\n- **Set appropriate timeouts** (120s+ for builds, 300s+ for Maven, 600s+ for Docker)",".github/skills/openspec-archive-change/SKILL.md":"---\nname: openspec-archive-change\ndescription: Archive a completed change in the experimental workflow. Use when the user wants to finalize and archive a change after implementation is complete.\nlicense: MIT\ncompatibility: Requires openspec CLI.\nmetadata:\n  author: openspec\n  version: \"1.0\"\n  generatedBy: \"1.0.0\"\n---\n\nArchive a completed change in the experimental workflow.\n\n**Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague\nor ambiguous you MUST prompt for available changes.\n\n**Steps**\n\n1. **If no change name provided, prompt for selection**\n\n   Run `openspec list --json` to get available changes. Use the **AskUserQuestion tool** to let the user select.\n\n   Show only active changes (not already archived).\n   Include the schema used for each change if available.\n\n   **IMPORTANT**: Do NOT guess or auto-select a change. Always let the user choose.\n\n2. **Check artifact completion status**\n\n   Run `openspec status --change \"<name>\" --json` to check artifact completion.\n\n   Parse the JSON to understand:\n    - `schemaName`: The workflow being used\n    - `artifacts`: List of artifacts with their status (`done` or other)\n\n   **If any artifacts are not `done`:**\n    - Display warning listing incomplete artifacts\n    - Use **AskUserQuestion tool** to confirm user wants to proceed\n    - Proceed if user confirms\n\n3. **Check task completion status**\n\n   Read the tasks file (typically `tasks.md`) to check for incomplete tasks.\n\n   Count tasks marked with `- [ ]` (incomplete) vs `- [x]` (complete).\n\n   **If incomplete tasks found:**\n    - Display warning showing count of incomplete tasks\n    - Use **AskUserQuestion tool** to confirm user wants to proceed\n    - Proceed if user confirms\n\n   **If no tasks file exists:** Proceed without task-related warning.\n\n4. **Assess delta spec sync state**\n\n   Check for delta specs at `openspec/changes/<name>/specs/`. If none exist, proceed without sync prompt.\n\n   **If delta specs exist:**\n    - Compare each delta spec with its corresponding main spec at `openspec/specs/<capability>/spec.md`\n    - Determine what changes would be applied (adds, modifications, removals, renames)\n    - Show a combined summary before prompting\n\n   **Prompt options:**\n    - If changes needed: \"Sync now (recommended)\", \"Archive without syncing\"\n    - If already synced: \"Archive now\", \"Sync anyway\", \"Cancel\"\n\n   If user chooses sync, execute /opsx:sync logic (use the openspec-sync-specs skill). Proceed to archive regardless of\n   choice.\n\n5. **Perform the archive**\n\n   Create the archive directory if it doesn't exist:\n   ```bash\n   mkdir -p openspec/changes/archive\n   ```\n\n   Generate target name using current date: `YYYY-MM-DD-<change-name>`\n\n   **Check if target already exists:**\n    - If yes: Fail with error, suggest renaming existing archive or using different date\n    - If no: Move the change directory to archive\n\n   ```bash\n   mv openspec/changes/<name> openspec/changes/archive/YYYY-MM-DD-<name>\n   ```\n\n6. **Display summary**\n\n   Show archive completion summary including:\n    - Change name\n    - Schema that was used\n    - Archive location\n    - Whether specs were synced (if applicable)\n    - Note about any warnings (incomplete artifacts/tasks)\n\n**Output On Success**\n\n```\n## Archive Complete\n\n**Change:** <change-name>\n**Schema:** <schema-name>\n**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/\n**Specs:** ✓ Synced to main specs (or \"No delta specs\" or \"Sync skipped\")\n\nAll artifacts complete. All tasks complete.\n```\n\n**Guardrails**\n\n- Always prompt for change selection if not provided\n- Use artifact graph (openspec status --json) for completion checking\n- Don't block archive on warnings - just inform and confirm\n- Preserve .openspec.yaml when moving to archive (it moves with the directory)\n- Show clear summary of what happened\n- If sync is requested, use openspec-sync-specs approach (agent-driven)\n- If delta specs exist, always run the sync assessment and show the combined summary before prompting\n"},"files":{".github/copilot-instructions.md":"# PeerBanHelper Development Instructions\n\nAlways reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.\n\nPeerBanHelper is a Java-based BitTorrent client protection application with a Vue.js web interface. It automatically bans unwelcome, leeching, and abnormal BT clients with support for custom rules and GeoIP-based blocking.\n\n## Prerequisites and Setup\n\nInstall required dependencies in this exact order:\n\n1. **Install Java 21 using SDKMAN**:\n   ```bash\n   curl -s \"https://get.sdkman.io\" | bash\n   source \"/home/runner/.sdkman/bin/sdkman-init.sh\"\n   sdk install java 21.0.4-tem\n   ```\n   - Java 21 is REQUIRED. The application is compiled on Java 21 and designed to run on Java 23.\n   - Do NOT use Java 17 or other versions - the build will fail or have runtime issues.\n\n2. **Install pnpm globally**:\n   ```bash\n   npm install -g pnpm\n   ```\n   - pnpm >=9.0.0 is required for the WebUI build (specified in package.json engines).\n   - Node.js >=20.0.0 is required.\n\n## Building the Application\n\nALWAYS source the SDKMAN environment before any build commands:\n```bash\nsource \"/home/runner/.sdkman/bin/sdkman-init.sh\"\n```\n\n### Complete Build Process (Recommended)\n\nUse the provided build script for the complete build:\n```bash\n./build.sh\n```\n- **NEVER CANCEL**: Build takes 45-60 seconds. NEVER CANCEL. Set timeout to 120+ seconds.\n- This script handles both WebUI and Maven builds automatically.\n- Creates a complete executable JAR with all dependencies.\n\n### Manual Build Steps (if needed)\n\nIf you need to build components separately:\n\n1. **WebUI Build** (must be done first):\n   ```bash\n   cd webui\n   pnpm install  # Takes ~5 seconds\n   pnpm run build  # Takes ~35 seconds. NEVER CANCEL. Set timeout to 120+ seconds.\n   cd ..\n   cp -r webui/dist src/main/resources/static\n   ```\n\n2. **Maven Build** (after WebUI is built):\n   ```bash\n   mvn -B clean package --file pom.xml\n   ```\n   - **NEVER CANCEL**: Build takes 2-3 minutes. NEVER CANCEL. Set timeout to 300+ seconds.\n   - Downloads many dependencies on first run.\n   - Creates `target/PeerBanHelper.jar` and `target/libraries/` directory.\n\n## Testing and Validation\n\n### No Unit Tests Available\n- `mvn test` reports \"No tests to run\" - this project does not have unit tests.\n- `pnpm run test` is not available in the WebUI.\n\n### Linting\nRun WebUI linting to validate code quality:\n```bash\ncd webui\npnpm run lint  # Takes ~10 seconds\n```\n- ALWAYS run linting before committing changes.\n- Fix any errors reported by prettier and eslint.\n\n### Manual Validation Scenarios\n\nALWAYS validate the application manually after making changes:\n\n1. **Start the Application**:\n   ```bash\n   source \"/home/runner/.sdkman/bin/sdkman-init.sh\"\n   java -Dpbh.nogui=true -jar target/PeerBanHelper.jar\n   ```\n   - Application starts on port 9898 by default.\n   - Takes ~6-10 seconds to start up completely.\n   - Downloads GeoIP databases on first run (this is normal).\n\n2. **Test Web Interface**:\n   ```bash\n   curl -I http://localhost:9898/\n   # Should return HTTP/1.1 200 OK\n   ```\n\n3. **Test API Endpoint**:\n   ```bash\n   curl -s http://localhost:9898/api/general/status\n   # Should return JSON with initialization message for fresh installs\n   ```\n\n4. **Complete User Scenario**:\n   - Navigate to `http://localhost:9898` in a browser.\n   - Complete the OOBE (Out of Box Experience) initialization wizard.\n   - Add a BitTorrent client configuration.\n   - Verify the dashboard loads and shows statistics.\n\n## Docker Build and Testing\n\n### Docker Build\n```bash\ndocker build -f Dockerfile . --tag peerbanhelper-test\n```\n- **NEVER CANCEL**: Build takes 3-4 minutes. NEVER CANCEL. Set timeout to 600+ seconds.\n- Uses multi-stage build: WebUI build, Maven build, then runtime container.\n\n### Docker Testing\n```bash\ndocker run --rm -p 9899:9898 peerbanhelper-test\n# Test with: curl -I http://localhost:9899/\n```\n\n## Key Project Structure\n\n### Backend (Java/Maven)\n- **Main class**: `com.ghostchu.peerbanhelper.MainJumpLoader`\n- **Source**: `src/main/java/` (444 Java source files)\n- **Resources**: `src/main/resources/` (contains config, translations, static files)\n- **Build output**: `target/PeerBanHelper.jar` + `target/libraries/`\n- **No test source directory** - this project has no unit tests\n\n### Frontend (Vue.js/TypeScript)\n- **Source**: `webui/src/`\n- **Package manager**: pnpm (required, npm is not supported)\n- **Build tool**: Vite\n- **Output**: `webui/dist/` → copied to `src/main/resources/static/`\n\n### Configuration Files\n- **Maven**: `pom.xml` (Java 21, 444 source files, extensive dependencies)\n- **WebUI**: `webui/package.json` (Vue 3, TypeScript, ArcoDesign UI library)\n- **Docker**: `Dockerfile` (multi-stage with Node.js and Maven)\n- **Build script**: `build.sh` (automates WebUI + Maven build)\n\n## Common Issues and Solutions\n\n### Build Failures\n- **Missing Java 21**: Ensure you've sourced SDKMAN and installed Java 21.0.4-tem\n- **pnpm not found**: Install pnpm globally with `npm install -g pnpm`\n- **WebUI build before Maven**: Always build WebUI first, Maven depends on the static files\n\n### Runtime Issues\n- **Port conflicts**: Default port 9898, use `-Dpbh.port=8080` to change\n- **GeoIP download failures**: Normal on first run, requires internet connection\n- **Initialization required**: Fresh installs need OOBE setup via WebUI\n\n## Development Workflow\n\n1. **Make Code Changes**: Edit Java/TypeScript source files\n2. **Build**: Run `./build.sh` to build everything\n3. **Lint**: Run `cd webui && pnpm run lint` for frontend changes\n4. **Test**: Start application and validate functionality manually\n5. **Validate**: Test both direct JAR and Docker container deployment\n\n## Command Reference\n\n### Essential Commands (with timeouts)\n```bash\n# Complete build (timeout: 120s)\n./build.sh\n\n# WebUI only (timeout: 120s)\ncd webui && pnpm install && pnpm run build\n\n# Maven only (timeout: 300s)\nsource \"/home/runner/.sdkman/bin/sdkman-init.sh\" && mvn -B clean package --file pom.xml\n\n# Docker build (timeout: 600s)\ndocker build -f Dockerfile . --tag peerbanhelper-test\n\n# Start application for testing\nsource \"/home/runner/.sdkman/bin/sdkman-init.sh\" && java -Dpbh.nogui=true -jar target/PeerBanHelper.jar\n```\n\n### Validation Commands\n```bash\n# Lint WebUI\ncd webui && pnpm run lint\n\n# Test web interface\ncurl -I http://localhost:9898/\n\n# Test API\ncurl -s http://localhost:9898/api/general/status\n```\n\n## Critical Reminders\n\n- **ALWAYS** source SDKMAN before Java/Maven commands: `source \"/home/runner/.sdkman/bin/sdkman-init.sh\"`\n- **NEVER CANCEL** long-running builds - they are expected to take several minutes\n- **ALWAYS** build WebUI before Maven when building manually\n- **ALWAYS** run linting before committing frontend changes\n- **ALWAYS** manually validate application functionality after changes\n- **Set appropriate timeouts** (120s+ for builds, 300s+ for Maven, 600s+ for Docker)",".github/skills/openspec-archive-change/SKILL.md":"---\nname: openspec-archive-change\ndescription: Archive a completed change in the experimental workflow. Use when the user wants to finalize and archive a change after implementation is complete.\nlicense: MIT\ncompatibility: Requires openspec CLI.\nmetadata:\n  author: openspec\n  version: \"1.0\"\n  generatedBy: \"1.0.0\"\n---\n\nArchive a completed change in the experimental workflow.\n\n**Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague\nor ambiguous you MUST prompt for available changes.\n\n**Steps**\n\n1. **If no change name provided, prompt for selection**\n\n   Run `openspec list --json` to get available changes. Use the **AskUserQuestion tool** to let the user select.\n\n   Show only active changes (not already archived).\n   Include the schema used for each change if available.\n\n   **IMPORTANT**: Do NOT guess or auto-select a change. Always let the user choose.\n\n2. **Check artifact completion status**\n\n   Run `openspec status --change \"<name>\" --json` to check artifact completion.\n\n   Parse the JSON to understand:\n    - `schemaName`: The workflow being used\n    - `artifacts`: List of artifacts with their status (`done` or other)\n\n   **If any artifacts are not `done`:**\n    - Display warning listing incomplete artifacts\n    - Use **AskUserQuestion tool** to confirm user wants to proceed\n    - Proceed if user confirms\n\n3. **Check task completion status**\n\n   Read the tasks file (typically `tasks.md`) to check for incomplete tasks.\n\n   Count tasks marked with `- [ ]` (incomplete) vs `- [x]` (complete).\n\n   **If incomplete tasks found:**\n    - Display warning showing count of incomplete tasks\n    - Use **AskUserQuestion tool** to confirm user wants to proceed\n    - Proceed if user confirms\n\n   **If no tasks file exists:** Proceed without task-related warning.\n\n4. **Assess delta spec sync state**\n\n   Check for delta specs at `openspec/changes/<name>/specs/`. If none exist, proceed without sync prompt.\n\n   **If delta specs exist:**\n    - Compare each delta spec with its corresponding main spec at `openspec/specs/<capability>/spec.md`\n    - Determine what changes would be applied (adds, modifications, removals, renames)\n    - Show a combined summary before prompting\n\n   **Prompt options:**\n    - If changes needed: \"Sync now (recommended)\", \"Archive without syncing\"\n    - If already synced: \"Archive now\", \"Sync anyway\", \"Cancel\"\n\n   If user chooses sync, execute /opsx:sync logic (use the openspec-sync-specs skill). Proceed to archive regardless of\n   choice.\n\n5. **Perform the archive**\n\n   Create the archive directory if it doesn't exist:\n   ```bash\n   mkdir -p openspec/changes/archive\n   ```\n\n   Generate target name using current date: `YYYY-MM-DD-<change-name>`\n\n   **Check if target already exists:**\n    - If yes: Fail with error, suggest renaming existing archive or using different date\n    - If no: Move the change directory to archive\n\n   ```bash\n   mv openspec/changes/<name> openspec/changes/archive/YYYY-MM-DD-<name>\n   ```\n\n6. **Display summary**\n\n   Show archive completion summary including:\n    - Change name\n    - Schema that was used\n    - Archive location\n    - Whether specs were synced (if applicable)\n    - Note about any warnings (incomplete artifacts/tasks)\n\n**Output On Success**\n\n```\n## Archive Complete\n\n**Change:** <change-name>\n**Schema:** <schema-name>\n**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/\n**Specs:** ✓ Synced to main specs (or \"No delta specs\" or \"Sync skipped\")\n\nAll artifacts complete. All tasks complete.\n```\n\n**Guardrails**\n\n- Always prompt for change selection if not provided\n- Use artifact graph (openspec status --json) for completion checking\n- Don't block archive on warnings - just inform and confirm\n- Preserve .openspec.yaml when moving to archive (it moves with the directory)\n- Show clear summary of what happened\n- If sync is requested, use openspec-sync-specs approach (agent-driven)\n- If delta specs exist, always run the sync assessment and show the combined summary before prompting\n"},"items":[{"name":"copilot-instructions.md","path":".github/copilot-instructions.md","title":"copilot-instructions.md","content":"# PeerBanHelper Development Instructions\n\nAlways reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.\n\nPeerBanHelper is a Java-based BitTorrent client protection application with a Vue.js web interface. It automatically bans unwelcome, leeching, and abnormal BT clients with support for custom rules and GeoIP-based blocking.\n\n## Prerequisites and Setup\n\nInstall required dependencies in this exact order:\n\n1. **Install Java 21 using SDKMAN**:\n   ```bash\n   curl -s \"https://get.sdkman.io\" | bash\n   source \"/home/runner/.sdkman/bin/sdkman-init.sh\"\n   sdk install java 21.0.4-tem\n   ```\n   - Java 21 is REQUIRED. The application is compiled on Java 21 and designed to run on Java 23.\n   - Do NOT use Java 17 or other versions - the build will fail or have runtime issues.\n\n2. **Install pnpm globally**:\n   ```bash\n   npm install -g pnpm\n   ```\n   - pnpm >=9.0.0 is required for the WebUI build (specified in package.json engines).\n   - Node.js >=20.0.0 is required.\n\n## Building the Application\n\nALWAYS source the SDKMAN environment before any build commands:\n```bash\nsource \"/home/runner/.sdkman/bin/sdkman-init.sh\"\n```\n\n### Complete Build Process (Recommended)\n\nUse the provided build script for the complete build:\n```bash\n./build.sh\n```\n- **NEVER CANCEL**: Build takes 45-60 seconds. NEVER CANCEL. Set timeout to 120+ seconds.\n- This script handles both WebUI and Maven builds automatically.\n- Creates a complete executable JAR with all dependencies.\n\n### Manual Build Steps (if needed)\n\nIf you need to build components separately:\n\n1. **WebUI Build** (must be done first):\n   ```bash\n   cd webui\n   pnpm install  # Takes ~5 seconds\n   pnpm run build  # Takes ~35 seconds. NEVER CANCEL. Set timeout to 120+ seconds.\n   cd ..\n   cp -r webui/dist src/main/resources/static\n   ```\n\n2. **Maven Build** (after WebUI is built):\n   ```bash\n   mvn -B clean package --file pom.xml\n   ```\n   - **NEVER CANCEL**: Build takes 2-3 minutes. NEVER CANCEL. Set timeout to 300+ seconds.\n   - Downloads many dependencies on first run.\n   - Creates `target/PeerBanHelper.jar` and `target/libraries/` directory.\n\n## Testing and Validation\n\n### No Unit Tests Available\n- `mvn test` reports \"No tests to run\" - this project does not have unit tests.\n- `pnpm run test` is not available in the WebUI.\n\n### Linting\nRun WebUI linting to validate code quality:\n```bash\ncd webui\npnpm run lint  # Takes ~10 seconds\n```\n- ALWAYS run linting before committing changes.\n- Fix any errors reported by prettier and eslint.\n\n### Manual Validation Scenarios\n\nALWAYS validate the application manually after making changes:\n\n1. **Start the Application**:\n   ```bash\n   source \"/home/runner/.sdkman/bin/sdkman-init.sh\"\n   java -Dpbh.nogui=true -jar target/PeerBanHelper.jar\n   ```\n   - Application starts on port 9898 by default.\n   - Takes ~6-10 seconds to start up completely.\n   - Downloads GeoIP databases on first run (this is normal).\n\n2. **Test Web Interface**:\n   ```bash\n   curl -I http://localhost:9898/\n   # Should return HTTP/1.1 200 OK\n   ```\n\n3. **Test API Endpoint**:\n   ```bash\n   curl -s http://localhost:9898/api/general/status\n   # Should return JSON with initialization message for fresh installs\n   ```\n\n4. **Complete User Scenario**:\n   - Navigate to `http://localhost:9898` in a browser.\n   - Complete the OOBE (Out of Box Experience) initialization wizard.\n   - Add a BitTorrent client configuration.\n   - Verify the dashboard loads and shows statistics.\n\n## Docker Build and Testing\n\n### Docker Build\n```bash\ndocker build -f Dockerfile . --tag peerbanhelper-test\n```\n- **NEVER CANCEL**: Build takes 3-4 minutes. NEVER CANCEL. Set timeout to 600+ seconds.\n- Uses multi-stage build: WebUI build, Maven build, then runtime container.\n\n### Docker Testing\n```bash\ndocker run --rm -p 9899:9898 peerbanhelper-test\n# Test with: curl -I http://localhost:9899/\n```\n\n## Key Project Structure\n\n### Backend (Java/Maven)\n- **Main class**: `com.ghostchu.peerbanhelper.MainJumpLoader`\n- **Source**: `src/main/java/` (444 Java source files)\n- **Resources**: `src/main/resources/` (contains config, translations, static files)\n- **Build output**: `target/PeerBanHelper.jar` + `target/libraries/`\n- **No test source directory** - this project has no unit tests\n\n### Frontend (Vue.js/TypeScript)\n- **Source**: `webui/src/`\n- **Package manager**: pnpm (required, npm is not supported)\n- **Build tool**: Vite\n- **Output**: `webui/dist/` → copied to `src/main/resources/static/`\n\n### Configuration Files\n- **Maven**: `pom.xml` (Java 21, 444 source files, extensive dependencies)\n- **WebUI**: `webui/package.json` (Vue 3, TypeScript, ArcoDesign UI library)\n- **Docker**: `Dockerfile` (multi-stage with Node.js and Maven)\n- **Build script**: `build.sh` (automates WebUI + Maven build)\n\n## Common Issues and Solutions\n\n### Build Failures\n- **Missing Java 21**: Ensure you've sourced SDKMAN and installed Java 21.0.4-tem\n- **pnpm not found**: Install pnpm globally with `npm install -g pnpm`\n- **WebUI build before Maven**: Always build WebUI first, Maven depends on the static files\n\n### Runtime Issues\n- **Port conflicts**: Default port 9898, use `-Dpbh.port=8080` to change\n- **GeoIP download failures**: Normal on first run, requires internet connection\n- **Initialization required**: Fresh installs need OOBE setup via WebUI\n\n## Development Workflow\n\n1. **Make Code Changes**: Edit Java/TypeScript source files\n2. **Build**: Run `./build.sh` to build everything\n3. **Lint**: Run `cd webui && pnpm run lint` for frontend changes\n4. **Test**: Start application and validate functionality manually\n5. **Validate**: Test both direct JAR and Docker container deployment\n\n## Command Reference\n\n### Essential Commands (with timeouts)\n```bash\n# Complete build (timeout: 120s)\n./build.sh\n\n# WebUI only (timeout: 120s)\ncd webui && pnpm install && pnpm run build\n\n# Maven only (timeout: 300s)\nsource \"/home/runner/.sdkman/bin/sdkman-init.sh\" && mvn -B clean package --file pom.xml\n\n# Docker build (timeout: 600s)\ndocker build -f Dockerfile . --tag peerbanhelper-test\n\n# Start application for testing\nsource \"/home/runner/.sdkman/bin/sdkman-init.sh\" && java -Dpbh.nogui=true -jar target/PeerBanHelper.jar\n```\n\n### Validation Commands\n```bash\n# Lint WebUI\ncd webui && pnpm run lint\n\n# Test web interface\ncurl -I http://localhost:9898/\n\n# Test API\ncurl -s http://localhost:9898/api/general/status\n```\n\n## Critical Reminders\n\n- **ALWAYS** source SDKMAN before Java/Maven commands: `source \"/home/runner/.sdkman/bin/sdkman-init.sh\"`\n- **NEVER CANCEL** long-running builds - they are expected to take several minutes\n- **ALWAYS** build WebUI before Maven when building manually\n- **ALWAYS** run linting before committing frontend changes\n- **ALWAYS** manually validate application functionality after changes\n- **Set appropriate timeouts** (120s+ for builds, 300s+ for Maven, 600s+ for Docker)","category":".github","tokens":1737},{"name":"SKILL.md","path":".github/skills/openspec-archive-change/SKILL.md","title":"openspec-archive-change Skill","content":"---\nname: openspec-archive-change\ndescription: Archive a completed change in the experimental workflow. Use when the user wants to finalize and archive a change after implementation is complete.\nlicense: MIT\ncompatibility: Requires openspec CLI.\nmetadata:\n  author: openspec\n  version: \"1.0\"\n  generatedBy: \"1.0.0\"\n---\n\nArchive a completed change in the experimental workflow.\n\n**Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague\nor ambiguous you MUST prompt for available changes.\n\n**Steps**\n\n1. **If no change name provided, prompt for selection**\n\n   Run `openspec list --json` to get available changes. Use the **AskUserQuestion tool** to let the user select.\n\n   Show only active changes (not already archived).\n   Include the schema used for each change if available.\n\n   **IMPORTANT**: Do NOT guess or auto-select a change. Always let the user choose.\n\n2. **Check artifact completion status**\n\n   Run `openspec status --change \"<name>\" --json` to check artifact completion.\n\n   Parse the JSON to understand:\n    - `schemaName`: The workflow being used\n    - `artifacts`: List of artifacts with their status (`done` or other)\n\n   **If any artifacts are not `done`:**\n    - Display warning listing incomplete artifacts\n    - Use **AskUserQuestion tool** to confirm user wants to proceed\n    - Proceed if user confirms\n\n3. **Check task completion status**\n\n   Read the tasks file (typically `tasks.md`) to check for incomplete tasks.\n\n   Count tasks marked with `- [ ]` (incomplete) vs `- [x]` (complete).\n\n   **If incomplete tasks found:**\n    - Display warning showing count of incomplete tasks\n    - Use **AskUserQuestion tool** to confirm user wants to proceed\n    - Proceed if user confirms\n\n   **If no tasks file exists:** Proceed without task-related warning.\n\n4. **Assess delta spec sync state**\n\n   Check for delta specs at `openspec/changes/<name>/specs/`. If none exist, proceed without sync prompt.\n\n   **If delta specs exist:**\n    - Compare each delta spec with its corresponding main spec at `openspec/specs/<capability>/spec.md`\n    - Determine what changes would be applied (adds, modifications, removals, renames)\n    - Show a combined summary before prompting\n\n   **Prompt options:**\n    - If changes needed: \"Sync now (recommended)\", \"Archive without syncing\"\n    - If already synced: \"Archive now\", \"Sync anyway\", \"Cancel\"\n\n   If user chooses sync, execute /opsx:sync logic (use the openspec-sync-specs skill). Proceed to archive regardless of\n   choice.\n\n5. **Perform the archive**\n\n   Create the archive directory if it doesn't exist:\n   ```bash\n   mkdir -p openspec/changes/archive\n   ```\n\n   Generate target name using current date: `YYYY-MM-DD-<change-name>`\n\n   **Check if target already exists:**\n    - If yes: Fail with error, suggest renaming existing archive or using different date\n    - If no: Move the change directory to archive\n\n   ```bash\n   mv openspec/changes/<name> openspec/changes/archive/YYYY-MM-DD-<name>\n   ```\n\n6. **Display summary**\n\n   Show archive completion summary including:\n    - Change name\n    - Schema that was used\n    - Archive location\n    - Whether specs were synced (if applicable)\n    - Note about any warnings (incomplete artifacts/tasks)\n\n**Output On Success**\n\n```\n## Archive Complete\n\n**Change:** <change-name>\n**Schema:** <schema-name>\n**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/\n**Specs:** ✓ Synced to main specs (or \"No delta specs\" or \"Sync skipped\")\n\nAll artifacts complete. All tasks complete.\n```\n\n**Guardrails**\n\n- Always prompt for change selection if not provided\n- Use artifact graph (openspec status --json) for completion checking\n- Don't block archive on warnings - just inform and confirm\n- Preserve .openspec.yaml when moving to archive (it moves with the directory)\n- Show clear summary of what happened\n- If sync is requested, use openspec-sync-specs approach (agent-driven)\n- If delta specs exist, always run the sync assessment and show the combined summary before prompting\n","category":".github","tokens":1013}]}