diff --git a/misc/claude-code/Makefile b/misc/claude-code/Makefile index c37c62ea81a8..a4ed33fc45eb 100644 --- a/misc/claude-code/Makefile +++ b/misc/claude-code/Makefile @@ -1,118 +1,119 @@ PORTNAME= claude-code DISTVERSION= 2.1.90 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 \ +FETCH_DEPENDS= cargo:lang/rust \ + curl:ftp/curl \ jq:textproc/jq \ + npm:www/npm \ ${LOCALBASE}/share/certs/ca-root-nss.crt:security/ca_root_nss RUN_DEPENDS= rg:textproc/ripgrep USES= nodejs:run 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 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} .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 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 .include diff --git a/misc/claude-code/distinfo b/misc/claude-code/distinfo index da7b2c9116c7..27017760fd71 100644 --- a/misc/claude-code/distinfo +++ b/misc/claude-code/distinfo @@ -1,5 +1,5 @@ -TIMESTAMP = 1775147894 +TIMESTAMP = 1775631098 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 index 532a1b72fac5..032f24083761 100644 --- a/misc/claude-code/files/audio-capture-fetch.sh +++ b/misc/claude-code/files/audio-capture-fetch.sh @@ -1,80 +1,86 @@ #!/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 +set -euo pipefail + +export LC_ALL=C +umask 002 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) +# Create a deterministic tarball (normalise timestamps, permissions, sort entries) echo "===> Creating tarball" cd "${BUILD_DIR}" +find "${SRC}" -type d -exec chmod 755 {} \; +find "${SRC}" -type f ! -perm -0100 -exec chmod 644 {} \; +find "${SRC}" -type f -perm -0100 -exec chmod 755 {} \; 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}"