diff --git a/misc/claude-code/Makefile b/misc/claude-code/Makefile index 83e12ce4d0b4..c37c62ea81a8 100644 --- a/misc/claude-code/Makefile +++ b/misc/claude-code/Makefile @@ -1,62 +1,118 @@ PORTNAME= claude-code DISTVERSION= 2.1.90 -PORTREVISION= 1 +PORTREVISION= 2 CATEGORIES= misc # machine-learning +DISTFILES= ${PORTNAME}-${DISTVERSION}${EXTRACT_SUFX} MAINTAINER= yuri@FreeBSD.org COMMENT= Agentic coding tool from Anthropic that lives in your terminal WWW= https://github.com/anthropics/claude-code FETCH_DEPENDS= npm:www/npm \ jq:textproc/jq \ ${LOCALBASE}/share/certs/ca-root-nss.crt:security/ca_root_nss RUN_DEPENDS= rg:textproc/ripgrep USES= nodejs:run -NO_BUILD= yes -NO_ARCH= yes +OPTIONS_DEFINE= AUDIO_CAPTURE +OPTIONS_DEFAULT= AUDIO_CAPTURE +OPTIONS_SUB= yes + +AUDIO_CAPTURE_DESC= Build native audio capture module for FreeBSD +AUDIO_CAPTURE_BUILD_DEPENDS= ${LOCALBASE}/bin/cargo:lang/rust \ + pkgconf:devel/pkgconf +AUDIO_CAPTURE_LIB_DEPENDS= libasound.so:audio/alsa-lib + +AUDIO_CAPTURE_COMMIT= bb370f75235254da2c3d34f6168fc4a9902d9090 PACKAGE_NAME= @anthropic-ai/claude-code -FETCH_SCRIPT= ${PORTSDIR}/Tools/scripts/npmjs-fetch-with-dependencies.sh +FETCH_SCRIPT= ${PORTSDIR}/Tools/scripts/npmjs-fetch-with-dependencies.sh +AUDIO_CAPTURE_FETCH_SCRIPT= ${FILESDIR}/audio-capture-fetch.sh + +CLI_JS= ${WRKSRC}/node_modules/${PACKAGE_NAME}/cli.js +AUDIO_CAPTURE_WRKSRC= ${WRKDIR}/audio-capture-${AUDIO_CAPTURE_COMMIT} -CLI_JS= ${WRKSRC}/node_modules/${PACKAGE_NAME}/cli.js +.include + +.if ${PORT_OPTIONS:MAUDIO_CAPTURE} +ONLY_FOR_ARCHS= amd64 +ONLY_FOR_ARCHS_REASON= audio capture module only supports amd64 +DISTFILES+= audio-capture-${AUDIO_CAPTURE_COMMIT}${EXTRACT_SUFX}:audio_capture_src +MASTER_SITES+= https://github.com/kstonekuan/audio-capture/archive/:audio_capture_src +.else +NO_BUILD= yes +NO_ARCH= yes +.endif do-fetch: @if ! [ -f ${DISTDIR}/${PORTNAME}-${DISTVERSION}${EXTRACT_SUFX} ]; then \ ${SETENV} TMPDIR=${WRKDIR} LOCALBASE=${LOCALBASE} ${FETCH_SCRIPT} \ ${PACKAGE_NAME} ${DISTVERSION} \ ${FILESDIR}/package-lock.json \ ${DISTDIR}/${PORTNAME}-${DISTVERSION}${EXTRACT_SUFX}; \ fi +do-fetch-AUDIO_CAPTURE-on: + @if ! [ -f ${DISTDIR}/audio-capture-${AUDIO_CAPTURE_COMMIT}${EXTRACT_SUFX} ]; then \ + ${SETENV} TMPDIR=${WRKDIR} LOCALBASE=${LOCALBASE} \ + ${SH} ${AUDIO_CAPTURE_FETCH_SCRIPT} \ + ${AUDIO_CAPTURE_COMMIT} \ + ${DISTDIR}/audio-capture-${AUDIO_CAPTURE_COMMIT}${EXTRACT_SUFX}; \ + fi + # Raise API and MCP transport timeouts to 24 hours for slow (e.g. CPU-based) servers post-extract: ${REINPLACE_CMD} \ -e 's/var EP5=60000;/var EP5=86400000;/' \ -e 's/API_TIMEOUT_MS||String(600000)/API_TIMEOUT_MS||String(86400000)/' \ -e 's/DEFAULT_TIMEOUT=600000;/DEFAULT_TIMEOUT=86400000;/' \ ${CLI_JS} +post-extract-AUDIO_CAPTURE-on: + # patch cli.js to load audio-capture on FreeBSD + ${REINPLACE_CMD} \ + -e 's|q!=="darwin"&&q!=="linux"&&q!=="win32"|q!=="darwin"\&\&q!=="linux"\&\&q!=="win32"\&\&q!=="freebsd"|' \ + ${CLI_JS} + +do-build: +.if ${PORT_OPTIONS:MAUDIO_CAPTURE} + @${ECHO_MSG} "====> Building audio-capture for FreeBSD amd64..." + @cd ${AUDIO_CAPTURE_WRKSRC} && \ + ${SETENV} HOME=${WRKDIR} cargo build --release +.endif + do-install: - # install files + # install node_modules @${MKDIR} ${STAGEDIR}${PREFIX}/lib @cd ${WRKSRC} && \ ${COPYTREE_SHARE} node_modules ${STAGEDIR}${PREFIX}/lib + # remove *.node binaries for non-FreeBSD platforms + @${FIND} ${STAGEDIR}${PREFIX}/lib/node_modules/${PACKAGE_NAME}/vendor/audio-capture \ + -name "*.node" -delete +.if ${PORT_OPTIONS:MAUDIO_CAPTURE} + # install FreeBSD amd64 audio-capture module + @${MKDIR} ${STAGEDIR}${PREFIX}/lib/node_modules/${PACKAGE_NAME}/vendor/audio-capture/x64-freebsd + ${INSTALL_LIB} ${AUDIO_CAPTURE_WRKSRC}/target/release/libaudio_capture.so \ + ${STAGEDIR}${PREFIX}/lib/node_modules/${PACKAGE_NAME}/vendor/audio-capture/x64-freebsd/audio-capture.node +.endif + # remove bundled ripgrep + @${RM} -r ${STAGEDIR}${PREFIX}/lib/node_modules/${PACKAGE_NAME}/vendor/ripgrep + # remove empty vendor subdirectories (and vendor/ itself when AUDIO_CAPTURE=OFF) + @${FIND} ${STAGEDIR}${PREFIX}/lib/node_modules/${PACKAGE_NAME}/vendor \ + -depth -type d -empty -delete # update shebang ${REINPLACE_CMD} -i '' \ -e "s|#!/usr/bin/env node|#!${PREFIX}/bin/node|" \ ${STAGEDIR}${PREFIX}/lib/node_modules/${PACKAGE_NAME}/cli.js # set exec bit @${CHMOD} +x ${STAGEDIR}${PREFIX}/lib/node_modules/${PACKAGE_NAME}/cli.js # create wrapper script that uses system ripgrep @${MKDIR} ${STAGEDIR}${PREFIX}/bin @${ECHO_CMD} '#!/bin/sh' > ${STAGEDIR}${PREFIX}/bin/claude @${ECHO_CMD} 'export USE_BUILTIN_RIPGREP=false' >> ${STAGEDIR}${PREFIX}/bin/claude @${ECHO_CMD} 'exec ${PREFIX}/lib/node_modules/${PACKAGE_NAME}/cli.js "$$@"' >> ${STAGEDIR}${PREFIX}/bin/claude @${CHMOD} +x ${STAGEDIR}${PREFIX}/bin/claude - # remove bundled ripgrep - @${RM} -r ${STAGEDIR}${PREFIX}/lib/node_modules/${PACKAGE_NAME}/vendor/ripgrep .include diff --git a/misc/claude-code/distinfo b/misc/claude-code/distinfo index fa90d8cc93c4..da7b2c9116c7 100644 --- a/misc/claude-code/distinfo +++ b/misc/claude-code/distinfo @@ -1,3 +1,5 @@ TIMESTAMP = 1775147894 SHA256 (claude-code-2.1.90.tar.gz) = debb5e196531112978820e5c9b374eca1d6db6dda9098a3c6bae79c9e14320a6 SIZE (claude-code-2.1.90.tar.gz) = 16070380 +SHA256 (audio-capture-bb370f75235254da2c3d34f6168fc4a9902d9090.tar.gz) = d6a4e0ff2666efd60efd4259c0e29d6878975cc6f41a2171ff5a12b75e6ef7c6 +SIZE (audio-capture-bb370f75235254da2c3d34f6168fc4a9902d9090.tar.gz) = 26840618 diff --git a/misc/claude-code/files/audio-capture-fetch.sh b/misc/claude-code/files/audio-capture-fetch.sh new file mode 100644 index 000000000000..532a1b72fac5 --- /dev/null +++ b/misc/claude-code/files/audio-capture-fetch.sh @@ -0,0 +1,80 @@ +#!/bin/sh +# +# MAINTAINER: yuri@FreeBSD.org + +# This script fetches the audio-capture Rust source from GitHub, vendors all +# Cargo dependencies using 'cargo vendor', and packages everything into a +# reproducible tarball suitable for offline builds. +# +# Usage: $0 +# Example: $0 bb370f75235254da2c3d34f6168fc4a9902d9090 /distfiles/audio-capture-bb370f75.tar.gz + +set -eu + +AUDIO_CAPTURE_COMMIT="$1" +PACKAGE_TARBALL_OUTPUT="$2" + +LOCALBASE="${LOCALBASE:-/usr/local}" + +if [ -z "$AUDIO_CAPTURE_COMMIT" ] || [ -z "$PACKAGE_TARBALL_OUTPUT" ]; then + echo "Usage: $0 " + exit 1 +fi + +if [ -z "$TMPDIR" ]; then + TMPDIR="/tmp" +fi + +# to full paths +if ! echo "${PACKAGE_TARBALL_OUTPUT}" | grep -q "^/"; then + PACKAGE_TARBALL_OUTPUT="`pwd`/${PACKAGE_TARBALL_OUTPUT}" +fi +if ! echo "${TMPDIR}" | grep -q "^/"; then + TMPDIR="`pwd`/${TMPDIR}" +fi + +BUILD_DIR="${TMPDIR}/audio-capture-fetch-${AUDIO_CAPTURE_COMMIT}" +rm -rf "${BUILD_DIR}" +mkdir -p "${BUILD_DIR}" +cd "${BUILD_DIR}" + +# Download source from GitHub +echo "===> Downloading audio-capture source (commit ${AUDIO_CAPTURE_COMMIT})" +${LOCALBASE}/bin/curl -sL \ + "https://github.com/kstonekuan/audio-capture/archive/${AUDIO_CAPTURE_COMMIT}.tar.gz" \ + -o source.tar.gz +tar xzf source.tar.gz +rm source.tar.gz +SRC="audio-capture-${AUDIO_CAPTURE_COMMIT}" + +# Vendor all Cargo dependencies into the source tree +echo "===> Vendoring Rust dependencies" +cd "${BUILD_DIR}/${SRC}" +CARGO_HOME="${BUILD_DIR}/cargo-home" cargo vendor cargo-crates 2>&1 | tail -5 + +# Write .cargo/config.toml to use vendored crates +cat > "${BUILD_DIR}/${SRC}/.cargo/config.toml" << 'EOF' +[source.crates-io] +replace-with = "vendored-sources" + +[source.vendored-sources] +directory = "cargo-crates" + +[target.aarch64-apple-darwin] +rustflags = ["-C", "link-args=-undefined dynamic_lookup"] + +[target.x86_64-apple-darwin] +rustflags = ["-C", "link-args=-undefined dynamic_lookup"] +EOF + +# Create a deterministic tarball (normalise timestamps, sort entries) +echo "===> Creating tarball" +cd "${BUILD_DIR}" +find "${SRC}" -and -exec touch -h -d 1970-01-01T00:00:00Z {} \; +find "${SRC}" -print0 | sort -z | \ + tar czf "${PACKAGE_TARBALL_OUTPUT}" \ + --format=bsdtar --no-read-sparse --gid 0 --uid 0 \ + --options gzip:!timestamp --no-recursion --null -T - + +rm -rf "${BUILD_DIR}" +echo "===> Created: ${PACKAGE_TARBALL_OUTPUT}" diff --git a/misc/claude-code/pkg-plist b/misc/claude-code/pkg-plist index e130fd5e898c..89fe5b22a3c6 100644 --- a/misc/claude-code/pkg-plist +++ b/misc/claude-code/pkg-plist @@ -1,14 +1,9 @@ bin/claude lib/node_modules/.bin/claude lib/node_modules/@anthropic-ai/claude-code/LICENSE.md lib/node_modules/@anthropic-ai/claude-code/README.md lib/node_modules/@anthropic-ai/claude-code/bun.lock lib/node_modules/@anthropic-ai/claude-code/cli.js lib/node_modules/@anthropic-ai/claude-code/package.json lib/node_modules/@anthropic-ai/claude-code/sdk-tools.d.ts -lib/node_modules/@anthropic-ai/claude-code/vendor/audio-capture/arm64-darwin/audio-capture.node -lib/node_modules/@anthropic-ai/claude-code/vendor/audio-capture/arm64-linux/audio-capture.node -lib/node_modules/@anthropic-ai/claude-code/vendor/audio-capture/arm64-win32/audio-capture.node -lib/node_modules/@anthropic-ai/claude-code/vendor/audio-capture/x64-darwin/audio-capture.node -lib/node_modules/@anthropic-ai/claude-code/vendor/audio-capture/x64-linux/audio-capture.node -lib/node_modules/@anthropic-ai/claude-code/vendor/audio-capture/x64-win32/audio-capture.node +%%AUDIO_CAPTURE%%lib/node_modules/@anthropic-ai/claude-code/vendor/audio-capture/x64-freebsd/audio-capture.node