TypeScript:
- menu_ts.ts split into menu.ts, content.ts, popup.ts and xmltv.ts; the
other files drop their _ts suffix. Bundle order fixed in ts/tsconfig.json.
- All 94 string event handlers (setAttribute("onclick", "javascript: ..."))
replaced with addEventListener closures. changeButtonAction, which
rewrote an onclick attribute from select values, is gone.
- Settings rows are generated from one SETTINGS_FIELDS table instead of
~20 copy-pasted blocks; rendered HTML is byte-identical to before.
saveSettings now serialises password inputs, so a changed Plex token is
actually sent (the server treats the mask as unchanged).
- createLayout rebuilds the menu list only when the set of visible items
changes, so focus in the menu survives a refresh.
- announce()/alertUser(): alerts are mirrored into an aria-live region.
- Filter popup offers a third type, Regular Expression (regex-filter), and
the filter table labels it. Playlist popups get a Buffer select
(default / none / xTeVe / FFmpeg / VLC) saved as the playlist's
"buffer" parameter; the tuner field stays editable when the
playlist's own buffer is active.
Tests: tests/ holds 27 jsdom tests (Node's built-in runner, jsdom pinned)
that load the built bundle with a fixture server payload: menu visibility
rules, mapping table renders names as text, settings panel fields, popup
flows, sorting, bulk select, layout refresh keeps nodes, live region,
regex option, buffer select. npm test runs in the Drone webui-check step.
README-DEV documents the layout and the test workflow.
- .drone.yml: two command strings contained ": " and were parsed as maps
by Drone's YAML loader ("cannot unmarshal !!map into string"). Quoted.
- Filters: new type "regex-filter". The rule is a Go regular expression
tried against the channel name, the group title and the raw attribute
line; case-insensitive unless the filter is marked case sensitive.
Patterns are validated when the filter is saved and when rules are
rebuilt, and compiled once (cached). The two fixed {include}/!{exclude}
patterns are compiled at package level instead of per stream.
- Per-playlist buffer: a playlist's "buffer" parameter ("-", "xteve",
"ffmpeg", "vlc") overrides the global setting for that playlist in
the stream handler, the buffer start, the tuner lookup and the external
process buffer. Anything else falls back to the global setting.
(UI controls for both follow with the Phase 5 frontend work.)
- Tests: TestRegexFilter, TestBufferModeFor.
Go:
- staticcheck 399 -> 0 with staticcheck.conf (style checks ST1000/1003/
1005/1016/1020/1021/1022 excluded; error strings are shown in the UI).
- io/ioutil and rand.Seed removed; CloseNotifier kept with a lint-ignore
until the Phase 2 context rewrite.
- Dead code deleted: Auto handler, getStreamByChannelID, updateXEPG,
indexOfInt, jsonToMapInt64, removeOldSystemData, randomTime, and the
commented-out blocks in struct-buffer.go and internal/authentication.
- Duplicates folded: cacheImagesInBackground(), one addErrorToStream().
- Bugs found by SA4006/SA5001: os.Create handle leaked per ffmpeg segment
(buffer.go), http.NewRequest error unchecked (buffer.go), xepg.json
migration wrote null on read error (migrate.go), WriteUserData errors
silently dropped (authentication.go), defer Close before error check
(buffer.go, toolchain.go). checkFilePermission results were discarded;
an unwritable config or temp dir is now fatal at start-up.
- gofmt applied repo-wide; Drone runs gofmt check and staticcheck.
Docker:
- Entrypoint starts as root, applies PUID/PGID (falls back to XTEVE_UID/
XTEVE_GID, then image defaults), fixes config ownership only when it
differs, then drops to xteve via su-exec. --user starts skip all of it.
- /xteve removed from LEGACY_CONFIG_DIRS (it is the parent of the default).
- mwader/static-ffmpeg pinned to 7.1.1; VOLUME /xteve/config.
- Compose files pull registry.coadcorp.com/nathan/xteve:latest, use
PUID/PGID/TZ, and explain that SSDP needs host networking.
- .dockerignore excludes the npm toolchain (bundle stays in html/js).
Docs: README rewritten for the fork (about, registry, compose, env vars,
security notes); README-DEV gains a container section.
- html/embed.go embeds html/ (pages, css, img, js, video); src/assets.go
serves it, with os.DirFS("html") under -dev. Static assets get an ETag
and Cache-Control: no-cache; HTML pages are still templated (only the
login error message is substituted now).
- Delete the generated src/webUI.go (783 KB base64), src/html-build.go and
cmd/webui-gen; Dockerfile no longer runs a generator.
- Language layer removed: 254 {{.x}} placeholders inlined as English
strings in ts/*.ts and the two auth pages; html/lang/en.json, the
LanguageUI struct and the 'language' setting are gone.
- ts/tsconfig.json + package.json pin typescript 5.9.3; the seven sources
compile (ES2020, global scripts) into one committed html/js/app.js.
Ten unreferenced legacy scripts under html/js/ deleted; all pages load
js/app.js.
- Fix the six type errors that blocked a clean compile, including a real
bug: a missing semicolon in the search shortcut handler made the code
call the result of preventDefault(), so the shortcut threw instead of
focusing the search box.
- /healthz liveness endpoint; Dockerfile healthcheck and README use it.
- Drone: go vet, and a webui-check step that rebuilds the bundle and fails
if the committed app.js is stale.
- README-DEV.md documents build, UI toolchain, -dev, versioning, CI.
- Delete BinaryUpdate, internal/up2date, GitHub/Update structs and the
xteveAutoUpdate / update.url settings (UI rows, en.json, defaults).
Settings-schema migrations kept and moved to src/migrate.go.
- Drop kardianos/osext dependency.
- xteve.go version 0200 -> 0201 to match changelog; Drone now fails on drift.
- go.mod go 1.27.1; Dockerfile and Drone golang images pinned to 1.27.1.
- Fix four go vet unreachable-code warnings.
- .gitignore: .gocache/, agent.md, skill.md. .dockerignore: build context
no longer includes caches, ts/, tasks/ or markdown except the changelog.
- Drone: publish :latest only from master; other branches publish a
branch-named tag so a feature push cannot replace the deployed image.
- Add tasks/improvement-plan.md and tasks/todo.md.
- Regenerate src/webUI.go.