JioTV Go is a single Go CLI/server that wraps JioTV Android APIs for live TV, catch-up, EPG, web playback, and IPTV/M3U clients. The server uses Fiber; the web UI is server-rendered HTML with vanilla JavaScript and Tailwind CSS/DaisyUI.
main.gois the only executable. Itsurfave/cli/v2startup hook loads config, logger, persistent store, and URL encryption before command dispatch.cmd/owns CLI commands and the Fiber composition root.cmd/jiotv_go.go:JioTVServerconfigures middleware, embedded templates/static files, routes, scheduler, and server listen/TLS.internal/handlers/owns HTTP behavior.pkg/owns JioTV API access, credentials, persistence, EPG generation, URL encryption, and scheduling.- HLS flow:
/live/...β token refresh βpkg/television.Television.Liveβ encrypted local render URL β manifest rewrite/proxy handlers (/render.m3u8,/render.ts,/render.key). - DRM flow:
/play/...β MPD/license proxy URLs β MPD rewrite β DASH/license proxy handlers. Do not expose or bypass the encrypted upstream-URL flow. - Runtime state is intentionally global:
config.Cfg,handlers.TV,utils.Log, andstore. Preserve startup order and update shared state through existing lifecycle helpers; do not construct per-request television clients.
cmd/β CLI implementations, Fiber setup, login, EPG, background process support.internal/config/βJioTVConfigschema and file/environment loading.internal/handlers/β Fiber handlers for live, catch-up, DRM, EPG, auth, and UI.internal/middleware/β custom Fiber middleware.internal/utils/β shared handler error, proxy, URL, and cache helpers.pkg/television/β concretefasthttpJioTV API client and channel/custom-channel models.pkg/store/β mutex-protected TOML runtime store; credentials/device state go here.pkg/secureurl/,pkg/epg/,pkg/scheduler/,pkg/utils/β URL protection, EPG jobs, scheduling, and shared auth/HTTP utilities.web/views/β embedded Go HTML templates;web/static/internal/β browser JS and Tailwind source/output;web/test/β Jest tests.configs/β example YAML/TOML/JSON config files; pass one explicitly with--config.scripts/β release/install utilities, not the regular developer task runner.
.agents/skills/change-configuration/SKILL.mdβ use for anyJIOTV_*or JSON/YAML/TOML configuration change; it defines the required schema, defaults, examples, consumers, and tests to synchronize..agents/skills/diagnose-playback/SKILL.mdβ use for live, catch-up, HLS, DASH/DRM, browser, or IPTV playback failures; it defines the hop-by-hop evidence and token-scope checks.
Run from repository root unless stated otherwise:
# Dependencies and backend build
go mod tidy
go build -o build/jiotv_go .
# Backend tests
go test -v ./...
# Frontend dependencies, generated CSS, and tests
cd web && npm ci
cd web && npm run build
cd web && npm test -- --watchAll=false --ci
# Local server; debug enables template reload and stdout logs
JIOTV_DEBUG=true JIOTV_LOG_TO_STDOUT=true go run main.go serve --host 127.0.0.1 --port 5001
# Built server
./build/jiotv_go serve --host 127.0.0.1 --port 5001Use go test ./path/to/package -run '^TestName$' for focused Go work. Use cd web && npm run test:coverage for optional frontend coverage. No Makefile or project-local lint command exists.
- Format Go with
gofmt; use package-local*_test.gotests namedTestXxx. Prefer table cases andt.Runwhere existing tests do. - Fiber handlers use
func(*fiber.Ctx) error. Useinternal/utilsJSON error helpers for client errors; propagate/wrap operational errors with%wrather than inventing response formats. - Reuse
pkg/utilsrequest helpers andfasthttpAcquire*/Release*pairs. Never retain pooled request/response objects. - Configuration is a tagged global schema: add runtime settings to
internal/config.JioTVConfigwith YAML, JSON, TOML, andJIOTV_*tags. - No dependency-injection/service-interface layer: concrete package types and initialized globals are established patterns. Keep additions consistent unless a real isolation need exists.
- Shared mutable state requires existing synchronization: mutexes for token/store updates,
singleflightfor duplicate refreshes,sync.Mapplus TTL for caches, andRWMutexfor custom channels. Preserve these boundaries. - Frontend is vanilla JS. Follow existing
web/static/internal/*.jsmodule patterns and Tailwind/DaisyUI utility styling; do not introduce a frontend framework. - Runtime credentials/data belong under
JIOTV_PATH_PREFIX(default$HOME/.jiotv_go) and must remain untracked. Never commit.env, credentials, generated runtime state, or logs.
main.goβ CLI entry point and global initialization order.cmd/jiotv_go.goβ Fiber server composition and route registration.internal/config/config.goβ configuration schema/loading.internal/handlers/handlers.goβ handler initialization and HLS/channel behavior.internal/handlers/auth.goandinternal/handlers/drm.goβ credential refresh and DRM proxy lifecycle.pkg/television/television.goβ JioTV upstream client.pkg/store/store.goβ persistent runtime state.pkg/secureurl/secureurl.goβ upstream URL protection.web/package.jsonβ npm scripts and frontend dependencies.web/static/internal/input.cssβ Tailwind v4/DaisyUI 5 input;tailwind.cssis its committed generated output.web/jest.config.jsβ Jest/jsdom and frontend coverage scope.
- Go module:
github.com/jiotv-go/jiotv_go/v3. - Frontend package manager: npm with lockfile v3. Use
npm cifor reproducible installs. CI uses Node LTS; no repository Node version pin exists. - Frontend stack is Tailwind CSS 4 with
@tailwindcss/cliand DaisyUI 5. Configuration is CSS-first inweb/static/internal/input.css; there is no Tailwind/PostCSS config file. web/static/internal/tailwind.cssis a versioned, minified build artifact. Rebuild and commit it after changinginput.css, template class usage, or frontend dependencies.- Docker is optional local tooling:
docker-compose.ymlusesdev.Dockerfile, mounts the checkout, reads.env, and runs withJIOTV_DEBUG=true. Normal local Go development is simpler. - Do not casually run
scripts/build-binaries.sh,scripts/increment-version.sh, or installers; they are release/end-user tooling and may cross-build, alterVERSION, or mutate shell setup.
- Backend: standard Go
testingtests are colocated undercmd/,internal/, andpkg/; Testifyassertis optional, not required. Keep tests offline and deterministic: usehttptestor injected clients for upstream APIs, restore mutated globals and caches, and do not run shared-state tests in parallel. - Frontend: Jest with jsdom; tests live in
web/test/*.test.jsand use DOM/mocked-browser APIs. - CI quality gate:
go mod tidy,go test -v ./..., thencd web && npm ci && npm test -- --watchAll=false --ci. - Add or update behavior-focused tests for changed contracts. No numeric coverage threshold exists; Jest coverage covers
web/static/internal/**/*.js, while Go coverage is not configured. - No ESLint, Prettier, golangci-lint, Staticcheck, or local
go vetworkflow is declared..deepsource.tomlconfigures external Go, Docker, and shell analysis.
- The default and PR target branch is
develop;mainis the release branch. Open normal feature and fix PRs againstdevelop. - Follow Conventional Commits using the repository's established types:
feat:,fix:,docs:,test:,chore:, andrefactor:. Keep each commit to one logical change. - Before a PR, run the checks relevant to every changed area. Backend changes require
go test -v ./...; frontend changes additionally followweb/AGENTS.md; configuration and user-facing behavior changes require matching docs/examples. - Do not manually bump
VERSION, create release tags, or run release scripts for a normal change. Pushes tomaintrigger.github/workflows/release.yml, which updatesdevelop, builds release binaries, and publishes tags/releases.