huanbao commited on
Commit
8db91f8
·
verified ·
1 Parent(s): 27f1af2

Update entrypoint.sh

Browse files
Files changed (1) hide show
  1. entrypoint.sh +239 -81
entrypoint.sh CHANGED
@@ -1,24 +1,10 @@
1
  #!/bin/bash
2
  set -e
3
 
4
- # 导出环境变量供子进程使用
5
- export CURSOR_API_KEY="${CURSOR_API_KEY:-}"
6
-
7
- # 检查并包装 claude 二进制,让其每次执行都强制携带跳过权限参数
8
- CLAUDE_BIN=$(which claude 2>/dev/null || echo "/usr/local/bin/claude")
9
- if [ -f "$CLAUDE_BIN" ] && [ ! -f "${CLAUDE_BIN}.orig" ]; then
10
- mv "$CLAUDE_BIN" "${CLAUDE_BIN}.orig"
11
- cat << 'EOF' > "$CLAUDE_BIN"
12
- #!/bin/sh
13
- exec "$0.orig" --dangerously-skip-permissions "$@"
14
- EOF
15
- chmod +x "$CLAUDE_BIN"
16
- fi
17
-
18
  # 1. 创建持久化挂载目录
19
- mkdir -p /data/.claude /data/.codex /data/.cloudcli /data/app /data/.taskmaster /data/.cursor /data/.config/cursor
20
 
21
- # 2. 软链接映射到持久化盘
22
  if [ ! -L "$HOME/.claude" ]; then
23
  rm -rf "$HOME/.claude"
24
  ln -s /data/.claude "$HOME/.claude"
@@ -34,23 +20,23 @@ if [ ! -L "$HOME/.taskmaster" ]; then
34
  ln -s /data/.taskmaster "$HOME/.taskmaster"
35
  fi
36
 
37
- if [ ! -L "$HOME/.codex" ]; then
38
- rm -rf "$HOME/.codex"
39
- ln -s /data/.codex "$HOME/.codex"
40
- fi
41
-
42
- if [ ! -L "$HOME/.cursor" ]; then
43
- rm -rf "$HOME/.cursor"
44
- ln -s /data/.cursor "$HOME/.cursor"
45
  fi
 
 
 
46
 
47
- mkdir -p "$HOME/.config"
48
- if [ ! -L "$HOME/.config/cursor" ]; then
49
- rm -rf "$HOME/.config/cursor"
50
- ln -s /data/.config/cursor "$HOME/.config/cursor"
 
51
  fi
 
52
 
53
- # 3. 自动生成 Claude 配置
54
  mkdir -p "$HOME/.claude"
55
  cat <<EOF > "$HOME/.claude/settings.json"
56
  {
@@ -63,79 +49,251 @@ cat <<EOF > "$HOME/.claude/settings.json"
63
  "DISABLE_INSTALLATION_CHECKS": "1",
64
  "CLAUDE_CODE_PROXY_RESOLVES_HOSTS": "1",
65
  "CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS": "1",
66
- "ENABLE_TOOL_SEARCH": "0",
67
  "DISABLE_AUTOUPDATER": "1",
68
- "API_TIMEOUT_MS": "1200000",
69
- "CLAUDE_STREAM_IDLE_TIMEOUT_MS": "1200000",
70
- "CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS": "1200000",
71
- "CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS": "1200000",
72
- "BASH_DEFAULT_TIMEOUT_MS": "1800000",
73
- "IS_SANDBOX": "1",
74
- "ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-sonnet-d",
75
- "ANTHROPIC_DEFAULT_OPUS_MODEL": "claude-sonnet-d",
76
- "ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-d",
77
- "ANTHROPIC_MODEL": "claude-sonnet-d",
78
- "ANTHROPIC_REASONING_MODEL": "claude-sonnet-d"
79
  },
80
  "permissions": {
81
- "defaultMode": "bypassPermissions",
82
- "additionalDirectories": [
83
- "/home/node",
84
- "/data",
85
- "/data/app",
86
- "/home/node/app"
87
- ],
88
  "allow": [
 
 
 
89
  "Bash(*)",
90
- "Read(*)",
91
- "Write(*)",
92
- "Edit(*)",
93
- "MultiEdit(*)",
94
- "Glob(*)",
95
- "Grep(*)",
96
- "LS(*)",
97
- "*"
98
  ]
99
  },
100
- "hasCompletedOnboarding":true,
101
- "dangerouslySkipPermissions": true,
102
- "skipDangerousModePermissionPrompt": true,
103
- "skipWebFetchPreflight": true
104
  }
105
  EOF
106
 
107
- # 4. 自动生成 Codex 配置
108
- mkdir -p "$HOME/.codex"
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  cat <<EOF > "$HOME/.codex/config.toml"
110
  cli_auth_credentials_store = "file"
111
  model_provider = "${CODEX_PROVIDER:-custom}"
112
- model = "${CODEX_MODEL:-gpt-5.6-sol}"
 
 
 
113
  [model_providers.custom]
114
  name = "Custom"
115
- base_url = "${CODEX_BASE_URL:-https://api.openai.com/v1}"
116
- wire_api = "responses"
117
- requires_openai_auth = true
118
  EOF
119
 
120
  cat <<EOF > "$HOME/.codex/auth.json"
121
  {
122
- "OPENAI_API_KEY": "${CODEX_API_KEY:-sk-dummy-key}"
123
  }
124
  EOF
125
 
126
- # 5. 生成 Cursor 全路径凭证 (核心修复点)
127
- # 基础目录创建
128
- mkdir -p "$HOME/.cursor"
129
- cat <<EOF > "$HOME/.cursor/cli-config.json"
130
- {
131
- "permissions": {
132
- "allow": ["Shell(*)", "Read", "Write"],
133
- "deny": []
134
- },
135
- "version": 1
136
- }
137
- EOF
 
 
 
 
 
138
 
139
- # 6. 切换工作目录并启动
140
  cd /data/app
141
- exec "$@"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  #!/bin/bash
2
  set -e
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  # 1. 创建持久化挂载目录
5
+ mkdir -p /data/.claude /data/.cloudcli /data/app /data/.taskmaster /data/.codex_data/sessions
6
 
7
+ # 2. 软链接映射(常规目录)
8
  if [ ! -L "$HOME/.claude" ]; then
9
  rm -rf "$HOME/.claude"
10
  ln -s /data/.claude "$HOME/.claude"
 
20
  ln -s /data/.taskmaster "$HOME/.taskmaster"
21
  fi
22
 
23
+ # ==================== 针对 .codex 的 SQLite 隔离 ====================
24
+ if [ -L "$HOME/.codex" ]; then
25
+ rm -f "$HOME/.codex"
 
 
 
 
 
26
  fi
27
+ mkdir -p "$HOME/.codex"
28
+ # 清理持久盘上可能残留的历史损坏 SQLite
29
+ rm -f /data/.codex/*.sqlite* 2>/dev/null || true
30
 
31
+ # 只持久化会话日志文本
32
+ mkdir -p "$HOME/.codex/sessions"
33
+ if [ ! -L "$HOME/.codex/sessions" ]; then
34
+ rm -rf "$HOME/.codex/sessions"
35
+ ln -s /data/.codex_data/sessions "$HOME/.codex/sessions"
36
  fi
37
+ # ===================================================================
38
 
39
+ # 3. 自动生成 Claude Code 配置
40
  mkdir -p "$HOME/.claude"
41
  cat <<EOF > "$HOME/.claude/settings.json"
42
  {
 
49
  "DISABLE_INSTALLATION_CHECKS": "1",
50
  "CLAUDE_CODE_PROXY_RESOLVES_HOSTS": "1",
51
  "CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS": "1",
52
+ "ENABLE_TOOL_SEARCH": "true",
53
  "DISABLE_AUTOUPDATER": "1",
54
+ "ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-sonnet-x[1m]",
55
+ "ANTHROPIC_DEFAULT_OPUS_MODEL": "claude-sonnet-x[1m]",
56
+ "ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-x[1m]",
57
+ "ANTHROPIC_MODEL": "claude-sonnet-x[1m]",
58
+ "ANTHROPIC_REASONING_MODEL": "claude-sonnet-x[1m]"
 
 
 
 
 
 
59
  },
60
  "permissions": {
 
 
 
 
 
 
 
61
  "allow": [
62
+ "Read",
63
+ "Write",
64
+ "Edit",
65
  "Bash(*)",
66
+ "Glob",
67
+ "Grep",
68
+ "Agent",
69
+ "WebFetch",
70
+ "WebSearch",
71
+ "NotebookEdit"
 
 
72
  ]
73
  },
74
+ "model": "sonnet[1m]",
75
+ "skipWebFetchPreflight": true,
76
+ "effortLevel": "high",
77
+ "autoUpdatesChannel": "latest"
78
  }
79
  EOF
80
 
81
+ # 4. 自动生成 Codex 配置(依据 readme.md 实测结论修复 bwrap 命名空间报错)
82
+ # 修复要点:
83
+ # a. 顶层键必须位于任何 [table] 段之前,否则键被归入 table 导致配置失效(实测注意点);
84
+ # b. hfspace 容器 seccomp 拦截 CLONE_NEWUSER 且无 bwrap,沙箱双路径全阻断,
85
+ # 必须 sandbox_mode="danger-full-access" + approval_policy="never" 让 Codex 完全跳过沙箱;
86
+ # c. 通道用实测可用的中转网关:wire_api="chat"、env_key="OPENAI_API_KEY"(移除 requires_openai_auth);
87
+ # d. 凭证解析:优先 CODEX_API_KEY 环境变量,其次 /data/.codex/gw_token(持久盘凭证文件)。
88
+ CODEX_KEY_RESOLVED="${CODEX_API_KEY:-}"
89
+ if [ -z "$CODEX_KEY_RESOLVED" ] && [ -f /data/.codex/gw_token ]; then
90
+ CODEX_KEY_RESOLVED="$(head -n 1 /data/.codex/gw_token | tr -d '[:space:]')"
91
+ fi
92
+ if [ -n "$CODEX_KEY_RESOLVED" ]; then
93
+ export OPENAI_API_KEY="$CODEX_KEY_RESOLVED"
94
+ fi
95
+
96
  cat <<EOF > "$HOME/.codex/config.toml"
97
  cli_auth_credentials_store = "file"
98
  model_provider = "${CODEX_PROVIDER:-custom}"
99
+ model = "${CODEX_MODEL:-gpt-5.6-luna}"
100
+ sandbox_mode = "danger-full-access"
101
+ approval_policy = "never"
102
+
103
  [model_providers.custom]
104
  name = "Custom"
105
+ base_url = "${CODEX_BASE_URL:-https://cpa.freecode.eu.cc/v1}"
106
+ wire_api = "chat"
107
+ env_key = "OPENAI_API_KEY"
108
  EOF
109
 
110
  cat <<EOF > "$HOME/.codex/auth.json"
111
  {
112
+ "OPENAI_API_KEY": "${CODEX_KEY_RESOLVED:-sk-dummy-key}"
113
  }
114
  EOF
115
 
116
+ # 5. 创建 codex wrapper 兜底(task-master-ai 内置 codex 不在 PATH 中;
117
+ # 集成端无环境变量启动时,wrapper 自动从 gw_token 注入凭证)
118
+ if [ -w /usr/local/bin ] && [ ! -e /usr/local/bin/codex ] && [ -x /usr/local/lib/node_modules/task-master-ai/node_modules/.bin/codex ]; then
119
+ cat <<'WEOF' > /usr/local/bin/codex
120
+ #!/bin/bash
121
+ if [ -z "$OPENAI_API_KEY" ] && [ -f /data/.codex/gw_token ]; then
122
+ export OPENAI_API_KEY="$(head -n 1 /data/.codex/gw_token)"
123
+ fi
124
+ exec /usr/local/lib/node_modules/task-master-ai/node_modules/.bin/codex "$@"
125
+ WEOF
126
+ chmod +x /usr/local/bin/codex 2>/dev/null || true
127
+ fi
128
+
129
+ # 6. 全局读写赋权(随后收紧 gw_token 权限,维持 600 保密要求)
130
+ chown -R 1000:1000 /data "$HOME" 2>/dev/null || true
131
+ chmod -R 777 /data "$HOME" 2>/dev/null || true
132
+ chmod 600 /data/.codex/gw_token 2>/dev/null || true
133
 
134
+ # 7. 切换并启动
135
  cd /data/app
136
+ exec "$@"
137
+
138
+
139
+
140
+
141
+
142
+
143
+
144
+
145
+
146
+
147
+
148
+
149
+
150
+
151
+
152
+
153
+
154
+
155
+
156
+
157
+
158
+ # cc、cursor可用版本
159
+ # #!/bin/bash
160
+ # set -e
161
+
162
+ # # 导出环境变量供子进程使用
163
+ # export CURSOR_API_KEY="${CURSOR_API_KEY:-}"
164
+
165
+ # # 检查并包装 claude 二进制,让其每次执行都强制携带跳过权限参数
166
+ # CLAUDE_BIN=$(which claude 2>/dev/null || echo "/usr/local/bin/claude")
167
+ # if [ -f "$CLAUDE_BIN" ] && [ ! -f "${CLAUDE_BIN}.orig" ]; then
168
+ # mv "$CLAUDE_BIN" "${CLAUDE_BIN}.orig"
169
+ # cat << 'EOF' > "$CLAUDE_BIN"
170
+ # #!/bin/sh
171
+ # exec "$0.orig" --dangerously-skip-permissions "$@"
172
+ # EOF
173
+ # chmod +x "$CLAUDE_BIN"
174
+ # fi
175
+
176
+ # # 1. 创建持久化挂载目录
177
+ # mkdir -p /data/.claude /data/.codex /data/.cloudcli /data/app /data/.taskmaster /data/.cursor /data/.config/cursor
178
+
179
+ # # 2. 软链接映射到持久化盘
180
+ # if [ ! -L "$HOME/.claude" ]; then
181
+ # rm -rf "$HOME/.claude"
182
+ # ln -s /data/.claude "$HOME/.claude"
183
+ # fi
184
+
185
+ # if [ ! -L "$HOME/.cloudcli" ]; then
186
+ # rm -rf "$HOME/.cloudcli"
187
+ # ln -s /data/.cloudcli "$HOME/.cloudcli"
188
+ # fi
189
+
190
+ # if [ ! -L "$HOME/.taskmaster" ]; then
191
+ # rm -rf "$HOME/.taskmaster"
192
+ # ln -s /data/.taskmaster "$HOME/.taskmaster"
193
+ # fi
194
+
195
+ # if [ ! -L "$HOME/.codex" ]; then
196
+ # rm -rf "$HOME/.codex"
197
+ # ln -s /data/.codex "$HOME/.codex"
198
+ # fi
199
+
200
+ # if [ ! -L "$HOME/.cursor" ]; then
201
+ # rm -rf "$HOME/.cursor"
202
+ # ln -s /data/.cursor "$HOME/.cursor"
203
+ # fi
204
+
205
+ # mkdir -p "$HOME/.config"
206
+ # if [ ! -L "$HOME/.config/cursor" ]; then
207
+ # rm -rf "$HOME/.config/cursor"
208
+ # ln -s /data/.config/cursor "$HOME/.config/cursor"
209
+ # fi
210
+
211
+ # # 3. 自动生成 Claude 配置
212
+ # mkdir -p "$HOME/.claude"
213
+ # cat <<EOF > "$HOME/.claude/settings.json"
214
+ # {
215
+ # "cleanupPeriodDays": 720,
216
+ # "env": {
217
+ # "ANTHROPIC_BASE_URL": "${ANTHROPIC_BASE_URL:-}",
218
+ # "ANTHROPIC_AUTH_TOKEN": "${ANTHROPIC_AUTH_TOKEN:-}",
219
+ # "CLAUDE_CODE_ATTRIBUTION_HEADER": "0",
220
+ # "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
221
+ # "DISABLE_INSTALLATION_CHECKS": "1",
222
+ # "CLAUDE_CODE_PROXY_RESOLVES_HOSTS": "1",
223
+ # "CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS": "1",
224
+ # "ENABLE_TOOL_SEARCH": "0",
225
+ # "DISABLE_AUTOUPDATER": "1",
226
+ # "API_TIMEOUT_MS": "1200000",
227
+ # "CLAUDE_STREAM_IDLE_TIMEOUT_MS": "1200000",
228
+ # "CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS": "1200000",
229
+ # "CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS": "1200000",
230
+ # "BASH_DEFAULT_TIMEOUT_MS": "1800000",
231
+ # "IS_SANDBOX": "1",
232
+ # "ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-sonnet-d",
233
+ # "ANTHROPIC_DEFAULT_OPUS_MODEL": "claude-sonnet-d",
234
+ # "ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-d",
235
+ # "ANTHROPIC_MODEL": "claude-sonnet-d",
236
+ # "ANTHROPIC_REASONING_MODEL": "claude-sonnet-d"
237
+ # },
238
+ # "permissions": {
239
+ # "defaultMode": "bypassPermissions",
240
+ # "additionalDirectories": [
241
+ # "/home/node",
242
+ # "/data",
243
+ # "/data/app",
244
+ # "/home/node/app"
245
+ # ],
246
+ # "allow": [
247
+ # "Bash(*)",
248
+ # "Read(*)",
249
+ # "Write(*)",
250
+ # "Edit(*)",
251
+ # "MultiEdit(*)",
252
+ # "Glob(*)",
253
+ # "Grep(*)",
254
+ # "LS(*)",
255
+ # "*"
256
+ # ]
257
+ # },
258
+ # "hasCompletedOnboarding":true,
259
+ # "dangerouslySkipPermissions": true,
260
+ # "skipDangerousModePermissionPrompt": true,
261
+ # "skipWebFetchPreflight": true
262
+ # }
263
+ # EOF
264
+
265
+ # # 4. 自动生成 Codex 配置
266
+ # mkdir -p "$HOME/.codex"
267
+ # cat <<EOF > "$HOME/.codex/config.toml"
268
+ # cli_auth_credentials_store = "file"
269
+ # model_provider = "${CODEX_PROVIDER:-custom}"
270
+ # model = "${CODEX_MODEL:-gpt-5.6-sol}"
271
+ # [model_providers.custom]
272
+ # name = "Custom"
273
+ # base_url = "${CODEX_BASE_URL:-https://api.openai.com/v1}"
274
+ # wire_api = "responses"
275
+ # requires_openai_auth = true
276
+ # EOF
277
+
278
+ # cat <<EOF > "$HOME/.codex/auth.json"
279
+ # {
280
+ # "OPENAI_API_KEY": "${CODEX_API_KEY:-sk-dummy-key}"
281
+ # }
282
+ # EOF
283
+
284
+ # # 5. 生成 Cursor 全路径凭证 (核心修复点)
285
+ # # 基础目录创建
286
+ # mkdir -p "$HOME/.cursor"
287
+ # cat <<EOF > "$HOME/.cursor/cli-config.json"
288
+ # {
289
+ # "permissions": {
290
+ # "allow": ["Shell(*)", "Read", "Write"],
291
+ # "deny": []
292
+ # },
293
+ # "version": 1
294
+ # }
295
+ # EOF
296
+
297
+ # # 6. 切换工作目录并启动
298
+ # cd /data/app
299
+ # exec "$@"