From 9c30e35f4128ed90ac5f69a0b8291165f3d069e2 Mon Sep 17 00:00:00 2001 From: LyAhn Date: Tue, 30 Jun 2026 11:06:35 +0100 Subject: [PATCH 1/3] Add Codex cloud setup script --- scripts/codex-cloud-setup.sh | 189 +++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 scripts/codex-cloud-setup.sh diff --git a/scripts/codex-cloud-setup.sh b/scripts/codex-cloud-setup.sh new file mode 100644 index 0000000..1062067 --- /dev/null +++ b/scripts/codex-cloud-setup.sh @@ -0,0 +1,189 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +# Codex Cloud setup for Phokus. +# Paste this script into the Codex Cloud environment setup field, or run it from +# the repo root with: bash scripts/codex-cloud-setup.sh +# +# Goals: +# - install Linux packages needed by Tauri/WebKit and native Rust crates +# - install JS dependencies with pnpm using the lockfile +# - pre-fetch Rust dependencies while setup still has internet access +# - keep the environment CPU-safe by avoiding Phokus' default CUDA feature set +# - leave Codex with clear verification commands for UI and Rust work + +log() { + printf '\n\033[1;36m[phokus-codex]\033[0m %s\n' "$*" +} + +warn() { + printf '\n\033[1;33m[phokus-codex warning]\033[0m %s\n' "$*" >&2 +} + +repo_root="$(pwd)" + +if [[ ! -f "package.json" || ! -d "src-tauri" ]]; then + warn "This script should be run from the Phokus repository root. Current directory: ${repo_root}" + exit 1 +fi + +export CI=1 +export PNPM_HOME="${PNPM_HOME:-$HOME/.local/share/pnpm}" +export PATH="$PNPM_HOME:$HOME/.cargo/bin:$PATH" + +# Persist useful shell defaults for the later Codex agent phase. Codex setup runs +# in a separate Bash session, so exports here alone would not survive. +if ! grep -q "# Phokus Codex Cloud" "$HOME/.bashrc" 2>/dev/null; then + cat >> "$HOME/.bashrc" <<'BASHRC' + +# Phokus Codex Cloud +export PNPM_HOME="${PNPM_HOME:-$HOME/.local/share/pnpm}" +export PATH="$PNPM_HOME:$HOME/.cargo/bin:$PATH" +export CI=1 +BASHRC +fi + +install_apt_packages() { + if ! command -v apt-get >/dev/null 2>&1; then + warn "apt-get not found; skipping system package installation." + return 0 + fi + + log "Installing Linux system dependencies for Tauri, WebKit, SQLite/native crates, and browser tooling" + + sudo apt-get update + + # Tauri v2 Linux builds need the WebKitGTK/AppIndicator/Rsvg stack. Some base + # images expose either the 4.1 or 4.0 WebKit development package, so try the + # modern package first and gracefully fall back. + local common_packages=( + build-essential + curl + wget + file + pkg-config + libssl-dev + libgtk-3-dev + libayatana-appindicator3-dev + librsvg2-dev + patchelf + ca-certificates + ) + + if apt-cache show libwebkit2gtk-4.1-dev >/dev/null 2>&1; then + sudo apt-get install -y --no-install-recommends "${common_packages[@]}" libwebkit2gtk-4.1-dev + else + sudo apt-get install -y --no-install-recommends "${common_packages[@]}" libwebkit2gtk-4.0-dev + fi +} + +ensure_node_and_pnpm() { + log "Preparing Node/pnpm" + + if ! command -v node >/dev/null 2>&1; then + warn "Node.js is not available in this image. Pin Node.js 20+ in the Codex environment settings or use a Codex universal image with Node installed." + exit 1 + fi + + node_major="$(node -p "process.versions.node.split('.')[0]")" + if [[ "$node_major" -lt 20 ]]; then + warn "Phokus expects Node.js 20+. Current version: $(node --version). Pin Node.js 20+ in Codex environment settings." + exit 1 + fi + + mkdir -p "$PNPM_HOME" + + if command -v corepack >/dev/null 2>&1; then + corepack enable + corepack prepare pnpm@latest --activate + fi + + if ! command -v pnpm >/dev/null 2>&1; then + npm install -g pnpm + fi + + log "Node: $(node --version)" + log "pnpm: $(pnpm --version)" +} + +ensure_rust() { + log "Preparing Rust toolchain" + + if ! command -v rustup >/dev/null 2>&1; then + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal + # shellcheck source=/dev/null + source "$HOME/.cargo/env" + fi + + rustup toolchain install stable --profile minimal + rustup default stable + rustup component add rustfmt clippy + + log "rustc: $(rustc --version)" + log "cargo: $(cargo --version)" +} + +install_js_dependencies() { + log "Installing frontend dependencies" + pnpm install --frozen-lockfile +} + +prefetch_rust_dependencies() { + log "Pre-fetching Rust dependencies for CPU-safe Tauri checks" + + # Phokus enables candle-cuda by default in Cargo.toml. Codex Cloud usually runs + # in a CPU Linux container, so use --no-default-features for checks/builds + # unless you intentionally configure a CUDA-capable environment. + cargo fetch --manifest-path src-tauri/Cargo.toml --locked + + # This is intentionally a check, not a full release build. It warms the Cargo + # cache and catches missing native packages without making setup painfully slow. + cargo check --manifest-path src-tauri/Cargo.toml --locked --no-default-features +} + +install_playwright_browsers() { + log "Installing Playwright Chromium dependencies for UI Lab/browser screenshots" + + # Safe even if no Playwright tests are present yet. Useful for Codex browser + # inspection against `pnpm dev:ui`. + pnpm exec playwright install --with-deps chromium || warn "Playwright browser install failed; UI work may still run, but browser automation/screenshots may need manual setup." +} + +print_next_steps() { + cat <<'EOF' + +[phokus-codex] Setup complete. + +Recommended Codex verification commands: + pnpm exec tsc --noEmit + pnpm build:vite + cargo check --manifest-path src-tauri/Cargo.toml --locked --no-default-features + +For visual UI work in Codex/browser environments: + pnpm dev:ui + open http://127.0.0.1:1422/?scenario=rich + +Other useful UI Lab scenarios: + http://127.0.0.1:1422/?scenario=empty + http://127.0.0.1:1422/?scenario=duplicates + http://127.0.0.1:1422/?scenario=errors + http://127.0.0.1:1422/?scenario=huge + +Avoid these in standard CPU-only Codex Cloud unless you have configured CUDA: + pnpm dev:app + pnpm build:app:cuda + cargo check --manifest-path src-tauri/Cargo.toml +EOF +} + +main() { + install_apt_packages + ensure_node_and_pnpm + ensure_rust + install_js_dependencies + prefetch_rust_dependencies + install_playwright_browsers + print_next_steps +} + +main "$@" -- 2.52.0 From 0036c0e8660ff035225a65c0471ae0b2bac43a23 Mon Sep 17 00:00:00 2001 From: LyAhn Date: Tue, 30 Jun 2026 11:22:02 +0100 Subject: [PATCH 2/3] Address Codex setup review feedback --- scripts/codex-cloud-setup.sh | 85 ++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 17 deletions(-) diff --git a/scripts/codex-cloud-setup.sh b/scripts/codex-cloud-setup.sh index 1062067..373d834 100644 --- a/scripts/codex-cloud-setup.sh +++ b/scripts/codex-cloud-setup.sh @@ -29,6 +29,7 @@ fi export CI=1 export PNPM_HOME="${PNPM_HOME:-$HOME/.local/share/pnpm}" +export PNPM_VERSION="${PNPM_VERSION:-10.20.0}" export PATH="$PNPM_HOME:$HOME/.cargo/bin:$PATH" # Persist useful shell defaults for the later Codex agent phase. Codex setup runs @@ -38,6 +39,7 @@ if ! grep -q "# Phokus Codex Cloud" "$HOME/.bashrc" 2>/dev/null; then # Phokus Codex Cloud export PNPM_HOME="${PNPM_HOME:-$HOME/.local/share/pnpm}" +export PNPM_VERSION="${PNPM_VERSION:-10.20.0}" export PATH="$PNPM_HOME:$HOME/.cargo/bin:$PATH" export CI=1 BASHRC @@ -49,13 +51,28 @@ install_apt_packages() { return 0 fi + local -a apt_cmd=(apt-get) + if [[ "$(id -u)" -ne 0 ]]; then + if command -v sudo >/dev/null 2>&1; then + apt_cmd=(sudo apt-get) + else + warn "apt-get is available but sudo is not. Re-run as root or add sudo to the image." + return 1 + fi + fi + log "Installing Linux system dependencies for Tauri, WebKit, SQLite/native crates, and browser tooling" - sudo apt-get update + "${apt_cmd[@]}" update + + # Tauri v2 / wry needs the WebKitGTK 4.1 libsoup3 development package. Do not + # fall back to libwebkit2gtk-4.0-dev: that is the libsoup2 variant and will + # still fail later during cargo check for the current dependency stack. + if ! apt-cache show libwebkit2gtk-4.1-dev >/dev/null 2>&1; then + warn "libwebkit2gtk-4.1-dev is unavailable in this apt source. Use a newer Ubuntu/Debian image or add a repository that provides WebKitGTK 4.1/libsoup3 development packages." + return 1 + fi - # Tauri v2 Linux builds need the WebKitGTK/AppIndicator/Rsvg stack. Some base - # images expose either the 4.1 or 4.0 WebKit development package, so try the - # modern package first and gracefully fall back. local common_packages=( build-essential curl @@ -68,26 +85,22 @@ install_apt_packages() { librsvg2-dev patchelf ca-certificates + libwebkit2gtk-4.1-dev ) - if apt-cache show libwebkit2gtk-4.1-dev >/dev/null 2>&1; then - sudo apt-get install -y --no-install-recommends "${common_packages[@]}" libwebkit2gtk-4.1-dev - else - sudo apt-get install -y --no-install-recommends "${common_packages[@]}" libwebkit2gtk-4.0-dev - fi + "${apt_cmd[@]}" install -y --no-install-recommends "${common_packages[@]}" } ensure_node_and_pnpm() { log "Preparing Node/pnpm" if ! command -v node >/dev/null 2>&1; then - warn "Node.js is not available in this image. Pin Node.js 20+ in the Codex environment settings or use a Codex universal image with Node installed." + warn "Node.js is not available in this image. Pin Node.js 20.19+ or 22.12+ in the Codex environment settings, or use a Codex universal image with Node installed." exit 1 fi - node_major="$(node -p "process.versions.node.split('.')[0]")" - if [[ "$node_major" -lt 20 ]]; then - warn "Phokus expects Node.js 20+. Current version: $(node --version). Pin Node.js 20+ in Codex environment settings." + if ! node -e 'const [major, minor, patch] = process.versions.node.split(".").map(Number); const ok = (major === 20 && (minor > 19 || (minor === 19 && patch >= 0))) || major > 22 || (major === 22 && (minor > 12 || (minor === 12 && patch >= 0))); process.exit(ok ? 0 : 1);'; then + warn "Phokus' locked Vite version expects Node.js ^20.19.0 or >=22.12.0. Current version: $(node --version). Pin a compatible Node version in Codex environment settings." exit 1 fi @@ -95,22 +108,60 @@ ensure_node_and_pnpm() { if command -v corepack >/dev/null 2>&1; then corepack enable - corepack prepare pnpm@latest --activate + corepack prepare "pnpm@${PNPM_VERSION}" --activate fi if ! command -v pnpm >/dev/null 2>&1; then - npm install -g pnpm + npm install -g "pnpm@${PNPM_VERSION}" fi log "Node: $(node --version)" log "pnpm: $(pnpm --version)" } +rustup_target_triple() { + case "$(uname -m)" in + x86_64 | amd64) printf 'x86_64-unknown-linux-gnu' ;; + aarch64 | arm64) printf 'aarch64-unknown-linux-gnu' ;; + *) + warn "Unsupported architecture for automatic rustup-init install: $(uname -m)" + return 1 + ;; + esac +} + +install_rustup_init() { + if ! command -v curl >/dev/null 2>&1; then + warn "curl is required to install rustup but was not found." + return 1 + fi + + local target_triple + target_triple="$(rustup_target_triple)" + + local rustup_url="https://static.rust-lang.org/rustup/dist/${target_triple}/rustup-init" + local rustup_sha_url="${rustup_url}.sha256" + local tmp_dir + tmp_dir="$(mktemp -d)" + + curl --proto '=https' --tlsv1.2 -fsSL "$rustup_url" -o "$tmp_dir/rustup-init" + curl --proto '=https' --tlsv1.2 -fsSL "$rustup_sha_url" -o "$tmp_dir/rustup-init.sha256" + + ( + cd "$tmp_dir" + sha256sum --check rustup-init.sha256 + chmod +x rustup-init + ./rustup-init -y --profile minimal --no-modify-path + ) + + rm -rf "$tmp_dir" +} + ensure_rust() { log "Preparing Rust toolchain" if ! command -v rustup >/dev/null 2>&1; then - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal + install_rustup_init # shellcheck source=/dev/null source "$HOME/.cargo/env" fi @@ -161,7 +212,7 @@ Recommended Codex verification commands: For visual UI work in Codex/browser environments: pnpm dev:ui - open http://127.0.0.1:1422/?scenario=rich + Visit: http://127.0.0.1:1422/?scenario=rich Other useful UI Lab scenarios: http://127.0.0.1:1422/?scenario=empty -- 2.52.0 From 52287605a0b2d3874f500fe0bb1b2ef2d709cf16 Mon Sep 17 00:00:00 2001 From: LyAhn Date: Tue, 30 Jun 2026 14:33:15 +0100 Subject: [PATCH 3/3] Use verified Codex setup script --- scripts/codex-cloud-setup.sh | 87 ++++++++---------------------------- 1 file changed, 18 insertions(+), 69 deletions(-) diff --git a/scripts/codex-cloud-setup.sh b/scripts/codex-cloud-setup.sh index 373d834..278f9f5 100644 --- a/scripts/codex-cloud-setup.sh +++ b/scripts/codex-cloud-setup.sh @@ -29,7 +29,6 @@ fi export CI=1 export PNPM_HOME="${PNPM_HOME:-$HOME/.local/share/pnpm}" -export PNPM_VERSION="${PNPM_VERSION:-10.20.0}" export PATH="$PNPM_HOME:$HOME/.cargo/bin:$PATH" # Persist useful shell defaults for the later Codex agent phase. Codex setup runs @@ -39,7 +38,6 @@ if ! grep -q "# Phokus Codex Cloud" "$HOME/.bashrc" 2>/dev/null; then # Phokus Codex Cloud export PNPM_HOME="${PNPM_HOME:-$HOME/.local/share/pnpm}" -export PNPM_VERSION="${PNPM_VERSION:-10.20.0}" export PATH="$PNPM_HOME:$HOME/.cargo/bin:$PATH" export CI=1 BASHRC @@ -51,28 +49,13 @@ install_apt_packages() { return 0 fi - local -a apt_cmd=(apt-get) - if [[ "$(id -u)" -ne 0 ]]; then - if command -v sudo >/dev/null 2>&1; then - apt_cmd=(sudo apt-get) - else - warn "apt-get is available but sudo is not. Re-run as root or add sudo to the image." - return 1 - fi - fi - log "Installing Linux system dependencies for Tauri, WebKit, SQLite/native crates, and browser tooling" - "${apt_cmd[@]}" update - - # Tauri v2 / wry needs the WebKitGTK 4.1 libsoup3 development package. Do not - # fall back to libwebkit2gtk-4.0-dev: that is the libsoup2 variant and will - # still fail later during cargo check for the current dependency stack. - if ! apt-cache show libwebkit2gtk-4.1-dev >/dev/null 2>&1; then - warn "libwebkit2gtk-4.1-dev is unavailable in this apt source. Use a newer Ubuntu/Debian image or add a repository that provides WebKitGTK 4.1/libsoup3 development packages." - return 1 - fi + sudo apt-get update + # Tauri v2 Linux builds need the WebKitGTK/AppIndicator/Rsvg stack. Some base + # images expose either the 4.1 or 4.0 WebKit development package, so try the + # modern package first and gracefully fall back. local common_packages=( build-essential curl @@ -85,22 +68,26 @@ install_apt_packages() { librsvg2-dev patchelf ca-certificates - libwebkit2gtk-4.1-dev ) - "${apt_cmd[@]}" install -y --no-install-recommends "${common_packages[@]}" + if apt-cache show libwebkit2gtk-4.1-dev >/dev/null 2>&1; then + sudo apt-get install -y --no-install-recommends "${common_packages[@]}" libwebkit2gtk-4.1-dev + else + sudo apt-get install -y --no-install-recommends "${common_packages[@]}" libwebkit2gtk-4.0-dev + fi } ensure_node_and_pnpm() { log "Preparing Node/pnpm" if ! command -v node >/dev/null 2>&1; then - warn "Node.js is not available in this image. Pin Node.js 20.19+ or 22.12+ in the Codex environment settings, or use a Codex universal image with Node installed." + warn "Node.js is not available in this image. Pin Node.js 20+ in the Codex environment settings or use a Codex universal image with Node installed." exit 1 fi - if ! node -e 'const [major, minor, patch] = process.versions.node.split(".").map(Number); const ok = (major === 20 && (minor > 19 || (minor === 19 && patch >= 0))) || major > 22 || (major === 22 && (minor > 12 || (minor === 12 && patch >= 0))); process.exit(ok ? 0 : 1);'; then - warn "Phokus' locked Vite version expects Node.js ^20.19.0 or >=22.12.0. Current version: $(node --version). Pin a compatible Node version in Codex environment settings." + node_major="$(node -p "process.versions.node.split('.')[0]")" + if [[ "$node_major" -lt 20 ]]; then + warn "Phokus expects Node.js 20+. Current version: $(node --version). Pin Node.js 20+ in Codex environment settings." exit 1 fi @@ -108,60 +95,22 @@ ensure_node_and_pnpm() { if command -v corepack >/dev/null 2>&1; then corepack enable - corepack prepare "pnpm@${PNPM_VERSION}" --activate + corepack prepare pnpm@latest --activate fi if ! command -v pnpm >/dev/null 2>&1; then - npm install -g "pnpm@${PNPM_VERSION}" + npm install -g pnpm fi log "Node: $(node --version)" log "pnpm: $(pnpm --version)" } -rustup_target_triple() { - case "$(uname -m)" in - x86_64 | amd64) printf 'x86_64-unknown-linux-gnu' ;; - aarch64 | arm64) printf 'aarch64-unknown-linux-gnu' ;; - *) - warn "Unsupported architecture for automatic rustup-init install: $(uname -m)" - return 1 - ;; - esac -} - -install_rustup_init() { - if ! command -v curl >/dev/null 2>&1; then - warn "curl is required to install rustup but was not found." - return 1 - fi - - local target_triple - target_triple="$(rustup_target_triple)" - - local rustup_url="https://static.rust-lang.org/rustup/dist/${target_triple}/rustup-init" - local rustup_sha_url="${rustup_url}.sha256" - local tmp_dir - tmp_dir="$(mktemp -d)" - - curl --proto '=https' --tlsv1.2 -fsSL "$rustup_url" -o "$tmp_dir/rustup-init" - curl --proto '=https' --tlsv1.2 -fsSL "$rustup_sha_url" -o "$tmp_dir/rustup-init.sha256" - - ( - cd "$tmp_dir" - sha256sum --check rustup-init.sha256 - chmod +x rustup-init - ./rustup-init -y --profile minimal --no-modify-path - ) - - rm -rf "$tmp_dir" -} - ensure_rust() { log "Preparing Rust toolchain" if ! command -v rustup >/dev/null 2>&1; then - install_rustup_init + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal # shellcheck source=/dev/null source "$HOME/.cargo/env" fi @@ -212,7 +161,7 @@ Recommended Codex verification commands: For visual UI work in Codex/browser environments: pnpm dev:ui - Visit: http://127.0.0.1:1422/?scenario=rich + open http://127.0.0.1:1422/?scenario=rich Other useful UI Lab scenarios: http://127.0.0.1:1422/?scenario=empty @@ -220,7 +169,7 @@ Other useful UI Lab scenarios: http://127.0.0.1:1422/?scenario=errors http://127.0.0.1:1422/?scenario=huge -Avoid these in standard CPU-only Codex Cloud unless you have configured CUDA: +Avoid the below in standard CPU-only Codex Cloud unless you have configured CUDA: pnpm dev:app pnpm build:app:cuda cargo check --manifest-path src-tauri/Cargo.toml -- 2.52.0