diff --git a/.github/scripts/install-code-release.sh b/.github/scripts/install-code-release.sh new file mode 100755 index 000000000000..47e5da01ef52 --- /dev/null +++ b/.github/scripts/install-code-release.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -euo pipefail + +dest_dir="${1:-.github/auto/code-bin}" +repo="${GITHUB_REPOSITORY:-cbusillo/code}" + +case "$(uname -s)-$(uname -m)" in +Linux-x86_64) target="x86_64-unknown-linux-musl" ;; +Linux-aarch64 | Linux-arm64) target="aarch64-unknown-linux-musl" ;; +Darwin-x86_64) target="x86_64-apple-darwin" ;; +Darwin-arm64) target="aarch64-apple-darwin" ;; +*) + echo "unsupported platform for Code release bootstrap: $(uname -s)-$(uname -m)" >&2 + exit 1 + ;; +esac + +asset="code-${target}.tar.gz" +url="https://github.com/${repo}/releases/latest/download/${asset}" + +mkdir -p "$dest_dir" +tmp_dir="$(mktemp -d)" +trap 'rm -rf "$tmp_dir"' EXIT + +curl_args=(-fL --retry 3 --retry-delay 2) +if [ -n "${GITHUB_TOKEN:-}" ]; then + curl_args+=(-H "Authorization: Bearer ${GITHUB_TOKEN}") +fi + +curl "${curl_args[@]}" "$url" -o "$tmp_dir/$asset" +tar -xzf "$tmp_dir/$asset" -C "$tmp_dir" +install -m 0755 "$tmp_dir/code-${target}" "$dest_dir/code" +"$dest_dir/code" --version diff --git a/.github/workflows/issue-code.yml b/.github/workflows/issue-code.yml index 1ebc69e456ac..aa9c7b3666be 100644 --- a/.github/workflows/issue-code.yml +++ b/.github/workflows/issue-code.yml @@ -170,6 +170,7 @@ jobs: run: | set -euo pipefail ./build-fast.sh + echo "CODE_BIN=${CARGO_TARGET_DIR}/dev-fast/code" >> "$GITHUB_ENV" - name: Prepare agent workspace files env: @@ -273,7 +274,7 @@ jobs: STRICT_CARGO_HOME="1" \ GIT_TERMINAL_PROMPT="0" \ GIT_ASKPASS="/bin/false" \ - npx -y @just-every/code@latest \ + "$CODE_BIN" \ exec \ -s workspace-write \ -c sandbox_workspace_write.network_access=true \ diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml index 4a624e42ec03..91ebc2530ab4 100644 --- a/.github/workflows/issue-comment.yml +++ b/.github/workflows/issue-comment.yml @@ -286,6 +286,12 @@ jobs: PORT=5056 LOG_DEST=stdout EXIT_ON_5XX=1 RESPONSES_BETA="responses=v1" node scripts/openai-proxy.js > .github/auto/openai-proxy.log 2>&1 & for i in {1..30}; do if nc -z 127.0.0.1 5056; then break; else sleep 0.2; fi; done || true + - name: Install Code from GitHub Release + if: steps.meta.outputs.pr_number && env.OPENAI_API_KEY != '' + env: + GITHUB_TOKEN: ${{ github.token }} + run: .github/scripts/install-code-release.sh .github/auto/code-bin + - name: Print proxy startup log tail if: steps.meta.outputs.pr_number && env.OPENAI_API_KEY != '' run: | @@ -340,7 +346,7 @@ jobs: set +e { printf '%s' "$PROMPT" | env -i PATH="$SAFE_PATH" HOME="$SAFE_HOME" \ OPENAI_API_KEY="x" OPENAI_BASE_URL="http://127.0.0.1:5056/v1" \ - npx -y @just-every/code@latest exec -s read-only --cd "$GITHUB_WORKSPACE" --skip-git-repo-check -; } \ + .github/auto/code-bin/code exec -s read-only --cd "$GITHUB_WORKSPACE" --skip-git-repo-check -; } \ 2>&1 | tee .github/auto/AGENT_OUT.txt true set -e @@ -543,6 +549,12 @@ jobs: PORT=5056 LOG_DEST=stdout EXIT_ON_5XX=1 RESPONSES_BETA="responses=v1" node scripts/openai-proxy.js > .github/auto/openai-proxy.log 2>&1 & for i in {1..30}; do if nc -z 127.0.0.1 5056; then break; else sleep 0.2; fi; done || true + - name: Install Code from GitHub Release + if: env.OPENAI_API_KEY != '' + env: + GITHUB_TOKEN: ${{ github.token }} + run: .github/scripts/install-code-release.sh .github/auto/code-bin + - name: Print proxy startup log tail if: env.OPENAI_API_KEY != '' run: | @@ -578,7 +590,7 @@ jobs: RUSTUP_HOME="$GITHUB_WORKSPACE/.cargo-home/rustup" \ CARGO_TARGET_DIR="$GITHUB_WORKSPACE/${RUST_WORKSPACE_DIR}/target" \ STRICT_CARGO_HOME="1" \ - npx -y @just-every/code@latest exec -s read-only --cd "$GITHUB_WORKSPACE" --skip-git-repo-check -; } \ + .github/auto/code-bin/code exec -s read-only --cd "$GITHUB_WORKSPACE" --skip-git-repo-check -; } \ 2>&1 | tee .github/auto/TRIAGE_AGENT_OUT.txt true set -e diff --git a/.github/workflows/upstream-merge.yml b/.github/workflows/upstream-merge.yml index 65a823af537a..cf100d269be2 100644 --- a/.github/workflows/upstream-merge.yml +++ b/.github/workflows/upstream-merge.yml @@ -349,6 +349,7 @@ jobs: run: | set -euo pipefail ./build-fast.sh + echo "CODE_BIN=${CARGO_TARGET_DIR}/dev-fast/code" >> "$GITHUB_ENV" - name: Setup Node.js if: steps.check_upstream.outputs.skip != 'true' @@ -621,8 +622,7 @@ jobs: OPENAI_BASE_URL="http://127.0.0.1:5055/v1" \ OPENAI_API_BASE="http://127.0.0.1:5055/v1" \ GH_TOKEN="$GH_TOKEN" \ - npm_config_cache="$SAFE_HOME/.npm" \ - npx -y @just-every/code@latest \ + "$CODE_BIN" \ auto \ --goal-file .github/auto/AUTO_GOAL.md \ --max-attempts 3 \ @@ -738,8 +738,7 @@ jobs: OPENAI_API_BASE="http://127.0.0.1:5055/v1" \ GH_TOKEN="$GH_TOKEN" \ RUSTC_WRAPPER="sccache" SCCACHE_GHA_ENABLED="true" SCCACHE_IDLE_TIMEOUT="1800" SCCACHE_CACHE_SIZE="5G" \ - npm_config_cache="$SAFE_HOME/.npm" \ - npx -y @just-every/code@latest \ + "$CODE_BIN" \ exec \ -s workspace-write \ -c sandbox_workspace_write.allow_git_writes=true \ diff --git a/README.md b/README.md index b345256cfd6c..393863168672 100644 --- a/README.md +++ b/README.md @@ -80,17 +80,20 @@ ### Run ```bash -npx -y @just-every/code +code ``` ### Install & Run ```bash -npm install -g @just-every/code -code // or `coder` if you're using VS Code +just local-code-rebuild +code ``` -Note: If another tool already provides a `code` command (e.g. VS Code), our CLI is also installed as `coder`. Use `coder` to avoid conflicts. +Use `code update-check` to inspect the current GitHub Release manifest and +`code update --yes` to install a newer verified direct binary when one is +available. npm and Homebrew publishing are deferred unless package-manager +distribution becomes intentional again. **Authenticate** (one of the following): - **Sign in with ChatGPT** (Plus/Pro/Team; uses models available to your plan) diff --git a/code-rs/tui/src/updates.rs b/code-rs/tui/src/updates.rs index a9a0f3ce89e5..e00bcb496b31 100644 --- a/code-rs/tui/src/updates.rs +++ b/code-rs/tui/src/updates.rs @@ -144,10 +144,10 @@ struct ReleaseInfo { } const VERSION_FILENAME: &str = "version.json"; -const LATEST_RELEASE_URL: &str = "https://api.github.com/repos/just-every/code/releases/latest"; -const CURRENT_RELEASE_REPO: &str = "just-every/code"; -const LEGACY_RELEASE_REPO: &str = "openai/codex"; -pub const CODE_RELEASE_URL: &str = "https://github.com/just-every/code/releases/latest"; +const LATEST_RELEASE_URL: &str = "https://api.github.com/repos/cbusillo/code/releases/latest"; +const CURRENT_RELEASE_REPO: &str = "cbusillo/code"; +const LEGACY_RELEASE_REPO: &str = "just-every/code"; +pub const CODE_RELEASE_URL: &str = "https://github.com/cbusillo/code/releases/latest"; const CACHE_TTL_HOURS: i64 = 20; const MAX_CLOCK_SKEW_MINUTES: i64 = 5; @@ -179,37 +179,20 @@ fn version_filepath(config: &Config) -> PathBuf { } pub fn resolve_upgrade_resolution() -> UpgradeResolution { - if std::env::var_os("CODEX_MANAGED_BY_NPM").is_some() { + if let Ok(exe_path) = std::env::current_exe() { return UpgradeResolution::Command { command: vec![ - "npm".to_string(), - "install".to_string(), - "-g".to_string(), - "@just-every/code@latest".to_string(), + exe_path.display().to_string(), + "update".to_string(), + "--yes".to_string(), ], - display: "npm install -g @just-every/code@latest".to_string(), + display: "code update --yes".to_string(), }; } - #[cfg(target_os = "macos")] - { - if let Ok(exe_path) = std::env::current_exe() { - if exe_path.starts_with("/opt/homebrew") || exe_path.starts_with("/usr/local") { - return UpgradeResolution::Command { - command: vec![ - "brew".to_string(), - "upgrade".to_string(), - "code".to_string(), - ], - display: "brew upgrade code".to_string(), - }; - } - } - } - UpgradeResolution::Manual { instructions: format!( - "Download the latest release from {CODE_RELEASE_URL} and replace the installed binary." + "Run `code update --yes`, or download the latest release from {CODE_RELEASE_URL} and replace the installed binary." ), } } @@ -598,12 +581,7 @@ async fn fetch_latest_version(originator: &str) -> anyhow::Result { .json::() .await?; - // Support both tagging schemes: - // - "rust-vX.Y.Z" (legacy Rust-release workflow) - // - "vX.Y.Z" (general release workflow) - let latest_version = if let Some(v) = latest_tag_name.strip_prefix("rust-v") { - v.to_string() - } else if let Some(v) = latest_tag_name.strip_prefix('v') { + let latest_version = if let Some(v) = latest_tag_name.strip_prefix('v') { v.to_string() } else { // As a last resort, accept the raw tag if it looks like semver @@ -611,7 +589,7 @@ async fn fetch_latest_version(originator: &str) -> anyhow::Result { match parse_version(&latest_tag_name) { Some(_) => latest_tag_name.clone(), None => anyhow::bail!( - "Failed to parse latest tag name '{}': expected 'rust-vX.Y.Z' or 'vX.Y.Z'", + "Failed to parse latest tag name '{}': expected 'vX.Y.Z'", latest_tag_name ), } @@ -702,6 +680,21 @@ mod tests { fs::write(path, format!("{}\n", info)).expect("write version cache"); } + #[test] + fn upgrade_resolution_uses_cli_updater() { + match resolve_upgrade_resolution() { + UpgradeResolution::Command { command, display } => { + assert!(command.len() >= 3); + assert_eq!(command[command.len() - 2], "update"); + assert_eq!(command[command.len() - 1], "--yes"); + assert_eq!(display, "code update --yes"); + } + UpgradeResolution::Manual { instructions } => { + assert!(instructions.contains("code update --yes")); + } + } + } + #[test] fn read_version_info_discard_legacy_repo_cache() { let dir = tempdir().unwrap(); diff --git a/codex-cli/scripts/windows-cleanup.ps1 b/codex-cli/scripts/windows-cleanup.ps1 index 56251e89e607..c6798e71410d 100644 --- a/codex-cli/scripts/windows-cleanup.ps1 +++ b/codex-cli/scripts/windows-cleanup.ps1 @@ -28,5 +28,4 @@ Get-ChildItem -LiteralPath (Join-Path $npmRoot "@just-every") -Force -ErrorActio try { Remove-Item -LiteralPath $_.FullName -Recurse -Force -ErrorAction Stop } catch {} } -Write-Host "Cleanup complete. You can now run: npm install -g @just-every/code@latest" - +Write-Host "Cleanup complete. Install the current GitHub Release or run: code update --yes" diff --git a/docs/advanced.md b/docs/advanced.md index 23c3252babb4..f6f17387b328 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -7,7 +7,7 @@ Run Every Code headless in pipelines. Example GitHub Action step: ```yaml - name: Update changelog via Code run: | - npm install -g @just-every/code + just local-code-rebuild export OPENAI_API_KEY="${{ secrets.OPENAI_KEY }}" code exec --full-auto "update CHANGELOG for next release" ``` diff --git a/docs/install.md b/docs/install.md index 675fa0366c0c..7e7c5463b63d 100644 --- a/docs/install.md +++ b/docs/install.md @@ -16,7 +16,7 @@ GitHub Releases also contain a [DotSlash](https://dotslash-cli.com/) shim named ```bash # Clone the repository and navigate to the workspace root. -git clone https://github.com/just-every/code.git +git clone https://github.com/cbusillo/code.git cd code # Install the Rust toolchain, if necessary. @@ -26,8 +26,9 @@ source "$HOME/.cargo/env" # Build everything (CLI, TUI, MCP servers). This is the same check CI runs. ./build-fast.sh -# Launch the TUI with a sample prompt. -./target/debug/code -- "explain this codebase to me" +# Install the PATH-resolved local binary and launch the TUI. +just local-code-rebuild +code -- "explain this codebase to me" ``` > [!NOTE] diff --git a/docs/integration-zed.md b/docs/integration-zed.md index 627604ac3497..7d40e93499a2 100644 --- a/docs/integration-zed.md +++ b/docs/integration-zed.md @@ -6,20 +6,20 @@ To point Zed at Every Code's (Code) ACP server, add this block to `settings.json { "agent_servers": { "Code": { - "command": "npx", - "args": ["-y", "@just-every/code", "acp"] + "command": "code", + "args": ["acp"] } } } ``` -Adjust the `command` or `args` only if you pin a different version or use a globally installed binary. +Adjust `command` to an absolute binary path if Zed cannot find `code` on PATH. ## Zed prerequisites - Zed Stable `0.201.5` (released August 27, 2025) or newer adds ACP support with the Agent Panel. Update via `Zed → Check for Updates` before wiring Every Code in. Zed’s docs call out ACP as the mechanism powering Gemini CLI and other external agents. - External agents live inside the Agent Panel (`cmd-?`). Use the `+` button to start a new thread and pick `Code` (Every Code) from the external agent list. Zed runs our CLI as a subprocess over JSON‑RPC, so all prompts and diff previews stay local. -- Zed installs dependencies per entry automatically. If you keep `command = "npx"`, Zed will download the published `@just-every/code` package the first time you trigger the integration. +- Zed launches the configured command directly. Use the repo-built or GitHub Release binary instead of package-manager shims so the integration follows the same update source as the terminal CLI. ## How Every Code implements ACP @@ -35,7 +35,7 @@ write_text_file = { mcp_server = "zed", tool_name = "writeTextFile" } ``` Zed wires these tools automatically when you add the Code (Every Code) agent, so the identifiers above match the defaults. -- The CLI entry point (`npx @just-every/code acp`) is a thin wrapper over the Rust binary (`cargo run -p code-mcp-server -- --stdio`) that ships alongside the rest of Every Code. Build-from-source workflows plug in by swapping `command` for an absolute path to that binary. +- The CLI entry point (`code acp`) runs the Rust MCP server that ships alongside the rest of Every Code. Build-from-source workflows plug in by swapping `command` for an absolute path to that binary. ## Tips and troubleshooting diff --git a/scripts/local/rebuild-path-code.sh b/scripts/local/rebuild-path-code.sh index 8daa7848cd4e..05ecf8a28cf3 100755 --- a/scripts/local/rebuild-path-code.sh +++ b/scripts/local/rebuild-path-code.sh @@ -33,7 +33,7 @@ if [[ -n "$code_version" ]]; then echo "Embedding CODE_VERSION=$code_version" CODE_VERSION="$code_version" cargo build --manifest-path "$code_rs_root/Cargo.toml" -p code-cli --release else - echo "warning: could not resolve CODE_VERSION from rust-v tags; building without override" >&2 + echo "warning: could not resolve CODE_VERSION from package metadata; building without override" >&2 cargo build --manifest-path "$code_rs_root/Cargo.toml" -p code-cli --release fi trap - EXIT