1PORTNAME= claude-code 2DISTVERSION= 2.1.112 3CATEGORIES= misc # machine-learning 4DISTFILES= ${PORTNAME}-${DISTVERSION}${EXTRACT_SUFX} 5 6MAINTAINER= ports@MidnightBSD.org 7COMMENT= Agentic coding tool from Anthropic that lives in your terminal 8WWW= https://github.com/anthropics/claude-code 9 10LICENSE= anthropic 11LICENSE_NAME= Anthropic 12LICENSE_PERMS= dist-mirror pkg-mirror 13LICENSE_TEXT= See https://www.anthropic.com/legal/commercial-terms 14 15FETCH_DEPENDS= cargo:lang/rust \ 16 npm:www/npm \ 17 jq:textproc/jq \ 18 ${LOCALBASE}/share/certs/ca-root-nss.crt:security/ca_root_nss 19EXTRACT_DEPENDS= curl:ftp/curl 20RUN_DEPENDS= rg:textproc/ripgrep 21 22USES= nodejs:run 23 24JS_ARCH= ${ARCH:S/amd64/x64/:S/aarch64/arm64/:S/i386/ia32/:S/powerpc64le/ppc64le/:S/powerpc64/ppc64/:C/armv[67]/arm/} # modeled after electron.mk 25PLIST_SUB= JS_ARCH=${JS_ARCH} 26 27OPTIONS_DEFINE= AUDIO_CAPTURE USE_CURL_USER_AGENT 28OPTIONS_DEFAULT= USE_CURL_USER_AGENT 29OPTIONS_SUB= yes 30 31AUDIO_CAPTURE_DESC= Build native audio capture module for BSD 32USE_CURL_USER_AGENT_DESC= Use curl User-Agent for web fetching to bypass bot-blocking filters (e.g. Anubis) 33AUDIO_CAPTURE_BUILD_DEPENDS= ${LOCALBASE}/bin/cargo:lang/rust \ 34 pkgconf:devel/pkgconf 35AUDIO_CAPTURE_LIB_DEPENDS= libasound.so:audio/alsa-lib 36 37AUDIO_CAPTURE_COMMIT= bb370f75235254da2c3d34f6168fc4a9902d9090 38 39PACKAGE_NAME= @anthropic-ai/claude-code 40 41FETCH_SCRIPT= ${PORTSDIR}/Tools/scripts/npmjs-fetch-with-dependencies.sh 42AUDIO_CAPTURE_FETCH_SCRIPT= ${FILESDIR}/audio-capture-fetch.sh 43 44CLI_JS= ${WRKSRC}/node_modules/${PACKAGE_NAME}/cli.js 45AUDIO_CAPTURE_WRKSRC= ${WRKDIR}/audio-capture-${AUDIO_CAPTURE_COMMIT} 46 47.include <bsd.mport.options.mk> 48 49.if ${PORT_OPTIONS:MAUDIO_CAPTURE} 50DISTFILES+= audio-capture-${AUDIO_CAPTURE_COMMIT}${EXTRACT_SUFX}:audio_capture_src 51.else 52NO_BUILD= yes 53NO_ARCH= yes 54.endif 55 56do-fetch: 57 @if ! [ -f ${DISTDIR}/${PORTNAME}-${DISTVERSION}${EXTRACT_SUFX} ]; then \ 58 ${SETENV} TMPDIR=${WRKDIR} LOCALBASE=${LOCALBASE} ${FETCH_SCRIPT} \ 59 ${PACKAGE_NAME} ${DISTVERSION} \ 60 ${FILESDIR}/package-lock.json \ 61 ${DISTDIR}/${PORTNAME}-${DISTVERSION}${EXTRACT_SUFX}; \ 62 fi 63 64do-fetch-AUDIO_CAPTURE-on: 65 @if ! [ -f ${DISTDIR}/audio-capture-${AUDIO_CAPTURE_COMMIT}${EXTRACT_SUFX} ]; then \ 66 ${SETENV} TMPDIR=${WRKDIR} LOCALBASE=${LOCALBASE} \ 67 ${SH} ${AUDIO_CAPTURE_FETCH_SCRIPT} \ 68 ${AUDIO_CAPTURE_COMMIT} \ 69 ${DISTDIR}/audio-capture-${AUDIO_CAPTURE_COMMIT}${EXTRACT_SUFX}; \ 70 fi 71 72# Raise API and MCP transport timeouts to 24 hours for slow (e.g. CPU-based) servers 73post-extract: 74 ${REINPLACE_CMD} -i '' \ 75 -e 's/var EP5=60000;/var EP5=86400000;/' \ 76 -e 's/API_TIMEOUT_MS||String(600000)/API_TIMEOUT_MS||String(86400000)/' \ 77 -e 's/DEFAULT_TIMEOUT=600000;/DEFAULT_TIMEOUT=86400000;/' \ 78 -e 's#}async function Rt(){#}async function Rt(){if(process.argv[1]\&\&(process.argv[1].includes("/usr/local/lib/node_modules")||process.argv[1].includes("/usr/lib/node_modules")))return"package-manager";#' \ 79 -e 's#f==="development"){E("AutoUpdater: Cannot auto-update development build")#f==="development"||f==="package-manager"){E("AutoUpdater: Cannot auto-update development build")#' \ 80 ${CLI_JS} 81 82post-extract-AUDIO_CAPTURE-on: 83 # patch cli.js to load audio-capture 84 ${REINPLACE_CMD} -i '' \ 85 -e 's|q!=="darwin"&&q!=="linux"&&q!=="win32"|q!=="darwin"\&\&q!=="linux"\&\&q!=="win32"\&\&q!=="midnightbsd"|' \ 86 ${CLI_JS} 87 88post-extract-USE_CURL_USER_AGENT-on: 89 # patch cli.js to use a curl-style User-Agent for web fetching 90 @_V=$$(${LOCALBASE}/bin/curl --version 2>/dev/null | head -1 | ${AWK} '{print $$2}'); \ 91 ${REINPLACE_CMD} -i '' \ 92 -e 's|function dUq(){return`Claude-User ($${yA()}; +https://support.anthropic.com/)`}|function dUq(){return"curl/'"$$_V"'"}|' \ 93 ${CLI_JS} 94 95do-build: 96.if ${PORT_OPTIONS:MAUDIO_CAPTURE} 97 @${ECHO_MSG} "====> Building audio-capture for amd64..." 98 @cd ${AUDIO_CAPTURE_WRKSRC} && \ 99 ${SETENV} HOME=${WRKDIR} cargo build --release 100.endif 101 102do-install: 103 # install files 104 @${MKDIR} ${PREFIX}/lib 105 @cd ${WRKSRC} && \ 106 ${COPYTREE_SHARE} node_modules ${STAGEDIR}${PREFIX}/lib 107 # remove *.node binaries for FreeBSD platforms 108 @${FIND} ${STAGEDIR}${PREFIX}/lib/node_modules/${PACKAGE_NAME}/vendor/audio-capture \ 109 -name "*.node" -delete 110.if ${PORT_OPTIONS:MAUDIO_CAPTURE} 111 # install BSD amd64 audio-capture module 112 @${MKDIR} ${STAGEDIR}${PREFIX}/lib/node_modules/${PACKAGE_NAME}/vendor/audio-capture/x64-freebsd 113 ${INSTALL_LIB} ${AUDIO_CAPTURE_WRKSRC}/target/release/libaudio_capture.so \ 114 ${STAGEDIR}${PREFIX}/lib/node_modules/${PACKAGE_NAME}/vendor/audio-capture/x64-freebsd/audio-capture.node 115.endif 116 # remove Linux-only seccomp binaries (seccomp is a Linux kernel API, guarded by process.platform==="linux" in cli.js) 117 @${RM} -r ${STAGEDIR}${PREFIX}/lib/node_modules/${PACKAGE_NAME}/vendor/seccomp 118 # remove bundled ripgrep 119 @${RM} -r ${STAGEDIR}${PREFIX}/lib/node_modules/${PACKAGE_NAME}/vendor/ripgrep 120 # remove empty vendor subdirectories (and vendor/ itself when AUDIO_CAPTURE=OFF) 121 @${FIND} ${STAGEDIR}${PREFIX}/lib/node_modules/${PACKAGE_NAME}/vendor \ 122 -depth -type d -empty -delete 123 # update shebang 124 ${REINPLACE_CMD} -i '' \ 125 -e "s|#!/usr/bin/env node|#!${TRUE_PREFIX}/bin/node|" \ 126 ${STAGEDIR}${PREFIX}/lib/node_modules/${PACKAGE_NAME}/cli.js 127 # set exec bit 128 @${CHMOD} +x ${STAGEDIR}${PREFIX}/lib/node_modules/${PACKAGE_NAME}/cli.js 129 # create wrapper script that uses system ripgrep 130 @${MKDIR} ${STAGEDIR}${PREFIX}/bin 131 @${ECHO_CMD} '#!/bin/sh' > ${STAGEDIR}${PREFIX}/bin/claude 132 @${ECHO_CMD} 'export USE_BUILTIN_RIPGREP=false' >> ${STAGEDIR}${PREFIX}/bin/claude 133 @${ECHO_CMD} 'exec ${TRUE_PREFIX}/lib/node_modules/${PACKAGE_NAME}/cli.js "$$@"' >> ${STAGEDIR}${PREFIX}/bin/claude 134 @${CHMOD} +x ${STAGEDIR}${PREFIX}/bin/claude 135 136.include <bsd.port.mk> 137