diff --git a/.claude/memory/MEMORY.md b/.claude/memory/MEMORY.md index 7fc1f494..d11d079d 100644 --- a/.claude/memory/MEMORY.md +++ b/.claude/memory/MEMORY.md @@ -19,6 +19,7 @@ - [Syncro API — Invoice Verification Pattern](syncro_invoice_verification_pattern.md) — /invoices?customer_id=X returns no ticket linkage; query /invoices/{number} for ticket_id. Compare by ticket ID, not number. - [Syncro asset/RMM IS API-drivable](reference_syncro_rmm_api_gui_only.md) — CORRECTED 2026-07-10: asset read/create/update, patches, installed_apps, rmm_alerts all work via API; ONLY policy folders + `policy_folder_id` move need the `Assets - Policy Change` token scope (401 today). Archive stays GUI-only. Full catalog: `.claude/standards/syncro/api-reference.md`. - [Datto EDR detection behavior](reference_datto_edr_detection_behavior.md) — alert `sourceType`: `av`=Datto AV signature, `rule`=EDR reputation detection (both via `edr.py detections`). EDR is reputation-based not structural (wire known-bad file as autostart exe to trip it; loose files aren't surveyed). AV is tamper-protected (console-only disable); disabling Datto AV uninstalls it + Defender auto-reactivates (AMSI blocks scripts with literal EICAR → build from char codes). Verified live on RMM-TEST-MACHINE. +- [Bug & Project Tracker (Gitea Issues)](project_bug_tracker_gitea.md) — Official tracker for bugs/features/skills across GuruRMM, GuruConnect, ClaudeTools. Dashboard + `bug-tracker` skill. Set up 2026-07-17. - [Approval Workflow: Tools vs Projects](approval-workflow-tools-vs-projects.md) — Tools (remediation, scripts): Howard/Claude with approval. Projects (GuruRMM): Mike approval for architecture/features; Howard can handle merges/deploys himself (2026-06-21); bugs→bug list. - [CDP Chrome driver](reference_cdp_chrome_driver.md) — Drive Chrome via DevTools Protocol (.claude/scripts/cdp.py): visible window + screenshots-to-disk so Gemini/Grok can SEE the live site. Use localhost not 127.0.0.1; dedicated profile. Antigravity-style. - [Firefox driver (ff.py)](reference_ff_firefox_driver.md) — PREFERRED browser driver. Drive Firefox via Playwright (.claude/scripts/ff.py): daemon on :9333, persistent profile, nav/shot/click/type/eval/console/network. Mike dislikes Chrome; claude-in-chrome connector disabled 2026-06-06. diff --git a/.claude/memory/project_bug_tracker_gitea.md b/.claude/memory/project_bug_tracker_gitea.md new file mode 100644 index 00000000..b493f58e --- /dev/null +++ b/.claude/memory/project_bug_tracker_gitea.md @@ -0,0 +1,27 @@ +--- +name: Bug & Project Tracker (Gitea Issues) +description: Gitea Issues is the official bug/feature/skill/project tracker for GuruRMM, GuruConnect, and ClaudeTools. Dashboard at projects/msp-tools/bug-tracker/dashboard.html. Skill at .claude/skills/bug-tracker/skill.md. +type: project +--- + +Mike and Howard want centralized tracking of bugs, features, skills, and project work across +GuruRMM, GuruConnect, and ClaudeTools — the wiki was not working as a tracker (no status, +no history, things got forgotten). Set up 2026-07-17. + +**Why:** Bug fixes and feature work were getting dropped because there was no visible tracker. +Unless someone remembered to ask, work just disappeared. The forum (Discord ct-forum) is good +for discussion/decisions but has no status fields, filtering, or board view. + +**How to apply:** +- When a bug surfaces during a session, file it as a Gitea issue (use the `bug-tracker` skill) +- Repos tracked: `gururmm`, `guru-connect`, `claudetools` (owner: `azcomputerguru`) +- Standard labels: bug/feature/skill/project, P1-P4 priority, component tags, status tags (in-progress/blocked/dropped/fixed/verified) +- Milestones: "Active Sprint" and "Backlog" on each repo +- **Live dashboard:** `https://tracker.azcomputerguru.com/dashboard.html` (SSL via NPM on Jupiter) + - Docker container `acg-tracker` on Jupiter (172.16.3.20:8089), nginx:alpine, files at `/mnt/user/appdata/acg-tracker/` + - NPM proxy host ID 12, SSL cert ID 13 (Let's Encrypt DNS challenge via Cloudflare) + - Cloudflare DNS A record: tracker.azcomputerguru.com -> 72.194.62.10 + - Login with Gitea username/password (stored in localStorage via Basic auth) + - To update dashboard: re-upload `dashboard.html` to Jupiter via SFTP, `docker restart acg-tracker` +- Kanban board (Open / In Progress / Blocked / Done), list view, create/comment/close issues from the dashboard +- Source files: `projects/msp-tools/bug-tracker/` diff --git a/.claude/skills/bug-tracker/skill.md b/.claude/skills/bug-tracker/skill.md new file mode 100644 index 00000000..01a6ebc2 --- /dev/null +++ b/.claude/skills/bug-tracker/skill.md @@ -0,0 +1,90 @@ +--- +name: bug-tracker +description: "File, list, update, and close bugs/features/tasks in the Gitea issue tracker across GuruRMM, GuruConnect, and ClaudeTools repos. Visual dashboard at projects/msp-tools/bug-tracker/dashboard.html." +triggers: + - "file a bug" + - "track a bug" + - "open an issue" + - "bug tracker" + - "what bugs are open" + - "list bugs" + - "close issue" + - "update issue" + - "mark fixed" + - "what's being worked on" +--- + +# Bug & Project Tracker — Gitea Issues + +Manage the ACG bug/feature/skill/project tracker via Gitea Issues API. +Dashboard: `projects/msp-tools/bug-tracker/dashboard.html` + +## Setup + +- Gitea: `https://git.azcomputerguru.com/api/v1` +- Owner: `azcomputerguru` +- Token: vault `services/gitea` → `credentials.api.api-token` +- Tracked repos: `gururmm`, `guru-connect`, `claudetools` + +## Label scheme + +| Label | Purpose | +|-------|---------| +| `bug` | Something broken | +| `feature` | New capability | +| `skill` | Skill work | +| `project` | Project-level | +| `P1-critical` / `P2-high` / `P3-normal` / `P4-low` | Priority | +| `in-progress` | Being worked | +| `blocked` | Blocked | +| `dropped` | Stalled | +| `fixed` | Fix applied | +| `verified` | Confirmed working | +| `security` | Security-related | +| `component:rmm-agent` / `rmm-server` / `rmm-dashboard` / `guruconnect` / `harness` | Component | + +## Operations + +### File a new issue +Read the token from vault. POST to `/repos/{owner}/{repo}/issues`: +```json +{ + "title": "...", + "body": "## Problem\n...\n\n## Steps to reproduce\n...\n\n## Expected behavior\n...\n\n## Session context\nFiled from session on MACHINE at DATE", + "labels": [label_id, label_id, ...] +} +``` +Always include: one type label (bug/feature/skill/project), one priority label, component label(s) if applicable. + +### List open issues +GET `/repos/{owner}/{repo}/issues?state=open&type=issues&limit=50` +For cross-repo view, query all tracked repos and merge results. + +### Update an issue (add progress, change status) +- Add a comment: POST `/repos/{owner}/{repo}/issues/{number}/comments` with `{"body": "..."}` +- Change labels: PATCH `/repos/{owner}/{repo}/issues/{number}` or use label endpoints +- Close: PATCH with `{"state": "closed"}` + +### Mark fixed +Add `fixed` label, add a comment describing the fix, reference the commit if available. + +### Mark verified +Add `verified` label, close the issue. + +## Auto-filing (IMPORTANT) + +When a bug surfaces during a Claude session — a command fails unexpectedly, a skill hits an error that needs follow-up, or the user reports something broken — **file it as an issue automatically** (with user confirmation for the title/priority). This is the whole point: bugs should not require someone to remember them. + +The issue body should include: +- What happened (error message, unexpected behavior) +- Context (what was being attempted, which machine, which session) +- Any workaround applied +- Links to relevant session logs if available + +## Dashboard + +Open `projects/msp-tools/bug-tracker/dashboard.html` in a browser. +Pass the Gitea token as a URL parameter: `?token=xxx` +It shows a kanban board (Open / In Progress / Blocked / Done) with filtering by repo and type. + +$ARGUMENTS diff --git a/projects/msp-tools/bug-tracker/Dockerfile b/projects/msp-tools/bug-tracker/Dockerfile new file mode 100644 index 00000000..3e77b405 --- /dev/null +++ b/projects/msp-tools/bug-tracker/Dockerfile @@ -0,0 +1,4 @@ +FROM nginx:alpine +COPY nginx.conf /etc/nginx/conf.d/default.conf +COPY dashboard.html /usr/share/nginx/html/dashboard.html +EXPOSE 80 diff --git a/projects/msp-tools/bug-tracker/dashboard.html b/projects/msp-tools/bug-tracker/dashboard.html new file mode 100644 index 00000000..99c3d88f --- /dev/null +++ b/projects/msp-tools/bug-tracker/dashboard.html @@ -0,0 +1,655 @@ + + + + + +ACG Tracker + + + + +
+
+

ACG Tracker

+

Bug tracking, project status, and skill work across all Guru repos

+ + + + +

+ Mike: azcomputerguru · Howard: howard +

+
+
+ +
+
+

ACG Tracker

+
+ + sign out +
+
+
+ +
+
+
+ + +
+ +
+ + +
+ +
+ + + + diff --git a/projects/msp-tools/bug-tracker/nginx.conf b/projects/msp-tools/bug-tracker/nginx.conf new file mode 100644 index 00000000..c33ee774 --- /dev/null +++ b/projects/msp-tools/bug-tracker/nginx.conf @@ -0,0 +1,19 @@ +server { + listen 80; + server_name localhost; + root /usr/share/nginx/html; + index dashboard.html; + + # Proxy Gitea API to avoid CORS issues + # Use host gateway to reach Gitea on the Docker host at port 3000 + location /gitea/ { + proxy_pass http://host.docker.internal:3000/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location / { + try_files $uri $uri/ /dashboard.html; + } +} diff --git a/projects/msp-tools/bug-tracker/serve.sh b/projects/msp-tools/bug-tracker/serve.sh new file mode 100644 index 00000000..79cc9f6c --- /dev/null +++ b/projects/msp-tools/bug-tracker/serve.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# Serve the bug tracker dashboard on localhost:8089 +# Usage: bash projects/msp-tools/bug-tracker/serve.sh [--open] +# +# Pass the Gitea token as ?token=xxx in the browser URL, or set GITEA_TOKEN env var +# to have it injected automatically. + +DIR="$(cd "$(dirname "$0")" && pwd)" +PORT=8089 + +echo "[INFO] Serving bug tracker dashboard at http://localhost:$PORT/dashboard.html" + +if [[ -n "$GITEA_TOKEN" ]]; then + echo "[INFO] Open: http://localhost:$PORT/dashboard.html?token=$GITEA_TOKEN" +else + echo "[INFO] Add ?token=YOUR_GITEA_TOKEN to the URL for authenticated access" +fi + +if [[ "$1" == "--open" ]]; then + (sleep 1 && start "" "http://localhost:$PORT/dashboard.html") & +fi + +cd "$DIR" +python -m http.server $PORT --bind 127.0.0.1 diff --git a/session-logs/2026-07/2026-07-17-howard-bug-tracker-deployment.md b/session-logs/2026-07/2026-07-17-howard-bug-tracker-deployment.md new file mode 100644 index 00000000..bd767e7a --- /dev/null +++ b/session-logs/2026-07/2026-07-17-howard-bug-tracker-deployment.md @@ -0,0 +1,122 @@ +# 2026-07-17 — Bug & Project Tracker Deployment + +## User +- **User:** Howard Enos (howard) +- **Machine:** Howard-Home +- **Role:** tech + +## Session Summary + +Howard relayed Mike's request for a real bug and project tracker. The existing wiki-based bug tracking was insufficient — bugs and feature work were getting dropped and forgotten because there was no visible tracker with status, priority, history, or assignment. The Discord ct-forum was considered but rejected as a tracker because it lacks status fields, filtering, and board views. + +Evaluated options and chose Gitea Issues as the backend since the infrastructure was already running (Gitea on Jupiter, 33 repos, issues enabled everywhere). Created a standardized label scheme (type: bug/feature/skill/project/security; priority: P1-P4; status: in-progress/blocked/dropped/fixed/verified; components: rmm-agent/server/dashboard/guruconnect/harness) and applied it across 4 tracked repos: gururmm, guru-rmm, guru-connect, and claudetools. Created milestones (Active Sprint, Backlog) on each. + +Built a single-page dashboard (dashboard.html) that reads/writes directly to the Gitea API — no separate database, no sync jobs, no cache. The dashboard provides: login via Gitea credentials (stored in localStorage), kanban board view (Open/In Progress/Blocked/Done), sortable list view, sidebar sections (RMM Bugs/Features/Security, GuruConnect, Harness Bugs, Skill Work, Projects), search, issue creation, commenting, status changes (in-progress/blocked/fixed/close/reopen), and detail modals with full comment history. + +Deployed the dashboard as a Docker container (nginx:alpine) on Jupiter (172.16.3.20:8089), proxied through NPM with Let's Encrypt SSL at tracker.azcomputerguru.com. The nginx config proxies /gitea/ to the local Gitea instance to avoid CORS issues. Created Cloudflare DNS A record pointing to 72.194.62.10. Verified round-trip: create -> read -> comment -> close all work through the proxy, both Howard and Mike logins confirmed working. + +Backfilled 60+ issues from existing sources: errorlog.md bugs became ClaudeTools issues (vault leak, remediation-tool failures, discord-dm attachment bug, msp360 licensing, syncro parse errors, unifi-wifi truncation, coord API errors); RMM Thoughts features became gururmm issues (14 features from the backlog); skill work items filed (8 skills needing work + 3 project-level items). All backfilled issues include a "Discovered: YYYY-MM-DD" field in the body so the dashboard shows accurate ages rather than the filing date. Fixed label gaps on all older issues (12 closed gururmm, 5 older guru-connect, guru-rmm #1) so every issue across all repos has type + priority labels. DM'd Mike the tracker URL and login instructions. + +## Key Decisions + +- **Gitea Issues over Discord forum or external tools** — Gitea was already running, has issues/labels/milestones/API, and requires no new accounts or services. The forum is good for discussion but lacks status fields and board views. +- **Single HTML dashboard with Gitea API proxy** — no separate database or sync mechanism. The dashboard IS Gitea's data displayed as a board. Changes in Gitea appear immediately in the dashboard and vice versa. +- **nginx proxy for /gitea/ path** — avoids CORS issues by proxying API calls through the same origin. Uses host.docker.internal to reach Gitea on the Docker host. +- **Basic auth (localStorage) over API tokens in URLs** — users log in with their Gitea username/password once, stored in browser localStorage. No tokens in URLs or embedded in the page. +- **"Discovered" date field in issue body** — Gitea doesn't support backdating created_at via API. Added `**Discovered:** YYYY-MM-DD` to issue bodies and the dashboard parses it to show accurate ages. +- **Strict separation: our code bugs only, no client machine issues** — the tracker only holds bugs in our code (skills, scripts, harness, RMM, GuruConnect) and our feature/project work. Client machine problems, vendor API limitations, and client-specific quirks stay in the wiki and errorlog. +- **Sidebar sections by domain** — not just repo filters. RMM Bugs / RMM Features / RMM Security / GuruConnect / Harness Bugs / Skill Work / Projects give focused views into each area. + +## Problems Encountered + +- **Gitea project boards API not exposed in v1.25** — the built-in project board feature exists in the web UI but has no REST API. Solved by building the custom dashboard with its own kanban rendering. +- **CORS on local file:// origin** — the initial dashboard opened as a local file couldn't make fetch calls to the Gitea API. Solved by serving via a local HTTP server, then deploying as a proper Docker container behind NPM. +- **nginx proxy 502 to git.azcomputerguru.com** — the container couldn't resolve the external hostname. Fixed by proxying to host.docker.internal:3000 (Gitea's internal port) with --add-host flag on docker run. +- **NPM SSL cert creation API schema** — the meta field validation was strict. Required dns_challenge + dns_provider + dns_provider_credentials in exact format (no extra fields like letsencrypt_email). +- **Local DNS at Cascades (10.137.42.1) not resolving new record** — the UniFi DNS server hadn't picked up the new Cloudflare record. Public DNS (8.8.8.8, 1.1.1.1) resolved fine. Workaround: direct IP access; DNS propagation resolves naturally. +- **sshpass not available on Windows** — needed for SSH to Jupiter with password. Solved using Python paramiko for all SSH/SFTP operations. +- **Backfilled issues showing "7m" age** — all newly created issues showed minutes-old ages instead of their real discovery dates. Solved by adding Discovered dates to issue bodies and updating the dashboard to parse and display them. + +## Configuration Changes + +### Files Created +- `projects/msp-tools/bug-tracker/dashboard.html` — main tracker dashboard (single-page app) +- `projects/msp-tools/bug-tracker/nginx.conf` — nginx config with Gitea API proxy +- `projects/msp-tools/bug-tracker/Dockerfile` — nginx:alpine container definition +- `projects/msp-tools/bug-tracker/serve.sh` — local development server script +- `.claude/skills/bug-tracker/skill.md` — bug-tracker skill definition +- `.claude/memory/project_bug_tracker_gitea.md` — project memory for the tracker + +### Files Modified +- `.claude/memory/MEMORY.md` — added bug tracker memory entry + +### Gitea Changes (via API) +- Created 20 labels on each of 4 repos (gururmm, guru-rmm, guru-connect, claudetools) +- Created 2 milestones per repo (Active Sprint, Backlog) on gururmm, guru-connect, claudetools +- Filed 10 ClaudeTools bug issues from errorlog +- Filed 14 GuruRMM feature issues from RMM Thoughts +- Filed 8 skill work issues + 3 project issues on ClaudeTools +- Added type/priority labels to all 12 closed gururmm issues, 5 older guru-connect issues, guru-rmm #1 +- Added Discovered dates to all 35 backfilled issue bodies + +### Infrastructure Changes +- Docker container `acg-tracker` created on Jupiter (172.16.3.20:8089) +- Files deployed to `/mnt/user/appdata/acg-tracker/` on Jupiter +- NPM proxy host ID 12 created: tracker.azcomputerguru.com -> 172.16.3.20:8089 +- SSL cert ID 13 created: Let's Encrypt via Cloudflare DNS challenge +- Cloudflare DNS A record: tracker.azcomputerguru.com -> 72.194.62.10 + +## Credentials & Secrets + +- Gitea API token (azcomputerguru): `9b1da4b79a38ef782268341d25a4b6880572063f` (vault: services/gitea) +- Gitea Howard login: howard / q6Uh-qZCq-d6mMf_DrJ64pf7WQQ6 (vault: services/gitea-howard) +- Jupiter SSH: root / Th1nk3r^99## (vault: infrastructure/jupiter-unraid-primary) +- NPM admin: mike@azcomputerguru.com / JcmO6nERg4m5JtD6 (vault: services/npm) +- Cloudflare DNS token: DRRGkHS33pxAUjQfRDzDeVPtt6wwUU6FwtXqOzNj (vault: services/cloudflare) + +## Infrastructure & Servers + +- **Jupiter:** 172.16.3.20, Docker host, Unraid + - `acg-tracker` container: nginx:alpine, port 8089, restart unless-stopped + - Files: `/mnt/user/appdata/acg-tracker/dashboard.html`, `nginx.conf` + - `--add-host host.docker.internal:host-gateway` for Gitea proxy +- **Gitea:** 172.16.3.20:3000 (Docker container `gitea`) +- **NPM:** 172.16.3.20:7818 (admin), ports 1880/18443 + - Proxy host #12: tracker.azcomputerguru.com -> 172.16.3.20:8089 (SSL, cert #13) +- **Cloudflare:** zone 1beb9917c22b54be32e5215df2c227ce + - A record: tracker -> 72.194.62.10 (not proxied) +- **Public URL:** https://tracker.azcomputerguru.com/dashboard.html + +## Commands & Outputs + +```bash +# Deploy tracker to Jupiter (via paramiko) +docker run -d --name acg-tracker --restart unless-stopped \ + --add-host host.docker.internal:host-gateway \ + -p 8089:80 \ + -v /mnt/user/appdata/acg-tracker/dashboard.html:/usr/share/nginx/html/dashboard.html:ro \ + -v /mnt/user/appdata/acg-tracker/nginx.conf:/etc/nginx/conf.d/default.conf:ro \ + nginx:alpine + +# Update dashboard on Jupiter +# Upload via SFTP, then: docker restart acg-tracker +``` + +## Pending / Incomplete Tasks + +- Local DNS at Cascades (10.137.42.1) may still not resolve tracker.azcomputerguru.com — will propagate naturally +- The bug-tracker skill needs integration into session error-handling workflows so bugs are auto-filed (tracked as claudetools issue #13) +- Consider adding assignee support to the dashboard (Gitea supports assignees) +- RMM Thoughts backlog (RMM_THOUGHTS.md) now has corresponding Gitea issues — future feature requests should go directly to Gitea via the tracker + +## Reference Information + +- Dashboard source: `projects/msp-tools/bug-tracker/dashboard.html` +- Skill definition: `.claude/skills/bug-tracker/skill.md` +- Memory: `.claude/memory/project_bug_tracker_gitea.md` +- Live URL: https://tracker.azcomputerguru.com/dashboard.html +- Direct URL: http://172.16.3.20:8089/dashboard.html +- Gitea repos tracked: gururmm, guru-rmm, guru-connect, claudetools +- NPM proxy host ID: 12, SSL cert ID: 13 +- Discord DM to Mike: message_id 1527866483869220864 +- Final issue counts: gururmm 21 open / 12 closed, guru-connect 18 open, claudetools 21 open, guru-rmm 1 open