126 lines
4.2 KiB
Text
126 lines
4.2 KiB
Text
def detect-platform []: nothing -> string {
|
|
let os = $nu.os-info.name | str downcase
|
|
let arch = $nu.os-info.arch | str downcase
|
|
|
|
let norm_arch = match $arch {
|
|
"x86_64" | "x64" | "amd64" => "x64"
|
|
"aarch64" | "arm64" => "arm64"
|
|
_ => { error make { msg: $"unsupported arch: ($arch)" } }
|
|
}
|
|
|
|
match $os {
|
|
"linux" => {
|
|
let musl_ld = $"/lib/ld-musl-($arch).so.1"
|
|
let suffix = if ($musl_ld | path exists) { "-musl" } else { "" }
|
|
$"linux-($norm_arch)($suffix)"
|
|
}
|
|
"macos" | "darwin" => $"darwin-($norm_arch)"
|
|
"windows" => { error make { msg: "windows unsupported by this launcher" } }
|
|
_ => { error make { msg: $"unsupported os: ($os)" } }
|
|
}
|
|
}
|
|
|
|
def build-binary [version: string, binary_path: string, cache: string] {
|
|
let platform = detect-platform
|
|
let pkg = $"@anthropic-ai/claude-code-($platform)"
|
|
let tarball_url = $"https://registry.npmjs.org/($pkg)/-/claude-code-($platform)-($version).tgz"
|
|
|
|
let tgz_dir = $cache | path join "tgz"
|
|
mkdir $tgz_dir
|
|
let tgz = $tgz_dir | path join $"claude-code-($platform)-($version).tgz"
|
|
|
|
if not ($tgz | path exists) {
|
|
print --stderr $"(ansi cyan)fetch:(ansi reset) ($tarball_url)"
|
|
http get --raw $tarball_url | save --force --raw $tgz
|
|
}
|
|
|
|
let workdir = $cache | path join $"build-($version)"
|
|
rm -rf $workdir
|
|
mkdir $workdir
|
|
|
|
run-external $env._TAR "-xzf" $tgz "-C" $workdir
|
|
let native_bin = $workdir | path join "package" "claude"
|
|
if not ($native_bin | path exists) {
|
|
error make { msg: $"lift: ($native_bin) missing after tar extract" }
|
|
}
|
|
|
|
let cli = $workdir | path join "cli.cjs"
|
|
run-external $env._LIFT_SCRIPT $native_bin $cli
|
|
run-external $env._PATCH_SCRIPT $cli
|
|
|
|
# Bun's bundler keeps a handful of http/ws/schema libs as runtime-external.
|
|
# Deno has no equivalent provision — drop a package.json next to cli.cjs,
|
|
# resolve deps into a local node_modules/, and bundle that tree into the
|
|
# executable via --include.
|
|
cp --force $env._EXTERNAL_PACKAGE_JSON ($workdir | path join "package.json")
|
|
|
|
cd $workdir
|
|
$env.DENO_DIR = ($workdir | path join ".deno")
|
|
run-external $env._DENO "install" "--node-modules-dir=auto"
|
|
run-external $env._DENO "compile" "--allow-all" "--no-check" "--node-modules-dir=auto" "--include=node_modules" "--output" $binary_path "cli.cjs"
|
|
|
|
# nushell refuses to delete a directory you're currently inside
|
|
cd $cache
|
|
rm -rf $workdir
|
|
}
|
|
|
|
def main --wrapped [...args] {
|
|
let cache = $env
|
|
| get --optional "XDG_CACHE_HOME"
|
|
| default ($env.HOME | path join ".cache")
|
|
| path join "claude-code"
|
|
mkdir $cache
|
|
|
|
let config_dir = $env | get --optional "CLAUDE_CONFIG_DIR" | default (
|
|
$env
|
|
| get --optional "XDG_CONFIG_HOME"
|
|
| default ($env.HOME | path join ".config")
|
|
| path join "claude"
|
|
)
|
|
mkdir $config_dir
|
|
|
|
# Sync declarative settings into writable config dir
|
|
cp --force $env._SETTINGS_JSON ($config_dir | path join "settings.json")
|
|
|
|
let version = do {
|
|
let version_file = $cache | path join "latest-version"
|
|
let stale = try { (date now) - (ls $version_file | get 0.modified) > 6hr } catch { true }
|
|
|
|
if not $stale { return (try { open $version_file } catch { "" }) }
|
|
|
|
let version = try {
|
|
http get --max-time 5sec https://registry.npmjs.org/@anthropic-ai/claude-code/latest
|
|
| get version
|
|
} catch {
|
|
print --stderr $"(ansi yellow_bold)warn:(ansi reset) version cache stale, can't re-fetch"
|
|
return ""
|
|
}
|
|
|
|
try {
|
|
$version | save --force $version_file
|
|
}
|
|
$version
|
|
}
|
|
|
|
let binary_path = if ($version | is-empty) {
|
|
print --stderr $"(ansi yellow_bold)warn:(ansi reset) falling back to latest binary"
|
|
|
|
try {
|
|
glob ($cache | path join "claude-*") | sort | last
|
|
} catch {
|
|
print --stderr $"(ansi red_bold)error:(ansi reset) no binary found"
|
|
exit 67
|
|
}
|
|
} else {
|
|
$cache | path join $"claude-($version)"
|
|
}
|
|
|
|
if not ($binary_path | path exists) {
|
|
build-binary $version $binary_path $cache
|
|
}
|
|
|
|
$env.PATH = ($env.PATH | prepend ($env._RUNTIME_DEPS | split row ":"))
|
|
$env._ENV_JSON | load-env
|
|
|
|
exec $binary_path ...$args
|
|
}
|