Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

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

flash-mac: also bake github-pat from /api/claude-token response

claude-token netlify fn already returns githubPat alongside the Claude
OAuth token. Bake it to /github-pat in the supplementary cpio archive —
pty.c reads it at child spawn and sets GITHUB_TOKEN so on-device git
push to the GitHub mirror works without SSH setup.

Also broadens the gate so we still build the supplementary cpio when
only githubPat is present (e.g. user saved PAT but never stored Claude
token), and renames the scope log from "claude token: skipped" to
"creds fetch: skipped" since we're fetching both now.

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

+44 -22
+44 -22
fedac/native/scripts/flash-mac.sh
··· 93 93 [ -z "${USER_HANDLE}${USER_SUB}${USER_EMAIL}" ] && \ 94 94 log "No ~/.ac-token (run \`ac-login\` first to bake credentials in)" 95 95 96 - # --- fetch Claude OAuth token from MongoDB (year-long token per handle) --- 97 - # The claude-token netlify function returns the token stored at 98 - # @handles.claudeCodeToken for the authenticated user's sub. pty.c reads 99 - # /claude-token at spawn time and sets CLAUDE_CODE_OAUTH_TOKEN so 100 - # `claude` launches without an interactive login prompt. 96 + # --- fetch Claude OAuth token + GitHub PAT from MongoDB --- 97 + # /api/claude-token returns { handle, token, githubPat } from @handles. 98 + # `token` is the year-long Claude Code OAuth bearer (sk-ant-...) — pty.c 99 + # reads /claude-token at spawn time and sets CLAUDE_CODE_OAUTH_TOKEN so 100 + # `claude` launches without interactive login. `githubPat` lets on-device 101 + # git push to the GitHub mirror without SSH. 101 102 CLAUDE_TOKEN="" 103 + GITHUB_PAT="" 102 104 if [ -n "${AC_ACCESS_TOKEN}" ]; then 103 - log "Fetching Claude OAuth token from MongoDB…" 105 + log "Fetching Claude token + GitHub PAT from MongoDB…" 104 106 CT_RESP="$(curl -fsS -H "Authorization: Bearer ${AC_ACCESS_TOKEN}" \ 105 107 "https://aesthetic.computer/api/claude-token" 2>/dev/null || echo "")" 106 108 if [ -n "${CT_RESP}" ]; then 107 - CLAUDE_TOKEN="$(node -e ' 108 - try { process.stdout.write(JSON.parse(process.argv[1]).token || ""); } catch {} 109 + eval "$(node -e ' 110 + try { 111 + const r = JSON.parse(process.argv[1]); 112 + const out = (k, v) => process.stdout.write(`${k}=${JSON.stringify(v || "")}\n`); 113 + out("CLAUDE_TOKEN", r.token); 114 + out("GITHUB_PAT", r.githubPat); 115 + } catch {} 109 116 ' "${CT_RESP}" 2>/dev/null)" 110 117 fi 111 118 if [ -n "${CLAUDE_TOKEN}" ]; then 112 - log " claude token: ${#CLAUDE_TOKEN} bytes fetched" 119 + log " claude token: ${#CLAUDE_TOKEN} bytes" 113 120 else 114 - log " claude token: none stored in MongoDB (POST to /api/claude-token from the web to save one)" 121 + log " claude token: none stored in MongoDB (POST to /api/claude-token to save)" 115 122 fi 123 + [ -n "${GITHUB_PAT}" ] && log " github pat: ${#GITHUB_PAT} bytes" 116 124 elif [ "${AC_TOKEN_EXPIRED}" = "1" ]; then 117 - log " claude token: skipped (~/.ac-token expired — run \`ac-login\` to refresh)" 125 + log " creds fetch: skipped (~/.ac-token expired — run \`ac-login\` to refresh)" 118 126 fi 119 127 120 - # --- bake Claude creds into initramfs via concatenated cpio archive --- 128 + # --- bake creds into initramfs via concatenated cpio archive --- 121 129 # The Linux kernel's unpack_to_rootfs() accepts multiple concatenated 122 130 # gzipped cpio archives in the initrd stream (same trick intel-ucode 123 - # uses). We build a tiny supplementary archive containing /claude-token 124 - # + /claude-state.json and append it to the end of initramfs.cpio.gz. 125 - # pty.c reads /claude-token directly; init copies /claude-state.json to 126 - # /tmp/.claude.json so Claude Code skips onboarding prompts. 127 - if [ -n "${CLAUDE_TOKEN}" ]; then 131 + # uses). We build a tiny supplementary archive containing the baked 132 + # files and append it to the end of initramfs.cpio.gz. 133 + # Files baked (matches ac-os Linux layout): 134 + # /claude-token plain bearer — pty.c reads + sets CLAUDE_CODE_OAUTH_TOKEN 135 + # /claude-state.json init copies to /tmp/.claude.json (skips CC onboarding) 136 + # /github-pat plain bearer — pty.c sets GITHUB_TOKEN 137 + if [ -n "${CLAUDE_TOKEN}${GITHUB_PAT}" ]; then 128 138 BAKE_DIR="$(mktemp -d /tmp/ac-bake.XXXXXX)" 129 139 BAKED_INITRAMFS="/tmp/ac-initramfs-baked.$$.cpio.gz" 130 140 ORIG_INITRD_SIZE="$(stat -f%z "${INITRAMFS}")" 131 - printf %s "${CLAUDE_TOKEN}" > "${BAKE_DIR}/claude-token" 132 - chmod 600 "${BAKE_DIR}/claude-token" 133 - cat > "${BAKE_DIR}/claude-state.json" <<STATE 141 + BAKE_LIST="" 142 + if [ -n "${CLAUDE_TOKEN}" ]; then 143 + printf %s "${CLAUDE_TOKEN}" > "${BAKE_DIR}/claude-token" 144 + chmod 600 "${BAKE_DIR}/claude-token" 145 + cat > "${BAKE_DIR}/claude-state.json" <<STATE 134 146 {"oauthAccount":{"emailAddress":"${USER_EMAIL}","organizationName":"","accountUuid":""},"hasCompletedOnboarding":true,"installMethod":"manual","numStartups":1,"autoUpdates":false,"autoUpdatesProtectedForNative":true} 135 147 STATE 148 + BAKE_LIST="${BAKE_LIST}claude-token 149 + claude-state.json 150 + " 151 + fi 152 + if [ -n "${GITHUB_PAT}" ]; then 153 + printf %s "${GITHUB_PAT}" > "${BAKE_DIR}/github-pat" 154 + chmod 600 "${BAKE_DIR}/github-pat" 155 + BAKE_LIST="${BAKE_LIST}github-pat 156 + " 157 + fi 136 158 cp "${INITRAMFS}" "${BAKED_INITRAMFS}" 137 - ( cd "${BAKE_DIR}" && printf 'claude-token\nclaude-state.json\n' \ 159 + ( cd "${BAKE_DIR}" && printf '%s' "${BAKE_LIST}" \ 138 160 | cpio -o -H newc 2>/dev/null ) \ 139 161 | gzip -9 >> "${BAKED_INITRAMFS}" \ 140 - || die "Failed to append Claude creds cpio to initramfs" 162 + || die "Failed to append creds cpio to initramfs" 141 163 rm -rf "${BAKE_DIR}" 142 164 INITRAMFS="${BAKED_INITRAMFS}" 143 165 NEW_INITRD_SIZE="$(stat -f%z "${INITRAMFS}")"