File size: 5,466 Bytes
5bee529
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d68f646
5bee529
 
 
 
 
 
d68f646
5bee529
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/usr/bin/env bash
set -euo pipefail

PORT="${PORT:-7860}"

if [[ -z "${PASSWORD:-}" && -z "${HASHED_PASSWORD:-}" ]]; then
  echo "[ERROR] Missing PASSWORD/HASHED_PASSWORD secret."
  exit 1
fi

if [[ -d "/data" ]]; then
  WORKDIR="/data/workspace"
  EXT_DIR="/data/code-server/extensions"
  USER_DATA_DIR="/data/code-server/user-data"
  CODEX_DIR="/data/.codex"
else
  WORKDIR="${HOME}/workspace"
  EXT_DIR="${HOME}/.local/share/code-server/extensions"
  USER_DATA_DIR="${HOME}/.local/share/code-server/user-data"
  CODEX_DIR="${HOME}/.codex"
fi

mkdir -p "$WORKDIR" "$EXT_DIR" "$USER_DATA_DIR" "${USER_DATA_DIR}/User" "${HOME}/.config/code-server" "$CODEX_DIR"

cat > "${HOME}/.config/code-server/config.yaml" <<EOF
bind-addr: 0.0.0.0:${PORT}
auth: password
cert: false
EOF

if [[ -n "${HASHED_PASSWORD:-}" ]]; then
  echo "hashed-password: ${HASHED_PASSWORD}" >> "${HOME}/.config/code-server/config.yaml"
else
  echo "password: ${PASSWORD}" >> "${HOME}/.config/code-server/config.yaml"
fi

# Codex config.toml
: "${CODEX_MODEL_PROVIDER:=sub2api}"
: "${CODEX_MODEL:=gpt-5.4}"
: "${CODEX_REASONING_EFFORT:=xhigh}"
: "${CODEX_NETWORK_ACCESS:=enabled}"
: "${CODEX_DISABLE_RESPONSE_STORAGE:=true}"
: "${CODEX_WSL_ACK:=true}"
: "${CODEX_VERBOSITY:=high}"
: "${CODEX_PROVIDER_NAME:=sub2api}"
: "${CODEX_BASE_URL:=https://cacodex-sub2api.hf.space}"
: "${CODEX_WIRE_API:=responses}"
: "${CODEX_REQUIRES_OPENAI_AUTH:=true}"
: "${PLAYWRIGHT_MCP_ENABLE:=true}"
: "${PLAYWRIGHT_MCP_HOST:=127.0.0.1}"
: "${PLAYWRIGHT_MCP_PORT:=8931}"
: "${PLAYWRIGHT_MCP_URL:=http://${PLAYWRIGHT_MCP_HOST}:${PLAYWRIGHT_MCP_PORT}/mcp}"

cat > "${CODEX_DIR}/config.toml" <<EOF
model_provider = "${CODEX_MODEL_PROVIDER}"
model = "${CODEX_MODEL}"
model_reasoning_effort = "${CODEX_REASONING_EFFORT}"
network_access = "${CODEX_NETWORK_ACCESS}"
disable_response_storage = ${CODEX_DISABLE_RESPONSE_STORAGE}
windows_wsl_setup_acknowledged = ${CODEX_WSL_ACK}
model_verbosity = "${CODEX_VERBOSITY}"

[model_providers.${CODEX_PROVIDER_NAME}]
name = "${CODEX_PROVIDER_NAME}"
base_url = "${CODEX_BASE_URL}"
wire_api = "${CODEX_WIRE_API}"
requires_openai_auth = ${CODEX_REQUIRES_OPENAI_AUTH}
EOF

if [[ "${PLAYWRIGHT_MCP_ENABLE}" == "true" ]]; then
  cat >> "${CODEX_DIR}/config.toml" <<EOF

[mcp_servers.playwright]
url = "${PLAYWRIGHT_MCP_URL}"
EOF
fi

if [[ -n "${CODEX_AUTH_JSON:-}" ]]; then
  printf '%s\n' "${CODEX_AUTH_JSON}" > "${CODEX_DIR}/auth.json"
elif [[ -n "${OPENAI_API_KEY:-}" ]]; then
  cat > "${CODEX_DIR}/auth.json" <<EOF
{
  "OPENAI_API_KEY": "${OPENAI_API_KEY}"
}
EOF
fi

chmod 600 "${CODEX_DIR}/config.toml" 2>/dev/null || true
chmod 600 "${CODEX_DIR}/auth.json" 2>/dev/null || true

if [[ "${CODEX_DIR}" != "${HOME}/.codex" ]]; then
  rm -rf "${HOME}/.codex"
  ln -s "${CODEX_DIR}" "${HOME}/.codex"
fi

# 默认中文界面
cat > "${USER_DATA_DIR}/User/locale.json" <<EOF
{
  "locale": "zh-cn"
}
EOF

# 首次启动安装扩展(幂等)
EXT_MARKER="${USER_DATA_DIR}/.extensions_installed"
if [[ ! -f "${EXT_MARKER}" ]]; then
  echo "[INFO] Installing extensions on first boot..."

  install_ext() {
    code-server --extensions-dir "${EXT_DIR}" --install-extension "$1" || true
  }

  # 你指定的 3 个(尽量装)
  install_ext ms-vscode.cpptools
  install_ext ms-vscode.cpptools-themes
  install_ext ms-vscode.cpp-devtools
  install_ext ms-vscode.cmake-tools
  install_ext danielpinto8zz6.c-cpp-compile-run
  install_ext golang.go
  install_ext rust-lang.rust-analyzer
  install_ext redhat.java
  install_ext vscjava.vscode-java-debug
  install_ext vscjava.vscode-java-test
  install_ext vscjava.vscode-maven
  install_ext vscjava.vscode-gradle
  install_ext vscjava.vscode-java-dependency
  install_ext ms-python.vscode-pylance
  install_ext ms-python.python
  install_ext ms-python.debugpy
  install_ext ms-python.vscode-python-envs
  install_ext ms-playwright.playwright

  # Codex
  install_ext openai.chatgpt

  # 若微软扩展不可用,装稳定替代
  install_ext MS-CEINTL.vscode-language-pack-zh-hans
  install_ext llvm-vs-code-extensions.vscode-clangd
  install_ext ms-vscode.makefile-tools
  install_ext vadimcn.vscode-lldb

  touch "${EXT_MARKER}"
fi

if [[ "${PLAYWRIGHT_MCP_ENABLE}" == "true" ]]; then
  if command -v playwright-mcp >/dev/null 2>&1; then
    echo "[INFO] Starting Playwright MCP server at ${PLAYWRIGHT_MCP_URL}"
    nohup playwright-mcp --headless --browser chromium --no-sandbox --port "${PLAYWRIGHT_MCP_PORT}" --host "${PLAYWRIGHT_MCP_HOST}" >/tmp/playwright-mcp.log 2>&1 &
  else
    echo "[WARN] Playwright MCP not installed; skipping server start."
  fi
fi

echo "[INFO] Java:   $(java -version 2>&1 | head -n1 || true)"
echo "[INFO] Python: $(python --version || true)"
echo "[INFO] Pip:    $(pip --version || true)"
echo "[INFO] Node:   $(node --version || true)"
echo "[INFO] npm:    $(npm --version || true)"
echo "[INFO] Docker: $(docker --version || true)"
echo "[INFO] Buildx: $(docker buildx version 2>/dev/null || true)"
echo "[INFO] Compose: $(docker compose version 2>/dev/null || true)"
echo "[INFO] g++:    $(g++ --version | head -n1 || true)"
echo "[INFO] Rust:   $(rustc --version || true)"
echo "[INFO] Cargo:  $(cargo --version || true)"
echo "[INFO] Go:     $(go version || true)"
echo "[INFO] Playwright: $(playwright --version 2>/dev/null || true)"

exec code-server "$WORKDIR" \
  --extensions-dir "$EXT_DIR" \
  --user-data-dir "$USER_DATA_DIR" \
  --disable-telemetry \
  --disable-update-check \
  --log warn