diff --git a/.ai/COMMANDS.md b/.ai/COMMANDS.md new file mode 100644 index 0000000..83aad35 --- /dev/null +++ b/.ai/COMMANDS.md @@ -0,0 +1,55 @@ +# Known Commands + +Only commands verified for this repository should be added here. + +## Repo status + + git status --short --branch + +## Install + + # Add repo-specific install command here + +## Start + + # Add repo-specific start command here + +## Stop + + # Add repo-specific stop command here + +## Restart + + # Add repo-specific restart command here + +## Lint + + # Add repo-specific lint command here + +## Test + + # Add repo-specific test command here + +## Build + + # Add repo-specific build command here + +## Typecheck + + # Add repo-specific typecheck command here + +## Format + + # Add repo-specific format command here + +## Audit + + # Add repo-specific audit command here + +## Rollback + + git status --short + git restore . + git clean -fd + +Warning: `git clean -fd` deletes untracked files. Review before using. diff --git a/.ai/FAILURES.md b/.ai/FAILURES.md new file mode 100644 index 0000000..c84c28c --- /dev/null +++ b/.ai/FAILURES.md @@ -0,0 +1,54 @@ +# Failure Knowledge Base + +Record recurring failures and proven fixes. + +## Template + +### Failure title + +- Date first seen: +- Symptoms: +- Error text: +- Cause: +- Fix: +- Verification: +- Prevention: + +--- + +## Known failures + +### Port 8788 already in use + +- Symptoms: Hermes/Hermex cannot start or browser cannot connect. +- Check: + + ss -ltnp | grep ':8788' + +- Fix: + + fuser -k 8788/tcp + +- Verification: + + curl -I http://127.0.0.1:8788 || true + +### GitHub auth expired + +- Symptoms: `gh` commands fail. +- Check: + + gh auth status + +- Fix: + + gh auth login + +### Tailscale IP changed + +- Symptoms: iPhone cannot reach old Hermex URL. +- Check: + + tailscale ip -4 + +- Fix: Update saved Hermex URL to current Tailscale IP. diff --git a/.ai/GITHUB_PROJECTS_PLAN.md b/.ai/GITHUB_PROJECTS_PLAN.md new file mode 100644 index 0000000..5e33a9a --- /dev/null +++ b/.ai/GITHUB_PROJECTS_PLAN.md @@ -0,0 +1,37 @@ +# GitHub Projects Plan — AI Mobile Command Center + +## Project name + +AI Mobile Command Center + +## Purpose + +Track Hermes, Hermex, GitHub, OpenCode, terminal, and mobile development work from one board. + +## Recommended fields + +| Field | Type | Values | +|---|---|---| +| Repo | Single select | agent-workbench, hermes-webui, scripts, opencode | +| Agent | Single select | Hermes, OpenCode, Manual, Review | +| Risk | Single select | Safe, Needs Review, Dangerous | +| Device | Single select | iPhone, WSL, GitHub Actions, PC | +| Status | Single select | Inbox, Ready, Running, Blocked, Review, Done | +| Next Command | Text | Exact next command or /opencode comment | +| Context Health | Single select | Green, Yellow, Red | + +## Automation rules + +- New issue → Inbox +- PR opened → Review +- PR merged → Done +- Failed workflow → Blocked +- Label `agent-task` → Ready +- Label `dangerous` → Needs manual review + +## Mobile usage + +- Hermex: task creation and summaries +- GitHub Mobile: approval, review, merge +- Termius/Moshi: manual terminal execution +- GitHub Actions: verification diff --git a/.ai/RULESET_PLAN.md b/.ai/RULESET_PLAN.md new file mode 100644 index 0000000..009c4be --- /dev/null +++ b/.ai/RULESET_PLAN.md @@ -0,0 +1,27 @@ +# Repository Ruleset Plan + +## Target branch + +main + +## Required protections + +- Require pull request before merge +- Require status checks before merge +- Block force push +- Block branch deletion +- Require conversation resolution +- Restrict direct pushes to main +- Require linear history if compatible with workflow + +## Required status checks + +- AI Safety Checks +- Repo Health +- CodeQL + +## Rollout mode + +1. Start in Evaluate mode if available. +2. Confirm no expected workflow is blocked. +3. Switch to Active mode. diff --git a/.ai/RUN_LEDGER.md b/.ai/RUN_LEDGER.md new file mode 100644 index 0000000..030f57a --- /dev/null +++ b/.ai/RUN_LEDGER.md @@ -0,0 +1,26 @@ +# AI Run Ledger + +Use this file to record meaningful AI-assisted changes. + +## Template + +### YYYY-MM-DD — Short run title + +- Agent: +- Model/provider: +- Trigger: +- Related issue/PR: +- Files changed: +- Commands run: +- Tests run: +- Result: +- Risks: +- Rollback command: + + git revert + +--- + +## Runs + +No runs recorded yet. diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..19f02cd --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,27 @@ +{ + "name": "Agent Workbench Dev", + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "ghcr.io/devcontainers/features/github-cli:1": {}, + "ghcr.io/devcontainers/features/node:1": { + "version": "lts" + }, + "ghcr.io/devcontainers/features/python:1": { + "version": "3.12" + }, + "ghcr.io/devcontainers/features/go:1": { + "version": "latest" + } + }, + "postCreateCommand": "bash .devcontainer/setup.sh", + "customizations": { + "vscode": { + "extensions": [ + "GitHub.vscode-github-actions", + "GitHub.vscode-pull-request-github", + "GitHub.copilot", + "GitHub.copilot-chat" + ] + } + } +} diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh new file mode 100755 index 0000000..d555d1d --- /dev/null +++ b/.devcontainer/setup.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -euo pipefail + +echo "Setting up dev container..." + +if [ -f package.json ]; then + npm install +fi + +if [ -f requirements.txt ]; then + python3 -m pip install -r requirements.txt +fi + +if [ -f go.mod ]; then + go mod download +fi + +echo "Dev container setup complete." diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..85bfcc6 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,21 @@ +# Global owner +* @MerverliPy + +# GitHub automation and security-sensitive files +.github/workflows/* @MerverliPy +.github/dependabot.yml @MerverliPy +.github/CODEOWNERS @MerverliPy +SECURITY.md @MerverliPy + +# Agent and automation controls +.ai/* @MerverliPy +bin/* @MerverliPy +scripts/* @MerverliPy + +# Environment examples and config templates +*.env.example @MerverliPy +config/* @MerverliPy + +# Security/auth-sensitive source zones +src/auth/* @MerverliPy +src/security/* @MerverliPy diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c5db258..fe62ae1 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,11 +5,29 @@ version: 2 updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + time: "08:00" + labels: + - "dependencies" + - "github-actions" + - "automated" + open-pull-requests-limit: 5 + groups: + github-actions-minor-patch: + update-types: + - "minor" + - "patch" + - package-ecosystem: "npm" directory: "/" schedule: interval: "weekly" day: "monday" + time: "08:30" groups: typescript: patterns: @@ -23,11 +41,19 @@ updates: prefix: "chore(deps)" prefix-development: "chore(deps-dev)" - - package-ecosystem: "github-actions" + - package-ecosystem: "pip" directory: "/" schedule: interval: "weekly" day: "monday" + time: "09:00" labels: - "dependencies" - - "ci" + - "python" + - "automated" + open-pull-requests-limit: 5 + groups: + python-minor-patch: + update-types: + - "minor" + - "patch" diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..d2b95c1 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,28 @@ +changelog: + exclude: + labels: + - ignore-for-release + authors: + - dependabot + categories: + - title: Breaking Changes + labels: + - breaking + - title: Features + labels: + - feature + - enhancement + - title: Fixes + labels: + - bug + - fix + - title: Security + labels: + - security + - title: Maintenance + labels: + - dependencies + - maintenance + - title: Other Changes + labels: + - "*" diff --git a/.github/workflows/ai-safety.yml b/.github/workflows/ai-safety.yml new file mode 100644 index 0000000..da63acc --- /dev/null +++ b/.github/workflows/ai-safety.yml @@ -0,0 +1,34 @@ +name: AI Safety Checks + +on: + pull_request: + push: + branches: [ "main" ] + +permissions: + contents: read + +jobs: + safety: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Check for obvious secret patterns + run: | + set -e + if grep -RInE '(OPENAI_API_KEY|ANTHROPIC_API_KEY|GITHUB_TOKEN|TELEGRAM_BOT_TOKEN|BEGIN RSA PRIVATE KEY|BEGIN OPENSSH PRIVATE KEY)' . \ + --exclude-dir=.git \ + --exclude='*.md'; then + echo "Potential secret detected." + exit 1 + fi + + - name: Check for risky destructive shell patterns + run: | + set -e + if grep -RInE 'rm -rf /|rm -rf \$HOME|mkfs\.|dd if=|chmod -R 777|curl .*\| bash|wget .*\| bash' . \ + --exclude-dir=.git; then + echo "Risky destructive pattern detected." + exit 1 + fi diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..d100c5a --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,40 @@ +name: CodeQL + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + schedule: + - cron: "23 7 * * 1" + +permissions: + security-events: write + packages: read + actions: read + contents: read + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: [ "javascript-typescript", "python" ] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + + - name: Autobuild + uses: github/codeql-action/autobuild@v3 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/opencode.yml b/.github/workflows/opencode.yml new file mode 100644 index 0000000..f417889 --- /dev/null +++ b/.github/workflows/opencode.yml @@ -0,0 +1,32 @@ +name: OpenCode Agent + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + +permissions: + contents: write + pull-requests: write + issues: write + actions: read + +jobs: + opencode: + if: contains(github.event.comment.body, '/opencode') || contains(github.event.comment.body, '/oc') + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Show request + run: | + echo "OpenCode trigger detected." + echo "${{ github.event.comment.body }}" + + - name: Placeholder for OpenCode GitHub integration + run: | + echo "Install/configure OpenCode GitHub integration here." + echo "Do not enable autonomous write behavior until secrets and approval rules are configured." diff --git a/.github/workflows/repo-health.yml b/.github/workflows/repo-health.yml new file mode 100644 index 0000000..8cdd64c --- /dev/null +++ b/.github/workflows/repo-health.yml @@ -0,0 +1,42 @@ +name: Repo Health + +on: + pull_request: + push: + branches: [ "main" ] + +permissions: + contents: read + +jobs: + health: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Repo inventory + run: | + find . -maxdepth 3 -type f | sort | sed 's#^\./##' | head -300 + + - name: Node checks + if: hashFiles('package.json') != '' + run: | + npm ci || npm install + npm run lint --if-present + npm run typecheck --if-present + npm test --if-present + npm run build --if-present + + - name: Python checks + if: hashFiles('requirements.txt', 'pyproject.toml') != '' + run: | + python -m pip install --upgrade pip + if [ -f requirements.txt ]; then python -m pip install -r requirements.txt; fi + python -m compileall . + + - name: Go checks + if: hashFiles('go.mod') != '' + run: | + go mod download + go test ./...