Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
8513b38
Implement reportAccountAction, fix bug in auth flow between sonos and…
simojenki Oct 25, 2025
14204a6
Dummy implementation of /report/timePlayed as sonos s2 doesnt send th…
simojenki Oct 30, 2025
019d93f
Support for S2 scrobble via reporting endpoint
simojenki Oct 31, 2025
b9352c5
Ability to disable festivals for testing
simojenki Oct 31, 2025
e8429a2
Node on 22/bookworm, upgrade libs. (#231)
simojenki Nov 7, 2025
8143455
Rollback ts-md5 upgrade as breaks startup
simojenki Nov 7, 2025
200092a
Update README for CF documentation (#232)
simojenki Nov 9, 2025
4499a3e
Ability to specify login page style: classic, navidrome-ish, wkulhane…
simojenki Nov 10, 2025
6335b4c
Remove default value for BNB_SECRET, make it mandatory config. Remov…
simojenki Nov 11, 2025
6e78372
Add temporary ability to debug auth headers for CF support
simojenki Nov 29, 2025
2fb057d
Bump some libs
simojenki Nov 29, 2025
e526fef
Improve debug message
simojenki Nov 29, 2025
cc53bec
Use api key on /stream rather than full jwt to reduce length
simojenki Dec 3, 2025
f3a38a0
When returned cover art, if content type from upstream is invalid ret…
simojenki Jan 20, 2026
229a411
Cleanup smapi, fixed playlists so work in both S1 and S2
simojenki Jan 21, 2026
58ab637
Refactor interaction between subsonic classes (#228)
simojenki Jan 21, 2026
e22ef0e
Test case for different image sizes when using image replacement patt…
simojenki Jan 23, 2026
169e2e1
Add 1000x1000 as an image size
simojenki Jan 24, 2026
1bd17ee
Refactor how login tokens are found between soap and request headers …
simojenki Jan 28, 2026
5051f36
Updated docs for Sonos S2 support (#233)
simojenki Feb 7, 2026
05e6371
Fix incorrect documentation
simojenki Feb 7, 2026
a2e3633
Bump jws (#242)
dependabot[bot] Feb 7, 2026
0fc1c37
Bump qs from 6.14.0 to 6.14.1 (#243)
dependabot[bot] Feb 7, 2026
f311fae
Bump lodash from 4.17.21 to 4.17.23 (#244)
dependabot[bot] Feb 7, 2026
1055e44
Bump axios from 1.13.1 to 1.13.5 (#247)
dependabot[bot] Feb 11, 2026
4f1072f
Update README.md
simojenki Feb 11, 2026
c7e5975
Bump qs from 6.14.1 to 6.14.2 (#248)
dependabot[bot] Feb 14, 2026
55dd461
Bump minimatch (#250)
dependabot[bot] Mar 2, 2026
064bd3f
Bump underscore from 1.13.7 to 1.13.8 (#251)
dependabot[bot] Mar 4, 2026
217afeb
Remove DEBUG_CF env var flag now that CF tunnels are working
simojenki Mar 20, 2026
75cc0cf
Additional tests cases for non standard https port url building
simojenki Mar 20, 2026
907987b
Bump picomatch (#256)
dependabot[bot] Mar 26, 2026
ff9de5a
Bump handlebars from 4.7.8 to 4.7.9 (#257)
dependabot[bot] Mar 27, 2026
dc956c8
Bump path-to-regexp from 8.3.0 to 8.4.0 (#258)
dependabot[bot] Mar 28, 2026
50da3f8
Bump @xmldom/xmldom (#259)
dependabot[bot] Apr 1, 2026
274e892
Bump axios from 1.13.5 to 1.15.0 (#266)
dependabot[bot] Apr 14, 2026
977a5bf
Fix flaky date tests caused by UTC vs local timezone mismatch (#263)
AliceGrey Apr 14, 2026
b3b0574
Bump follow-redirects from 1.15.11 to 1.16.0 (#267)
dependabot[bot] Apr 14, 2026
2781ec5
Modernize CI and speed up Docker build (#264)
AliceGrey Apr 14, 2026
831e0f5
Pr 265 (#270)
simojenki Apr 17, 2026
8b4fab5
Bump @xmldom/xmldom (#271)
dependabot[bot] Apr 23, 2026
88b482f
claude (#268)
simojenki May 6, 2026
1545183
Feature/pr 262 (#273)
simojenki May 8, 2026
14c35bf
debug log on transcode
simojenki May 8, 2026
5f20019
Add BNB_SUBSONIC_TRANSCODE config to gate OpenSubsonic transcoding
simojenki May 8, 2026
39faa36
Remove BONOB_ legacy config key support
simojenki May 8, 2026
3448ab6
use podman rather than docker in devcontainer (#274)
simojenki May 13, 2026
fd8f3b1
Bump qs from 6.14.2 to 6.15.2 (#276)
dependabot[bot] May 24, 2026
35753b7
Bump ws from 8.18.3 to 8.21.0 (#277)
dependabot[bot] May 24, 2026
2179241
Load sonos config conditionally on BNB_SONOS_ENABLE_S1 (#278)
simojenki Jun 15, 2026
e46d40b
Bump form-data from 4.0.5 to 4.0.6 (#281)
dependabot[bot] Jun 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"permissions": {
"allow": [
"Bash(awk *",
"Bash(npx jest *)",
"Bash(node *)",
"Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\(json.dumps\\(d.get\\('jest', {}\\), indent=2\\)\\)\")"
]
}
}
34 changes: 29 additions & 5 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
FROM node:22-bullseye
FROM node:22-bookworm

ENV DEBIAN_FRONTEND=noninteractive

LABEL maintainer=simojenki

Expand All @@ -8,9 +10,31 @@ EXPOSE 4534
RUN apt-get update && \
apt-get -y upgrade && \
apt-get -y install --no-install-recommends \
containernetworking-plugins \
jq \
g++ \
git \
libvips-dev \
python3 \
make \
git \
g++ \
vim
podman \
python3 \
sudo \
tzdata \
vim && \
ln -fs /usr/share/zoneinfo/Australia/Melbourne /etc/localtime && \
dpkg-reconfigure --frontend noninteractive tzdata && \
apt-get clean

RUN echo "node ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/node

RUN mkdir -p /home/node/.config/containers

RUN cat > /home/node/.config/containers/storage.conf <<EOF
[storage]
driver = "vfs"
EOF

ENV BUILDAH_ISOLATION=chroot
ENV _CONTAINERS_USERNS_CONFIGURED=""

USER node
158 changes: 158 additions & 0 deletions .devcontainer/claude-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#!/bin/bash

set -e

# Parse command line arguments
TARGET="$1" # Optional target parameter

# Validate target if provided
if [[ -n "$TARGET" ]] && [[ ! "$TARGET" =~ ^(stable|latest|[0-9]+\.[0-9]+\.[0-9]+(-[^[:space:]]+)?)$ ]]; then
echo "Usage: $0 [stable|latest|VERSION]" >&2
exit 1
fi

GCS_BUCKET="https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases"
DOWNLOAD_DIR="$HOME/.claude/downloads"

# Check for required dependencies
DOWNLOADER=""
if command -v curl >/dev/null 2>&1; then
DOWNLOADER="curl"
elif command -v wget >/dev/null 2>&1; then
DOWNLOADER="wget"
else
echo "Either curl or wget is required but neither is installed" >&2
exit 1
fi

# Check if jq is available (optional)
HAS_JQ=false
if command -v jq >/dev/null 2>&1; then
HAS_JQ=true
fi

# Download function that works with both curl and wget
download_file() {
local url="$1"
local output="$2"

if [ "$DOWNLOADER" = "curl" ]; then
if [ -n "$output" ]; then
curl -fsSL -o "$output" "$url"
else
curl -fsSL "$url"
fi
elif [ "$DOWNLOADER" = "wget" ]; then
if [ -n "$output" ]; then
wget -q -O "$output" "$url"
else
wget -q -O - "$url"
fi
else
return 1
fi
}

# Simple JSON parser for extracting checksum when jq is not available
get_checksum_from_manifest() {
local json="$1"
local platform="$2"

# Normalize JSON to single line and extract checksum
json=$(echo "$json" | tr -d '\n\r\t' | sed 's/ \+/ /g')

# Extract checksum for platform using bash regex
if [[ $json =~ \"$platform\"[^}]*\"checksum\"[[:space:]]*:[[:space:]]*\"([a-f0-9]{64})\" ]]; then
echo "${BASH_REMATCH[1]}"
return 0
fi

return 1
}

# Detect platform
case "$(uname -s)" in
Darwin) os="darwin" ;;
Linux) os="linux" ;;
MINGW*|MSYS*|CYGWIN*) echo "Windows is not supported by this script. See https://code.claude.com/docs for installation options." >&2; exit 1 ;;
*) echo "Unsupported operating system: $(uname -s). See https://code.claude.com/docs for supported platforms." >&2; exit 1 ;;
esac

case "$(uname -m)" in
x86_64|amd64) arch="x64" ;;
arm64|aarch64) arch="arm64" ;;
*) echo "Unsupported architecture: $(uname -m)" >&2; exit 1 ;;
esac

# Detect Rosetta 2 on macOS: if the shell is running as x64 under Rosetta on an ARM Mac,
# download the native arm64 binary instead of the x64 one
if [ "$os" = "darwin" ] && [ "$arch" = "x64" ]; then
if [ "$(sysctl -n sysctl.proc_translated 2>/dev/null)" = "1" ]; then
arch="arm64"
fi
fi

# Check for musl on Linux and adjust platform accordingly
if [ "$os" = "linux" ]; then
if [ -f /lib/libc.musl-x86_64.so.1 ] || [ -f /lib/libc.musl-aarch64.so.1 ] || ldd /bin/ls 2>&1 | grep -q musl; then
platform="linux-${arch}-musl"
else
platform="linux-${arch}"
fi
else
platform="${os}-${arch}"
fi
mkdir -p "$DOWNLOAD_DIR"

# Always download latest version (which has the most up-to-date installer)
version=$(download_file "$GCS_BUCKET/latest")

# Download manifest and extract checksum
manifest_json=$(download_file "$GCS_BUCKET/$version/manifest.json")

# Use jq if available, otherwise fall back to pure bash parsing
if [ "$HAS_JQ" = true ]; then
checksum=$(echo "$manifest_json" | jq -r ".platforms[\"$platform\"].checksum // empty")
else
checksum=$(get_checksum_from_manifest "$manifest_json" "$platform")
fi

# Validate checksum format (SHA256 = 64 hex characters)
if [ -z "$checksum" ] || [[ ! "$checksum" =~ ^[a-f0-9]{64}$ ]]; then
echo "Platform $platform not found in manifest" >&2
exit 1
fi

# Download and verify
binary_path="$DOWNLOAD_DIR/claude-$version-$platform"
if ! download_file "$GCS_BUCKET/$version/$platform/claude" "$binary_path"; then
echo "Download failed" >&2
rm -f "$binary_path"
exit 1
fi

# Pick the right checksum tool
if [ "$os" = "darwin" ]; then
actual=$(shasum -a 256 "$binary_path" | cut -d' ' -f1)
else
actual=$(sha256sum "$binary_path" | cut -d' ' -f1)
fi

if [ "$actual" != "$checksum" ]; then
echo "Checksum verification failed" >&2
rm -f "$binary_path"
exit 1
fi

chmod +x "$binary_path"

# Run claude install to set up launcher and shell integration
echo "Setting up Claude Code..."
"$binary_path" install ${TARGET:+"$TARGET"}

# Clean up downloaded file
rm -f "$binary_path"

echo ""
echo "✅ Installation complete!"
echo ""
9 changes: 9 additions & 0 deletions .devcontainer/devcontainer-lock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"features": {
"ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {
"version": "1.0.5",
"resolved": "ghcr.io/anthropics/devcontainer-features/claude-code@sha256:cfc2e7d3e9fd3b9b01f8d5cb158508a884c8c0ede2e23ed10f32dea5d4ffe69a",
"integrity": "sha256:cfc2e7d3e9fd3b9b01f8d5cb158508a884c8c0ede2e23ed10f32dea5d4ffe69a"
}
}
}
35 changes: 25 additions & 10 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,28 +1,43 @@
{
"name": "bonob",
"name": "bonob-dev",
"build": {
"dockerfile": "Dockerfile"
},
"containerEnv": {
// these env vars need to be configured appropriately for your local dev env
"BNB_DEV_SONOS_DEVICE_IP": "${localEnv:BNB_DEV_SONOS_DEVICE_IP}",
"BNB_DEV_HOST_IP": "${localEnv:BNB_DEV_HOST_IP}",
"BNB_DEV_SUBSONIC_URL": "${localEnv:BNB_DEV_SUBSONIC_URL}"
"BNB_DEV_URL": "${localEnv:BNB_DEV_URL}",
"BNB_DEV_LOCAL_URL": "${localEnv:BNB_DEV_LOCAL_URL}",
"BNB_DEV_SUBSONIC_URL": "${localEnv:BNB_DEV_SUBSONIC_URL}",
"BNB_SECRET": "${localEnv:BNB_SECRET}"
},
// "postCreateCommand": "bash .devcontainer/setup.sh",
"remoteUser": "node",
"remoteEnv": {
"PATH": "/home/node/.local/bin:${containerEnv:PATH}"
},
"runArgs": [
"-p", "0.0.0.0:4534:4534",
"--privileged",
"--security-opt=label=disable"
],
"forwardPorts": [4534],
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"version": "latest",
"moby": true
}
"ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {}
// ,
// "ghcr.io/devcontainers/features/docker-in-docker:2": {
// "version": "latest",
// "moby": true
// }
},
"customizations": {
"vscode": {
"extensions": [
"esbenp.prettier-vscode",
"redhat.vscode-xml"
]
"davidanson.vscode-markdownlint",
"esbenp.prettier-vscode",
"redhat.vscode-xml"
// "ms-azuretools.vscode-docker"
]
}
}
}
8 changes: 8 additions & 0 deletions .devcontainer/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

set -e

if [ ! $(which claude) ] && [ "${BNB_DEV_USE_CLAUDE}" == "true" ]; then
# hardcoding version for the minute due to bug https://github.com/anthropics/claude-code/issues/47669
/workspaces/bonob/.devcontainer/claude-install.sh 2.1.89
fi
22 changes: 12 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ jobs:
steps:
-
name: Check out the repo
uses: actions/checkout@v3
uses: actions/checkout@v5
-
uses: actions/setup-node@v3
uses: actions/setup-node@v5
with:
node-version: 20
node-version: 22
-
run: npm install
-
Expand All @@ -35,44 +35,46 @@ jobs:
steps:
-
name: Check out the repo
uses: actions/checkout@v3
uses: actions/checkout@v5
with:
fetch-depth: 0
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
-
name: Docker meta
id: meta
uses: docker/metadata-action@v4
uses: docker/metadata-action@v5
with:
images: |
simojenki/bonob
ghcr.io/simojenki/bonob
-
name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Log in to GitHub Container registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Push image
uses: docker/build-push-action@v4
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
8 changes: 4 additions & 4 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v5

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
Expand All @@ -54,7 +54,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
uses: github/codeql-action/autobuild@v3

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
Expand All @@ -68,4 +68,4 @@ jobs:
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v3
Loading