Skip to content

Commit 23ac9cc

Browse files
committed
test: add codex npm plugin Docker live proof
1 parent 66db189 commit 23ac9cc

13 files changed

Lines changed: 738 additions & 6 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Docs: https://docs.openclaw.ai
1111
### Fixes
1212

1313
- Status: show the `openai-codex` OAuth profile for `openai/gpt-*` sessions running through the native Codex runtime instead of reporting auth as unknown. (#76197) Thanks @mbelinky.
14+
- Plugins/Codex: allow the official npm Codex plugin to install without the unsafe-install override, keep `/codex` command ownership, and cover the real npm Docker live path through managed `.openclaw/npm` dependencies plus uninstall failure proof.
1415

1516
## 2026.5.2
1617

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,7 @@
15271527
"test:docker:live-cli-backend:gemini:resume": "OPENCLAW_LIVE_CLI_BACKEND_MODEL=google-gemini-cli/gemini-3-flash-preview OPENCLAW_LIVE_CLI_BACKEND_RESUME_PROBE=1 bash scripts/test-live-cli-backend-docker.sh",
15281528
"test:docker:live-codex-bind": "OPENCLAW_LIVE_CODEX_BIND=1 OPENCLAW_LIVE_CODEX_TEST_FILES=src/gateway/gateway-codex-bind.live.test.ts bash scripts/test-live-codex-harness-docker.sh",
15291529
"test:docker:live-codex-harness": "bash scripts/test-live-codex-harness-docker.sh",
1530+
"test:docker:live-codex-npm-plugin": "bash scripts/e2e/codex-npm-plugin-live-docker.sh",
15301531
"test:docker:live-gateway": "bash scripts/test-live-gateway-models-docker.sh",
15311532
"test:docker:live-gateway:claude": "OPENCLAW_LIVE_GATEWAY_PROVIDERS=claude-cli OPENCLAW_LIVE_GATEWAY_MODELS=claude-cli/claude-sonnet-4-6 bash scripts/test-live-gateway-models-docker.sh",
15321533
"test:docker:live-gateway:codex": "OPENCLAW_LIVE_GATEWAY_PROVIDERS=codex-cli OPENCLAW_LIVE_GATEWAY_MODELS=codex-cli/gpt-5.5 bash scripts/test-live-gateway-models-docker.sh",
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
#!/usr/bin/env bash
2+
# Installs OpenClaw from a prepared package tarball, installs @openclaw/codex
3+
# from the real npm registry, and verifies a live Codex app-server turn.
4+
set -euo pipefail
5+
6+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
7+
source "$ROOT_DIR/scripts/lib/docker-e2e-image.sh"
8+
source "$ROOT_DIR/scripts/lib/docker-e2e-package.sh"
9+
10+
IMAGE_NAME="$(docker_e2e_resolve_image "openclaw-codex-npm-plugin-live-e2e" OPENCLAW_CODEX_NPM_PLUGIN_E2E_IMAGE)"
11+
DOCKER_TARGET="${OPENCLAW_CODEX_NPM_PLUGIN_DOCKER_TARGET:-bare}"
12+
HOST_BUILD="${OPENCLAW_CODEX_NPM_PLUGIN_HOST_BUILD:-1}"
13+
PACKAGE_TGZ="${OPENCLAW_CURRENT_PACKAGE_TGZ:-}"
14+
PROFILE_FILE="${OPENCLAW_CODEX_NPM_PLUGIN_PROFILE_FILE:-$HOME/.profile}"
15+
16+
docker_e2e_build_or_reuse "$IMAGE_NAME" codex-npm-plugin-live "$ROOT_DIR/scripts/e2e/Dockerfile" "$ROOT_DIR" "$DOCKER_TARGET"
17+
18+
prepare_package_tgz() {
19+
if [ -n "$PACKAGE_TGZ" ]; then
20+
PACKAGE_TGZ="$(docker_e2e_prepare_package_tgz codex-npm-plugin-live "$PACKAGE_TGZ")"
21+
return 0
22+
fi
23+
if [ "$HOST_BUILD" = "0" ] && [ -z "${OPENCLAW_CURRENT_PACKAGE_TGZ:-}" ]; then
24+
echo "OPENCLAW_CODEX_NPM_PLUGIN_HOST_BUILD=0 requires OPENCLAW_CURRENT_PACKAGE_TGZ" >&2
25+
exit 1
26+
fi
27+
PACKAGE_TGZ="$(docker_e2e_prepare_package_tgz codex-npm-plugin-live)"
28+
}
29+
30+
prepare_package_tgz
31+
32+
PROFILE_MOUNT=()
33+
PROFILE_STATUS="none"
34+
if [ -f "$PROFILE_FILE" ] && [ -r "$PROFILE_FILE" ]; then
35+
PROFILE_MOUNT=(-v "$PROFILE_FILE":/home/appuser/.profile:ro)
36+
PROFILE_STATUS="$PROFILE_FILE"
37+
fi
38+
39+
docker_e2e_package_mount_args "$PACKAGE_TGZ"
40+
run_log="$(docker_e2e_run_log codex-npm-plugin-live)"
41+
OPENCLAW_TEST_STATE_SCRIPT_B64="$(docker_e2e_test_state_shell_b64 codex-npm-plugin-live empty)"
42+
43+
echo "Running Codex npm plugin live Docker E2E..."
44+
echo "Profile file: $PROFILE_STATUS"
45+
if ! docker_e2e_run_with_harness \
46+
-e COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \
47+
-e OPENCLAW_CODEX_NPM_PLUGIN_MODEL="${OPENCLAW_CODEX_NPM_PLUGIN_MODEL:-codex/gpt-5.4}" \
48+
-e OPENCLAW_CODEX_NPM_PLUGIN_SPEC="${OPENCLAW_CODEX_NPM_PLUGIN_SPEC:-npm:@openclaw/codex@beta}" \
49+
-e "OPENCLAW_TEST_STATE_SCRIPT_B64=$OPENCLAW_TEST_STATE_SCRIPT_B64" \
50+
"${DOCKER_E2E_PACKAGE_ARGS[@]}" \
51+
"${PROFILE_MOUNT[@]}" \
52+
-i "$IMAGE_NAME" bash -s >"$run_log" 2>&1 <<'EOF'; then
53+
set -euo pipefail
54+
55+
source scripts/lib/openclaw-e2e-instance.sh
56+
openclaw_e2e_eval_test_state_from_b64 "${OPENCLAW_TEST_STATE_SCRIPT_B64:?missing OPENCLAW_TEST_STATE_SCRIPT_B64}"
57+
export NPM_CONFIG_PREFIX="$HOME/.npm-global"
58+
export npm_config_prefix="$NPM_CONFIG_PREFIX"
59+
export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"
60+
export NPM_CONFIG_CACHE="${NPM_CONFIG_CACHE:-$XDG_CACHE_HOME/npm}"
61+
export npm_config_cache="$NPM_CONFIG_CACHE"
62+
export PATH="$NPM_CONFIG_PREFIX/bin:$PATH"
63+
export OPENCLAW_AGENT_HARNESS_FALLBACK=none
64+
65+
for profile_path in "$HOME/.profile" /home/appuser/.profile; do
66+
if [ -f "$profile_path" ] && [ -r "$profile_path" ]; then
67+
set +e +u
68+
source "$profile_path"
69+
set -euo pipefail
70+
break
71+
fi
72+
done
73+
if [ -z "${OPENAI_API_KEY:-}" ]; then
74+
echo "ERROR: OPENAI_API_KEY was not available after sourcing ~/.profile." >&2
75+
exit 1
76+
fi
77+
export OPENAI_API_KEY
78+
if [ -n "${OPENAI_BASE_URL:-}" ]; then
79+
export OPENAI_BASE_URL
80+
fi
81+
82+
CODEX_PLUGIN_SPEC="${OPENCLAW_CODEX_NPM_PLUGIN_SPEC:?missing OPENCLAW_CODEX_NPM_PLUGIN_SPEC}"
83+
MODEL_REF="${OPENCLAW_CODEX_NPM_PLUGIN_MODEL:?missing OPENCLAW_CODEX_NPM_PLUGIN_MODEL}"
84+
SESSION_ID="codex-npm-plugin-live"
85+
SUCCESS_MARKER="OPENCLAW-CODEX-NPM-PLUGIN-LIVE-OK"
86+
87+
dump_debug_logs() {
88+
local status="$1"
89+
echo "Codex npm plugin live scenario failed with exit code $status" >&2
90+
openclaw_e2e_dump_logs \
91+
/tmp/openclaw-install.log \
92+
/tmp/openclaw-codex-plugin-install.log \
93+
/tmp/openclaw-codex-plugin-enable.log \
94+
/tmp/openclaw-codex-plugins-list.json \
95+
/tmp/openclaw-codex-plugin-inspect.json \
96+
/tmp/openclaw-codex-preflight.log \
97+
/tmp/openclaw-codex-agent.json \
98+
/tmp/openclaw-codex-agent.err \
99+
/tmp/openclaw-codex-plugin-uninstall.log \
100+
/tmp/openclaw-codex-plugins-list-after-uninstall.json \
101+
/tmp/openclaw-codex-agent-after-uninstall.json \
102+
/tmp/openclaw-codex-agent-after-uninstall.err
103+
}
104+
trap 'status=$?; dump_debug_logs "$status"; exit "$status"' ERR
105+
106+
mkdir -p "$NPM_CONFIG_PREFIX" "$XDG_CACHE_HOME" "$NPM_CONFIG_CACHE"
107+
chmod 700 "$XDG_CACHE_HOME" "$NPM_CONFIG_CACHE" || true
108+
109+
openclaw_e2e_install_package /tmp/openclaw-install.log
110+
command -v openclaw >/dev/null
111+
112+
echo "Installing Codex plugin from npm: $CODEX_PLUGIN_SPEC"
113+
openclaw plugins install "$CODEX_PLUGIN_SPEC" --force >/tmp/openclaw-codex-plugin-install.log 2>&1
114+
115+
node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs configure "$MODEL_REF"
116+
117+
echo "Enabling Codex plugin..."
118+
openclaw plugins enable codex >/tmp/openclaw-codex-plugin-enable.log 2>&1
119+
120+
openclaw plugins list --json >/tmp/openclaw-codex-plugins-list.json
121+
openclaw plugins inspect codex --runtime --json >/tmp/openclaw-codex-plugin-inspect.json
122+
node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-plugin "$CODEX_PLUGIN_SPEC"
123+
node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-npm-deps
124+
125+
CODEX_BIN="$(node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs print-codex-bin)"
126+
printf '%s\n' "$OPENAI_API_KEY" | "$CODEX_BIN" login --with-api-key >/dev/null
127+
128+
echo "Running Codex CLI preflight via managed npm dependency..."
129+
"$CODEX_BIN" exec \
130+
--json \
131+
--color never \
132+
--skip-git-repo-check \
133+
"Reply exactly: ${SUCCESS_MARKER}-PREFLIGHT" >/tmp/openclaw-codex-preflight.log 2>&1
134+
node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-preflight "${SUCCESS_MARKER}-PREFLIGHT"
135+
136+
echo "Running OpenClaw local agent turn through npm-installed Codex plugin..."
137+
openclaw agent --local \
138+
--agent main \
139+
--session-id "$SESSION_ID" \
140+
--model "$MODEL_REF" \
141+
--message "Reply exactly: $SUCCESS_MARKER" \
142+
--thinking low \
143+
--timeout 420 \
144+
--json >/tmp/openclaw-codex-agent.json 2>/tmp/openclaw-codex-agent.err
145+
146+
node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-agent-turn "$SUCCESS_MARKER" "$SESSION_ID" "$MODEL_REF"
147+
148+
echo "Uninstalling Codex plugin and verifying the configured harness now fails..."
149+
openclaw plugins uninstall codex --force >/tmp/openclaw-codex-plugin-uninstall.log 2>&1
150+
openclaw plugins list --json >/tmp/openclaw-codex-plugins-list-after-uninstall.json
151+
node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-uninstalled
152+
153+
set +e
154+
openclaw agent --local \
155+
--agent main \
156+
--session-id "${SESSION_ID}-after-uninstall" \
157+
--model "$MODEL_REF" \
158+
--message "Reply exactly: ${SUCCESS_MARKER}-AFTER-UNINSTALL" \
159+
--thinking low \
160+
--timeout 120 \
161+
--json >/tmp/openclaw-codex-agent-after-uninstall.json 2>/tmp/openclaw-codex-agent-after-uninstall.err
162+
after_uninstall_status=$?
163+
set -e
164+
node scripts/e2e/lib/codex-npm-plugin-live/assertions.mjs assert-agent-error "$after_uninstall_status"
165+
166+
echo "Codex npm plugin live Docker E2E passed"
167+
EOF
168+
docker_e2e_print_log "$run_log"
169+
rm -f "$run_log"
170+
exit 1
171+
fi
172+
173+
rm -f "$run_log"
174+
echo "Codex npm plugin live Docker E2E passed"

0 commit comments

Comments
 (0)