Backend:
- extract.go: listTags() navigates to volume, runs akaiutil lstags
- extract.go: parseTags() parses tag name/index from lstags output
- serve.go: GET /api/disk/partitions — list partitions on an ISO
- serve.go: GET /api/disk/volumes — list volumes on a partition
- serve.go: GET /api/volume/tags — list tags on a volume
Web UI:
- Tag Viewer section with ISO path input and Browse button
- Partition selector buttons
- Volume grid with click-to-select
- Tag chips with color-coded dots (20-color palette)
Tests:
- 6 parseTags tests (basic, spaces, defaults, no tags, empty, no-type)
- 1 listTags integration test
- 4 API endpoint tests (partitions, missing-ISO, missing-params, tags)
Karpathy: read-only view first — no write operations yet (settagi, clrtagi)
check-toolchain.sh now covers:
- golangci-lint
- npm
- web/ui node_modules (JS deps)
- electron node_modules (electron deps)
New install-all task (scripts/install-deps.sh):
- mise install (go, node, golangci-lint)
- cd web/ui && npm install
- cd electron && npm install
Usage:
mise run check-toolchain # audit everything
mise run install-all # install all deps from scratch
Redesigned WAV Browser as a structured Sample Library with card layout:
- WAVs grouped by library (ISO name) and program (volume name)
- Library cards with collapsible headers showing program/sample counts
- Program sections within each library
- Sample cards in a compact grid with play-on-click
Updated playWav to show a clean sample name in the player bar,
hide the player when playback ends, and use sample-card selectors
for active-state highlighting.
Clean display names (underscores → spaces, stripped .wav extensions)
doExtract() only checked data.message, so JSON responses with
error key (e.g. 'no ISO files found') would show green success.
Now checks data.error first and displays it in red.
Handle ListWavs now uses filepath.WalkDir to find .wav files
in all subdirectories. Returns relative paths (e.g. Kicks/kick.wav).
Serves them correctly via /wavs/ prefix.
Fixed: WalkDir swallows root errors differently than ReadDir —
now detects and reports non-existent root directory errors.
Added test for recursive subdirectory traversal.
Some archive.org file names include directory prefixes
(e.g. "ZERO-G - Deepest India/vocal.iso"). MkdirAll only
created the output root, not intermediate directories.
Added filepath.Dir(MkdirAll) in both downloadFile (CLI)
and handleAPIDownload (web).
Docker creates host-side bind-mount directories as root:root.
Pre-creating them with make init (or mise run init) ensures
they exist with the user's ownership before docker compose
touches them. docker-up now depends on init.
extract.go replaces the bash script with idiomatic Go:
- akaiutil process communication via stdin/stdout pipes
- partition enumeration (df output parsing)
- volume enumeration (dir output parsing per partition)
- sample2wavall per volume with WAV count aggregation
runAkaiutil is a package-level var — tests stub it with canned
output to verify parsing without a real akaiutil binary or ISO.
Removed: findScript(), -tool flag on extract, os/exec from main.go
Kept: extract_wavs.sh as a standalone utility (no longer called)
cmdExtract and handleAPIExtract were missing os.MkdirAll calls
while cmdDownload, cmdPipeline, and handleAPIDownload all had
them. The bash script creates dirs internally but this is not
robust — create dirs in Go before shelling out.
Closes#13
When binding to 0.0.0.0 (--host 0.0.0.0), print "localhost" and
"<host-ip>" URLs instead of the raw 0.0.0.0 address. Also handles
nil TCPAddr.IP to avoid the ":::" garbled display in Docker.
- Fix#11: Guard bcopy/bzero declarations with _VISUALCPP in commoninclude.h
to avoid redefinition errors on macOS where <strings.h> provides them
- Fix#12: Add --host flag to serve command, default 127.0.0.1
Docker now binds to 0.0.0.0 so Colima can reach the server from host
- Also fix truncate() panic when n < 3
- serve.go: embedded web UI (embed.FS), REST API endpoints for
search, list, download (SSE progress), and WAV extraction
- main.go: added serve subcommand and flag registration
- web/ui: vanilla JS frontend with search cards, download queue,
extract controls; dark theme, zero dependencies
- electron/: Electron wrapper that spawns fetch serve as sidecar,
reads port from stdout, creates BrowserWindow; electron-builder
config for macOS .app bundle with akaiutil + script as resources
Refs #1, #9