Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

claude: auto-install native binary on oven builds + pin Sonnet 4.7 default

Fixes two related on-device breakages reported after flash:

1. "claude: command not found" / "install native" prompt
ac-os bundles /bin/claude by copying from the builder's local
~/.local/share/claude/versions/<latest>. That works on developer
machines but the oven build server doesn't have claude pre-installed,
so /bin/claude was silently missing from every OS image. When the
user opened the `code` (claude) piece the PTY spawned a binary that
didn't exist, and the npm-wrapper stub that DOES exist on some
devices printed "install native" prompting them to download the
native binary they're already trying to run.

Fix: in ac-os, if CLAUDE_BIN isn't found locally, `curl -fsSL
https://claude.ai/install.sh | bash` populates the versions dir
as a fallback. Output is streamed through the build log so failures
are obvious. Non-fatal if install.sh fails — the build still
completes and logs "(non-fatal — will ship image without /bin/claude)"
so we don't break builds on network flake.

2. Default model wasn't pinned to Sonnet 4.7
Two-layer fix — the CLI resolves model selection from:
(a) ANTHROPIC_MODEL env var (set at PTY child spawn in pty.c)
(b) `model` key in /tmp/.claude/settings.json (written by init)
Both layers now carry `"sonnet"`, the Anthropic alias that resolves
to the latest Sonnet family member — currently 4.7. Users who want
to pin a specific version can override either source.

pty.c setenv uses overwrite=0 so ANTHROPIC_MODEL is preserved if the
user has already exported one in their shell session.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

+28 -3
+17 -2
fedac/native/ac-os
··· 130 130 # Copy fresh binary into initramfs 131 131 sudo cp "${BUILD_DIR}/ac-native" "${INITRAMFS_ROOT}/ac-native" 132 132 133 - # Claude Code native binary (no Node.js needed) 133 + # Claude Code native binary (no Node.js needed). 134 + # Look in the builder's home first; if nothing's installed (oven build 135 + # machines don't ship claude pre-installed) fall back to downloading 136 + # the latest native binary via claude.ai/install.sh so every OS build 137 + # ships a working /bin/claude instead of the "claude: command not 138 + # found" that was leaving devices broken post-flash. 134 139 local CLAUDE_NATIVE="${HOME}/.local/share/claude/versions" 135 140 local CLAUDE_BIN="" 136 141 if [ -d "${CLAUDE_NATIVE}" ]; then 137 - # Find the latest version binary 138 142 CLAUDE_BIN=$(ls -t "${CLAUDE_NATIVE}/"* 2>/dev/null | head -1) 143 + fi 144 + if [ -z "${CLAUDE_BIN}" ] || [ ! -f "${CLAUDE_BIN}" ]; then 145 + log "Claude native binary not found locally; fetching via claude.ai/install.sh..." 146 + # install.sh is safe to run on CI — writes to $HOME/.local only. 147 + if curl -fsSL https://claude.ai/install.sh | bash 2>&1 | sed 's/^/ [claude-install] /' | tail -20; then 148 + if [ -d "${CLAUDE_NATIVE}" ]; then 149 + CLAUDE_BIN=$(ls -t "${CLAUDE_NATIVE}/"* 2>/dev/null | head -1) 150 + fi 151 + else 152 + log " claude-install failed (non-fatal — will ship image without /bin/claude)" 153 + fi 139 154 fi 140 155 if [ -n "${CLAUDE_BIN}" ] && [ -f "${CLAUDE_BIN}" ]; then 141 156 log "Bundling Claude Code (native binary)..."
+5 -1
fedac/native/initramfs/init
··· 69 69 mkdir -p /tmp/.claude 70 70 [ -f /claude-creds.json ] && cp /claude-creds.json /tmp/.claude/.credentials.json 71 71 cp /claude-state.json /tmp/.claude.json 2>/dev/null 72 - printf '{"permissions":{"allow":["Bash(*)","Read(*)","Write(*)","Edit(*)","Glob(*)","Grep(*)","WebFetch(*)","WebSearch(*)"]},"autoUpdates":false,"installMethod":"native"}\n' > /tmp/.claude/settings.json 72 + # Pin Claude's default model to the "sonnet" alias — Anthropic's 73 + # CLI resolves "sonnet" to the latest Sonnet family member, which 74 + # is currently Sonnet 4.7. Users who want a specific pinned version 75 + # can override by writing a different model string into this file. 76 + printf '{"permissions":{"allow":["Bash(*)","Read(*)","Write(*)","Edit(*)","Glob(*)","Grep(*)","WebFetch(*)","WebSearch(*)"]},"autoUpdates":false,"installMethod":"native","model":"sonnet"}\n' > /tmp/.claude/settings.json 73 77 fi 74 78 if [ -f /tangled-key ] || [ -f /tangled-ssh-config ] || [ -f /tangled-known-hosts ]; then 75 79 mkdir -p /tmp/.ssh
+6
fedac/native/src/pty.c
··· 563 563 setenv("LOGNAME", "root", 1); 564 564 setenv("GIT_TERMINAL_PROMPT", "0", 1); 565 565 setenv("CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC", "1", 1); 566 + // Pin Claude's default model to "sonnet" — Anthropic's CLI resolves 567 + // that alias to the latest Sonnet family member, currently 4.7. 568 + // Setting ANTHROPIC_MODEL belt-and-suspenders alongside the same 569 + // key in /tmp/.claude/settings.json so either resolution path 570 + // lands on 4.7 instead of whatever the CLI's built-in default is. 571 + setenv("ANTHROPIC_MODEL", "sonnet", 0); 566 572 // SSL certs for API connections 567 573 setenv("SSL_CERT_FILE", "/etc/pki/tls/certs/ca-bundle.crt", 0); 568 574 setenv("SSL_CERT_DIR", "/etc/ssl/certs", 0);