Commit Graph

281 Commits

Author SHA1 Message Date
fd719f4ce9 sync: auto-sync from Mikes-MacBook-Air.local at 2026-05-12 20:04:47
Author: Mike Swanson
Machine: Mikes-MacBook-Air.local
Timestamp: 2026-05-12 20:04:47
2026-05-12 20:04:48 -07:00
f18a7f7dcf chore: update guru-rmm submodule pointer (session log) 2026-05-12 18:22:51 -07:00
e31162f3b8 sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-12 18:20:46
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-12 18:20:46
2026-05-12 18:20:46 -07:00
46485af009 sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-12 17:13:53
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-12 17:13:53
2026-05-12 17:13:55 -07:00
701e44c31b sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-12 12:09:27
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-12 12:09:27
2026-05-12 12:09:29 -07:00
e2316bfbf4 sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-12 10:48:35
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-12 10:48:35
2026-05-12 10:48:36 -07:00
f1bc4ee274 sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-12 10:18:07
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-12 10:18:07
2026-05-12 10:18:07 -07:00
c13947eac7 sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-12 10:15:17
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-12 10:15:17
2026-05-12 10:15:18 -07:00
5d70ec015c sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-12 09:54:38
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-12 09:54:38
2026-05-12 09:54:38 -07:00
68a0fd43e6 feat(gururmm): Phase 1 — Script Library, Check System, and Check-based Alerts
Submodule advanced through three commits:
- f6a9a5d: Phase 1 implementation (19 files, 2,838 insertions)
- ed3b797: Post-review fixes (disk threshold inversion + agents RwLock scope)
- 602eb85: Session log 2026-05-12

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 08:41:20 -07:00
fc8cc5f125 feat: retire PROJECT_STATE.md — add real-time coordination API protocol
- CLAUDE.md: triggers now query coordination API (/api/coord/status,
  /api/coord/components, /api/coord/messages) instead of reading
  PROJECT_STATE.md files
- COORDINATION_PROTOCOL.md: new doc covering locks, component states,
  workflows, work items, and inter-session messages via ClaudeTools API
- guru-rmm/PROJECT_STATE.md: marked ARCHIVED, redirects to
  COORDINATION_PROTOCOL.md for live state

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 08:37:13 -07:00
7a733c5d54 sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-12 08:28:49
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-12 08:28:49
2026-05-12 08:28:49 -07:00
bd88398297 sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-12 07:50:21
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-12 07:50:21
2026-05-12 07:50:21 -07:00
e75ddfbc53 sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-12 07:04:17
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-12 07:04:17
2026-05-12 07:04:18 -07:00
b1a588d0db sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-12 06:47:00
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-12 06:47:00
2026-05-12 06:47:00 -07:00
9fcd71bfbc sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-12 05:49:05
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-12 05:49:05
2026-05-12 05:49:06 -07:00
087e7cabc6 sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-11 19:44:15
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-11 19:44:15
2026-05-11 19:44:15 -07:00
373531d235 sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-11 19:16:35
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-11 19:16:35
2026-05-11 19:16:35 -07:00
6183b1c319 sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-11 18:22:21
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-11 18:22:21
2026-05-11 18:22:23 -07:00
2349259999 sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-08 12:25:28
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-08 12:25:28
2026-05-08 12:25:32 -07:00
8539f62462 radio-archive: add /api/clip endpoint + download buttons + ffmpeg in Dockerfile
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 08:44:46 -07:00
b1fac9ba16 sync: auto-sync from Mikes-MacBook-Air.local at 2026-05-08 10:42:22
Author: Mike Swanson
Machine: Mikes-MacBook-Air.local
Timestamp: 2026-05-08 10:42:22
2026-05-08 10:42:23 -04:00
d9812f75cd sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-04 12:24:49
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-04 12:24:49
2026-05-04 12:24:51 -07:00
b008b61440 sync: auto-sync from GURU-BEAST-ROG at 2026-05-01 15:05:53
Author: Mike Swanson
Machine: GURU-BEAST-ROG
Timestamp: 2026-05-01 15:05:53
2026-05-01 15:05:56 -07:00
281cdc4e4f Session log: radio-show UI redesign recovery + Jupiter audio-404 diagnosis
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 05:41:07 -07:00
d7ce9cb670 radio: visual redesign of search + episode pages, active-Q&A highlight follows playhead
Frontend pass on the two embedded HTML templates in the FastAPI server. No
backend / Python logic changed; only template strings, CSS, and inline JS.

Index page: full CSS custom-property theme (light, #c39733 accent),
responsive viewport meta, search input with embedded SVG magnifier and
focus ring, control bar reorganised into divider-separated groups with
the browse-mode toggle rendered via :has() selector, hit cards with
hover-lift + arrow indicator and focus-visible outline, restyled Q/A
badges and score/topic chips, animated loading dots.

Episode page: sticky audio player and sticky aside (top: 130px,
max-height calc'd against viewport). New active-Q&A highlight builds a
sorted index of QA blocks at load time, computes each block's end as
the next block's start (capped at +180s), and on timeupdate/pause
toggles .active on both the body QA block and its aside list item; a
"NOW PLAYING" pill is revealed on .qa.active. Intro-marker also gets
.active. Audio preload bumped from none to metadata so #qa-<id> deep
links can seek without a prior user gesture.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 05:35:55 -07:00
e7ec4a8858 Session log: Discord bot Phase 1 MVP implementation 2026-04-30 20:48:23 -07:00
777ad52803 feat: Discord bot Phase 1 MVP implementation
Implemented Phase 1 of ClaudeTools Discord bot with:

Core Features:
- Discord.py bot with message content intents
- Claude API integration with streaming responses
- Thread-based conversations with context management
- @mention handling with automatic thread creation
- Tool definitions for future ClaudeTools/remediation integration

Architecture:
- bot/main.py: Entry point with Discord client setup
- bot/config.py: Pydantic Settings for environment config
- bot/claude/client.py: Anthropic SDK wrapper with streaming
- bot/claude/tools.py: Tool definitions and system prompt
- bot/handlers/message_handler.py: Discord message handling

Configuration:
- requirements.txt: Python dependencies (discord.py, anthropic, httpx)
- .env.example: Environment variable template
- .gitignore: Sensitive data protection
- README.md: Comprehensive setup and usage guide

Next Steps (Phase 2):
- Implement tool execution (ClaudeTools API client)
- Add user role mapping and permissions
- Implement audit logging

Deployment Target: BEAST (Windows) as NSSM service
Test: @ClaudeTools hello should create thread and stream response

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-30 20:40:24 -07:00
8cf4bfe614 sync: auto-sync from Mikes-MacBook-Air.local at 2026-04-30 19:17:35
Author: Mike Swanson
Machine: Mikes-MacBook-Air.local
Timestamp: 2026-04-30 19:17:35
2026-04-30 19:17:36 -07:00
1f23f66404 sync: auto-sync from DESKTOP-0O8A1RL at 2026-04-30 13:53:29
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-04-30 13:53:29
2026-04-30 13:53:30 -07:00
f20a9628c3 radio: browseable Q&A — /api/qa, /api/audio range streaming, /episode HTML view
Make the radio archive Q&A pairs actually browseable end to end:

- /api/qa list endpoint (year, min_score, exclude_banter, topic_class,
  pagination, sort by air_date or score). Returns the same column shape as
  /api/search Q&A hits.
- /api/audio/{episode_id} streams the MP3 with HTTP Range support so the
  browser <audio> can seek. 206 + Content-Range when ranged, 200 when
  full-file. Returns 404 cleanly when episodes/ tree is absent (Jupiter).
- /episode/{id} HTML transcript view: chronological segments with clickable
  timestamps, Q&A blocks spliced inline (anchor #qa-<id>), intros marked
  inline, right-rail summary. Hash-anchor on load auto-seeks the audio.
- New question_excerpt / answer_excerpt fields on /api/search Q&A hits and
  on /api/qa items: trim leading run-on chatter, take ~300 chars, end on a
  sentence boundary or word boundary with ellipsis.
- Index UI: each Q&A hit now links to /episode/{id}#qa-{qa_id}; new
  "Browse all Q&A" toggle (year selector, sort, append-load 50 per page,
  defaults to min_score=3); FTS snippet replaced with the plain excerpt
  when available.

No new dependencies, no schema changes, no LLM calls. Uses
EPISODES_DIR env (default /data/episodes) — Jupiter compose still only
mounts /data so audio degrades gracefully to 404 there until episodes
are uploaded.
2026-04-30 07:17:48 -07:00
e6d7c293db sync: auto-sync from Mikes-MacBook-Air.local at 2026-04-30 06:24:45
Author: Mike Swanson
Machine: Mikes-MacBook-Air.local
Timestamp: 2026-04-30 06:24:45
2026-04-30 06:24:46 -07:00
6239f9fc3a radio: session log update — index UI exposes classifier filters
Backend min_score/exclude_banter wired through to HTML index. Adds
score badges (1-5 red->green), topic_class pills, dim styling on
banter rows. Live on http://172.16.3.20:8765/. Synced to portable
repo. pscp ENOSPC quirk worked around by plink-stdin streaming.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 06:07:00 -07:00
b9af34fbd8 radio: index UI exposes min_score / exclude_banter + score badges
Adds quality-filter controls to the search UI: a "min score" select
(any/2+/3+/4+/5) and a "hide banter" checkbox. Q/A hits gain a small
color-coded usefulness badge (1-5, red->green) and a topic_class tag
(computer-help, banter, off-topic, promo). Low-score and banter rows
render dimmed by default so they're visible but de-emphasized.

Defaults to "any" + banter visible to preserve existing search habits.
Mike toggles up when he wants quality. URL-encoded params built via
URLSearchParams so empty values don't leak into requests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 05:54:45 -07:00
48c8b311bf radio: session log — portable laptop bundle + /api/db.sqlite deploy
New private Gitea repo `azcomputerguru/radio-archive-portable` for
laptop offline use. Upstream gained /api/db.sqlite for HTTP-only DB
sync (no SSH keys needed). Jupiter container rebuilt + restarted with
the classifier-populated DB; verified end-to-end (200 OK, 60.5 MB,
1,405 classifier rows intact, min_score filter working).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 05:37:01 -07:00
5e3b1a2297 radio: add /api/db.sqlite for offline laptop sync
Streams the read-only archive.db over the same Tailscale-routed port
as the search service. Companion to azcomputerguru/radio-archive-portable
which curl-fetches from this endpoint and runs locally on the laptop.

Disclosure equivalent to /api/search (which already exposes every
transcript), so no auth added. Deployed to Jupiter; verified GET
returns 60 MB SQLite blob with all 1,405 classifier rows intact.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 19:50:50 -07:00
8d4bb16255 radio: session log — Q/A usefulness classifier (Track 1) complete
3.5h run on qwen3:14b processed 1,405/1,407 Q/A pairs (2 failed,
will retry on next invocation). 37% scored 4-5 (useful), 41%
scored 1-2 (banter/promo/off-topic). API filter ready; Jupiter
redeploy pending Mike's manual review.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 17:34:15 -07:00
42688901f9 radio: Q/A usefulness classifier + min_score search filter (Track 1)
Adds an Ollama-based content quality classifier and exposes the
results via the search API. 1,407 existing Q/A pairs were scored
in 3.5h via qwen3:14b (1,405 succeeded, 2 failed).

Distribution: 37% scored 4-5 (useful), 41% scored 1-2 (banter/promo/
off-topic). 43% flagged as banter overall. Default-on filtering at
search time will hide ~half of the noise without losing any real
listener questions.

Files:
- new classify_qa_quality.py: walks qa_pairs, calls Ollama qwen3:14b
  per row, writes usefulness_score/topic_class/is_banter back to DB.
  Idempotent (--rebuild to reprocess), --smoke for sample check, --limit
  for partial runs. Detached run handles 1407 rows in ~3.5h on a 4090.
- server/main.py: /api/search accepts min_score (0-5) and exclude_banter
  query params. NULL scores treat as "include" so unprocessed rows still
  appear. Episode detail endpoint includes the new fields in qa results.

Schema migration in import_to_sqlite.py was made by the same agent run
(visible on the live archive.db: usefulness_score / topic_class /
is_banter columns now exist on qa_pairs).

Local archive.db updated; Jupiter container has NOT been redeployed
yet — that is a separate manual step.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 17:32:41 -07:00
6b63c154d2 sync: auto-sync from GURU-BEAST-ROG at 2026-04-29 13:29:17
Author: Mike Swanson
Machine: GURU-BEAST-ROG
Timestamp: 2026-04-29 13:29:17
2026-04-29 13:29:19 -07:00
e00d4ebeb2 sync: auto-sync from DESKTOP-0O8A1RL at 2026-04-29 09:18:32
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-04-29 09:18:32
2026-04-29 09:18:33 -07:00
a1209b28bb GuruRMM submodule: update with UI_GAPS reference in roadmap
Added cross-reference from FEATURE_ROADMAP.md to UI_GAPS.md tracking document.

Clarifies that features may be backend-complete but UI-incomplete.

Submodule commit: f76051a

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-29 07:27:14 -07:00
394062811c GuruRMM submodule: update to include UI gaps tracking document
Added comprehensive UI_GAPS.md for sprint planning and progress tracking.

Documents 6 major UI gaps (P1-P2):
- Policies dashboard (critical - config mechanism)
- Temperature collection (BUG-001 fix)
- Enrollment management
- Tunnel sessions
- Install reporting
- Organizations management

Each gap includes status, missing components, effort estimates, dependencies.

Submodule commit: a018e7e

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-29 07:26:32 -07:00
01e949db08 GuruRMM submodule: update to include holistic development principles
Updated DESIGN.md with two fundamental principles:
1. Holistic Feature Development - every feature needs full stack (backend, API, UI, docs)
2. AI-Optional Operation - product works without AI agents; AI features are enhancements

Submodule commit: e490307

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-29 07:16:29 -07:00
ba756b49dd GuruRMM submodule: update to include network discovery + collection nodes
Updated GuruRMM roadmap with two major features:
- Network Discovery Node (P2): site-level device discovery and mapping
- Local Collection Node (P2): reduce WAN traffic by local aggregation

Submodule commit: db7d074

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-29 07:07:26 -07:00
519278a664 radio: session log update — Jupiter container live at 172.16.3.20:8765
Append to 2026-04-28-session.md covering the FastAPI/SQLite container
deploy: build + ship + verify, plus credentials, paths, and re-deploy
procedures for both DB updates and source updates.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 06:05:34 -07:00
71ada136a8 radio: FastAPI/SQLite query server, deployed to Jupiter
Read-only HTTP layer over archive.db. Endpoints: /api/stats,
/api/episodes, /api/episodes/{id}, /api/episodes/{id}/transcript,
/api/search (FTS5 over segments + qa_pairs, bm25-ranked, snippets),
/api/callers. Single-file HTML index with debounced search UI.

Deployed: Jupiter (Unraid Docker), bound to 172.16.3.20:8765, LAN only.
Container path: /mnt/user/appdata/radio-archive/{app,data}.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 06:00:22 -07:00
90b1ffff8b radio: session log — full archive imported (572 ep / 482.7h / 57.7 MB DB)
Execution-only follow-on to 2026-04-27. Both batch passes done (519+53,
0 errors), import_to_sqlite.py run incrementally to bring archive.db
to final state. Next step: Jupiter Docker container deploy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 05:30:08 -07:00
82940d96d7 radio: utf-8 transcript writes + sqlite archive importer + session log
- src/transcriber.py: open transcript.{json,txt,srt} with encoding="utf-8".
  Windows cp1252 default crashed on Whisper output containing U+2044.
- import_to_sqlite.py: new. Walks archive-data/transcripts, builds
  archive.db (5 tables + 2 FTS5 virtual tables, sha256-keyed idempotency).
  20.5 MB / 208 episodes at smoke-test time, 1.9s rebuild.
- batch_process.py: tracked from prior session — full-archive batch with
  resumable transcribe/diarize/intros/qa pipeline.
- .gitignore: archive-data/ and logs/.

Session log: 2026-04-27-archive-batch-and-sqlite-import.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:38:02 -07:00
488bf5849e radio: attach caller names to Q&A pairs from transcript intros
QAPair gets caller_name and caller_role fields populated by a new
attach_caller_names(pairs, transcript_segments) helper. For each pair,
finds the active opening intro at the question_start time (8s forward
tolerance, no backward limit — a caller's call can run for 10+ minutes
and the intro happens once at the start) and attaches the speaker name.

Validation on 9-episode test set:
  19/19 Q&A pairs (100%) now have caller names attached.

Examples of corrections from oracle attribution:
  2018-s10e18 @ 73:36  Christopher (was misattributed to "Tara")
  2015-s7e19 @ 35:45   William     (was misattributed to "Tara")
  2010-05-08-hr1       Jackie x3, Bruce
  2012-03-10-hr1       Adam x2
  2016-s8e43           John, Doug
  2017-s9e30           Tom, Denise x3, Charlie

speaker_oracle.py: adds speaker_at(time, intros) helper used both by the
existing resolve_speakers() and the new caller-name attachment. Also
adds the "let's fit/bring/put X in/on" intro pattern variant (caught
Charlie at 70:21 in 2017-s9e30 that "talk to X" missed).

download_full_archive.py: SSH keepalive every 30s + per-file retry-on-
failure (up to 3 attempts with reconnect). Earlier run hung on a dead
connection at file 109 of 589 with no recovery; restarted run is now
running at ~10 MB/s vs ~2-3 MB/s before.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 16:55:31 -07:00
1b574caba4 radio: transcript-driven speaker name resolution (oracle)
New module src/speaker_oracle.py extracts speaker introductions from
transcripts ("let's talk to William", "we have Clay from the Nerd Junkies",
"in Tara's place, we have Clay", "thanks for the call <name>") and binds
them to non-HOST diarization turns. Pure post-pass on diarization JSONs,
no audio processing — corrects audio-only cosine errors using Mike's
deterministic on-air announcements.

Algorithm:
- Extract intros: regex patterns for caller pickups, guest intros,
  fill-in announcements, caller closes. Case-strict (rejects mid-sentence
  lowercase matches), with a blacklist of common false-positive words.
  Deduplicates same-name intros within 5s.
- Resolve speakers: for each non-HOST turn, find the LATEST opening intro
  at or before turn.start (with 8s forward tolerance for boundary slop).
  Later intros implicitly close earlier callers, so the most recent
  intro wins. No artificial lookback limit (callers can talk for 10+ min).
- Falls back to caller_close patterns within 30s after a turn ends.

Validation on 9-episode test set:
  2018-s10e18: Christopher 190s correctly named (was mislabeled "Tara")
  2012-06-09 : Kay 160s correctly named (was mislabeled "Tara")
  2015-s7e19 : Clay 45s as fillin for Tara, William 40s as caller
  2016-s8e43 : Charles 630s, Bruce 210s, John 205s — most callers named
  2017-s9e30 : Denise 295s, Tom 115s, Elaine 85s, Jeff 10s
  Many other callers across all episodes correctly named.

Remaining unnamed CO-HOST/CALLER (~5-10% of non-HOST time) are real
co-host banter or callers without explicit Mike-introductions.

benchmark.py: adds Phase 2.5 "Name Resolution" between diarization and
Q&A extraction. Prints named-speaker breakdown per episode. Doesn't
modify diarization JSONs (resolution is computed on demand).

Next step: feed named turns into qa_extractor so Q&A pairs get caller
name attached for searchability. Also: bootstrap recurring-speaker
profiles (Tara, Tony, Rob, Randall, producers) by accumulating
intro-tagged windows across the full archive once download completes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 16:48:16 -07:00