diff --git a/.devcontainer/devcontainer-lock.json b/.devcontainer/devcontainer-lock.json new file mode 100644 index 0000000..41f7e1d --- /dev/null +++ b/.devcontainer/devcontainer-lock.json @@ -0,0 +1,9 @@ +{ + "features": { + "ghcr.io/anthropics/devcontainer-features/claude-code:1.0": { + "version": "1.0.5", + "resolved": "ghcr.io/anthropics/devcontainer-features/claude-code@sha256:cfc2e7d3e9fd3b9b01f8d5cb158508a884c8c0ede2e23ed10f32dea5d4ffe69a", + "integrity": "sha256:cfc2e7d3e9fd3b9b01f8d5cb158508a884c8c0ede2e23ed10f32dea5d4ffe69a" + } + } +} diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..c828cf4 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,14 @@ +// For format details, see https://aka.ms/devcontainer.json. +{ + "name": "ddev-claude-cli", + "image": "mcr.microsoft.com/devcontainers/go:2-1.27-bookworm", + "features": { + "ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {}, + // DDEV needs a Docker daemon; this runs one inside the devcontainer. + "ghcr.io/devcontainers/features/docker-in-docker:2": {}, + // Official DDEV feature: installs ddev (and mkcert) for testing the add-on end to end. + "ghcr.io/ddev/ddev/install-ddev:latest": {} + }, + // ShellCheck for the add-on's bash scripts; bats + helpers are what the DDEV add-on template's tests use. + "postCreateCommand": "sudo apt-get update && sudo apt-get install -y --no-install-recommends shellcheck bats bats-assert bats-support bats-file" +} diff --git a/codex-cli/install.sh b/codex-cli/install.sh deleted file mode 100755 index 75799b9..0000000 --- a/codex-cli/install.sh +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env bash -#ddev-generated -set -euo pipefail - -# All Codex CLI state is stored under .ddev/codex-cli so it survives container -# rebuilds without being committed to the project repository. -PERSIST_BASE="${DDEV_APPROOT}/.ddev/codex-cli" -PERSIST_HOME="${PERSIST_BASE}/home" # replaces $HOME inside the container -PERSIST_CONFIG_HOME="${PERSIST_BASE}/config" # XDG_CONFIG_HOME (e.g. ~/.config) -PERSIST_DATA_HOME="${PERSIST_BASE}/data" # XDG_DATA_HOME (e.g. ~/.local/share) -PERSIST_STATE_HOME="${PERSIST_BASE}/state" # XDG_STATE_HOME (e.g. ~/.local/state) -PERSIST_BIN_DIR="${PERSIST_BASE}/bin" # directory that holds the codex binary -PERSIST_BIN="${PERSIST_BIN_DIR}/codex" # full path to the codex executable -PERSIST_GITIGNORE_GLOBAL="${PERSIST_HOME}/.gitignore_global" # mirrors $HOME/.gitignore_global - -# Capture the container's original HOME before we override it below, so we can -# seed the persisted gitignore from the container image on first run. -CONTAINER_HOME="${HOME:?HOME must be set}" -CONTAINER_GITIGNORE_GLOBAL="${CONTAINER_HOME}/.gitignore_global" - -# Ensure all persistence directories exist. -mkdir -p \ - "${PERSIST_HOME}" \ - "${PERSIST_CONFIG_HOME}" \ - "${PERSIST_DATA_HOME}" \ - "${PERSIST_STATE_HOME}" \ - "${PERSIST_BIN_DIR}" - -# Seed the persisted gitignore from the container image on first run only. -if [ -f "${CONTAINER_GITIGNORE_GLOBAL}" ] && [ ! -f "${PERSIST_GITIGNORE_GLOBAL}" ]; then - cp -f "${CONTAINER_GITIGNORE_GLOBAL}" "${PERSIST_GITIGNORE_GLOBAL}" -fi - -# Codex stores its standalone package tree under $HOME/.codex and links -# $CODEX_INSTALL_DIR/codex into that tree. Point HOME there before any install -# or health check so package data survives container restarts. -export HOME="${PERSIST_HOME}" -export CODEX_HOME="${PERSIST_HOME}/.codex" -export XDG_CONFIG_HOME="${PERSIST_CONFIG_HOME}" -export XDG_DATA_HOME="${PERSIST_DATA_HOME}" -export XDG_STATE_HOME="${PERSIST_STATE_HOME}" -export PATH="${PERSIST_BIN_DIR}:${HOME}/.local/bin:${PATH}" - -# If a persisted binary exists but fails to run (e.g. wrong architecture after -# a host OS change), remove it so the install step below fetches a fresh copy. -if [ -x "${PERSIST_BIN}" ] && ! "${PERSIST_BIN}" --version >/dev/null 2>&1; then - echo "Persisted Codex CLI binary is not runnable, reinstalling ..." - rm -f "${PERSIST_BIN}" -fi - -# Download and install the Codex CLI into the persisted bin directory. -if [ ! -x "${PERSIST_BIN}" ]; then - echo "Installing Codex CLI ..." - export CODEX_INSTALL_DIR="${PERSIST_BIN_DIR}" - export CODEX_NON_INTERACTIVE=1 - curl -fsSL https://github.com/openai/codex/releases/latest/download/install.sh | sh -fi - -# Verify the binary is present after installation. -if [ ! -x "${PERSIST_BIN}" ]; then - echo "Codex CLI installation completed but no executable was found at ${PERSIST_BIN}." >&2 - exit 1 -fi - -# Point git's global excludes file at the persisted copy when available, -# so git inside the container respects user-defined ignore patterns. -if command -v git >/dev/null 2>&1 && [ -f "${PERSIST_GITIGNORE_GLOBAL}" ]; then - CURRENT_EXCLUDESFILE="$(git config --global --get core.excludesfile || true)" - if [ "${CURRENT_EXCLUDESFILE}" != "${PERSIST_GITIGNORE_GLOBAL}" ]; then - git config --global core.excludesfile "${PERSIST_GITIGNORE_GLOBAL}" - fi -fi - -# Shared with the Claude side: keeps the add-on's artifacts out of the project's git -# even when only the codex installer runs. -GIT_EXCLUDE="${DDEV_APPROOT}/.ddev/claude-code/git-exclude.sh" -if [ -x "${GIT_EXCLUDE}" ]; then - "${GIT_EXCLUDE}" || true -fi - -echo "Codex CLI version: $("${PERSIST_BIN}" --version)" diff --git a/commands/web/codex b/commands/web/codex deleted file mode 100755 index 189be17..0000000 --- a/commands/web/codex +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash -#ddev-generated -## Description: Run Codex CLI inside the web container -## Usage: codex -## Example: "ddev codex --version" -set -euo pipefail - -INSTALL_SCRIPT="${DDEV_APPROOT}/.ddev/codex-cli/install.sh" -PERSIST_BASE="${DDEV_APPROOT}/.ddev/codex-cli" -PERSIST_BIN="${PERSIST_BASE}/bin/codex" - -"${INSTALL_SCRIPT}" - -export HOME="${PERSIST_BASE}/home" -export CODEX_HOME="${PERSIST_BASE}/home/.codex" -export XDG_CONFIG_HOME="${PERSIST_BASE}/config" -export XDG_DATA_HOME="${PERSIST_BASE}/data" -export XDG_STATE_HOME="${PERSIST_BASE}/state" -export PATH="${PERSIST_BASE}/bin:${HOME}/.local/bin:${PATH}" -unset SSH_AUTH_SOCK - -cd "${DDEV_APPROOT}" -exec "${PERSIST_BIN}" --sandbox danger-full-access --ask-for-approval on-request "$@"