README.md

July 28, 2026 · View on GitHub

Tripbot loves you :robot: :heart:

GoDoc Go Report Card GitHub Super-Linter Version Build Status License

This is the source code to whereisdana.today, a 24/7 interactive slow-tv art project streaming on Twitch and YouTube.

If you like it, please consider subscribing to my channel on Twitch.tv. Thanks for watching!

-Dana (dana.lol)

How it all works

There are two main components built from this repo, each running in its own container: the chatbot itself, which listens for user commands, and an overlay server for on-screen graphics. The dashcam video playback lives in its own repo (adanalife/playout); the chatbot controls it over NATS and reads the currently-playing clip over HTTP. The scene compositing and streaming to the platforms (Twitch and YouTube) is handled by OBS, which lives in its own repo (adanalife/obs) and pulls the playback output over RTSP — so the bot and video server can still be split across machines. The chatbot still controls that OBS over its WebSocket (start/stop, health watchdog). The admin UI lives in a separate private repo (adanalife/tripbot-console), and platform API calls route through a private adanalife/platform-gateway service.

The general flow of information looks like this:

A diagram showing the different components

For more detail, check out Tripbot, the Adventure Robot.

Developing on the host (quick start)

Day-to-day Go work happens directly on the host. You'll need:

# run the unit tests in docker (postgres included, so the DB-backed tests run)
task test

# or call go directly through mise — the repo is pure Go, so the tests run on
# the host with no extra setup; the DB-backed ones skip without postgres
mise exec -- go test ./...
mise exec -- go build ./cmd/tripbot

Running the full stack locally

The full application stack (bot + dependencies) runs on the local k3d dev cluster managed from the infra repotask k8s:dev:cluster:up brings it up. See that repo's README for the cluster lifecycle targets.

For DB-backed tests you only need postgres, which task test spins up on demand via the docker-compose testing stack (infra/docker/docker-compose.testing.yml) — no manual setup required.

Changelog

Changelog entries are managed with towncrier. Every PR into main adds a fragment describing its user-facing change — a changelog CI check enforces this (label a PR skip-changelog for dependabot bumps, CI-only tweaks, or pure refactors that warrant no entry).

A fragment is a small markdown file in changelog.d/ named <PR-number>.<type>.md, e.g. 889.fix.md. Its contents are the entry prose (bold lead-in sentence, then detail — match the existing CHANGELOG.md style); the PR link is added automatically.

You won't know the PR number when branching, so run task changelog:add TYPE=<type> — it drops a +-prefixed placeholder (towncrier's issue-less convention, e.g. +fix.fix.md), and the changelog-number workflow renames it to <PR-number>.<type>.md on first push. No SKIP_CHANGELOG dance needed.

# scaffold one (opens $EDITOR); or just create the file by hand
task changelog:add PR=889 TYPE=fix

# preview the assembled notes
task changelog:preview

Types map to the changelog's component sections: gateway, chatbot, onscreens, playout, console, fix, deploy, ci, cleanup, misc, plus summary (a lead paragraph for the release, named +summary.summary.md — no PR number).

Releases

Releases are trunk-based: release-please maintains a standing release PR on main with the next version, computed from the conventional commits since the last release. The release PR also carries the collated changelog (built from the changelog.d/ fragments) and the bumped + re-synthed prod deploy manifests. Merging the release PR is the release: it tags vX.Y.Z, publishes the GitHub Release, kicks off the multi-arch image builds, and deploys prod (prod-1 autosyncs from main).