@ckcloudai.com/clawrouter 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,382 @@
1
+ #!/bin/bash
2
+
3
+ echo "🦞 ckcloud\n"
4
+
5
+ set -e
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+
9
+
10
+ echo "🦞 ckcloud plugin reinstall"
11
+ echo ""
12
+
13
+ if ! command -v jq >/dev/null 2>&1; then
14
+ echo "jq is required"
15
+ exit 1
16
+ fi
17
+
18
+ ############### 0. Back up wallet key BEFORE removing anything ###############
19
+ WALLET_FILE="$HOME/.openclaw/ckcloud/wallet.key"
20
+ WALLET_BACKUP=""
21
+
22
+ if [ -f "$WALLET_FILE" ]; then
23
+ echo "→ Backing up wallet..."
24
+ WALLET_KEY=$(cat "$WALLET_FILE" | tr -d '[:space:]')
25
+ KEY_LEN=${#WALLET_KEY}
26
+ if [[ "$WALLET_KEY" == 0x* ]] && [ "$KEY_LEN" -eq 66 ]; then
27
+ WALLET_BACKUP="$HOME/.openclaw/ckcloud/wallet.key.bak.$(date +%s)"
28
+ cp "$WALLET_FILE" "$WALLET_BACKUP"
29
+ chmod 600 "$WALLET_BACKUP"
30
+ echo " ✓ Wallet backed up to: $WALLET_BACKUP"
31
+ else
32
+ echo " ⚠ Wallet file exists but has invalid format — skipping backup"
33
+ fi
34
+ else
35
+ if [ -f "$HOME/.openclaw/ckcloud/mnemonic" ]; then
36
+ echo " ⚠ wallet.key missing but mnemonic exists — refusing to overwrite funds"
37
+ echo " Run: npx @ckcloudai.com/clawrouter wallet recover"
38
+ exit 1
39
+ fi
40
+ echo "→ No wallet found — generating a new wallet (fresh install)"
41
+ fi
42
+ echo ""
43
+
44
+ ############### 1. Remove plugin files ###############
45
+ echo "→ Removing plugin files..."
46
+ rm -rf ~/.openclaw/extensions/ckcloud
47
+
48
+ ############### 2. clean config ###############
49
+ CONFIG="$HOME/.openclaw/openclaw.json"
50
+
51
+ ## check file exist
52
+ if [ ! -f "$CONFIG" ]; then
53
+ echo " No openclaw.json found, skipping"
54
+ exit 0
55
+ fi
56
+
57
+ ## check json
58
+ if ! jq empty "$CONFIG" >/dev/null 2>&1; then
59
+ backup="$CONFIG.corrupt.$(date +%s)"
60
+ echo " ERROR: Invalid JSON in openclaw.json"
61
+ cp "$CONFIG" "$backup" || true
62
+ echo " Backed up to: $backup"
63
+ echo " Skipping config cleanup..."
64
+ exit 0
65
+ fi
66
+
67
+ tmp=$(mktemp)
68
+
69
+ ## clean config
70
+ jq '
71
+ if .plugins.entries.ckcloud then
72
+ del(.plugins.entries.ckcloud)
73
+ else . end |
74
+
75
+ if .plugins.installs.ckcloud then
76
+ del(.plugins.installs.ckcloud)
77
+ else . end |
78
+
79
+ if .plugins.allow then
80
+ .plugins.allow |= map(select(. != "ckcloud" and . != "@ckcloudai.com/clawrouter"))
81
+ else . end
82
+
83
+ ' "$CONFIG" > "$tmp"
84
+
85
+ mv "$tmp" "$CONFIG"
86
+
87
+ echo " Config cleaned"
88
+
89
+ ############### 3. stop old plugin proxy ###############
90
+ PORT_TO_KILL=8402
91
+
92
+ stop_proxy() {
93
+ local port="$1"
94
+ local os_name pids=
95
+ os_name=$(uname -s 2>/dev/null || echo "")
96
+
97
+ if command -v lsof >/dev/null 2>&1; then
98
+ pids=$(lsof -ti tcp:"$port" 2>/dev/null | tr '\n' ' ')
99
+ fi
100
+
101
+ if [ -z "$pids" ] && [[ "$os_name" == Linux* ]] && command -v fuser >/dev/null 2>&1; then
102
+ pids=$(fuser -n tcp "$port" 2>/dev/null | tr '\n' ' ')
103
+ fi
104
+
105
+ if [ -z "$pids" ]; then
106
+ echo "→ No proxy process detected on port $port"
107
+ return
108
+ fi
109
+
110
+ for pid in $pids; do
111
+ if [ -z "$pid" ]; then
112
+ continue
113
+ fi
114
+
115
+ if kill "$pid" >/dev/null 2>&1; then
116
+ echo "→ Stopped process $pid"
117
+ else
118
+ echo "→ Failed to stop process $pid"
119
+ fi
120
+ done
121
+ }
122
+
123
+ case "$(uname -s 2>/dev/null || echo "")" in
124
+ Darwin*|Linux*)
125
+ echo "→ Stopping proxy on port $PORT_TO_KILL..."
126
+ stop_proxy "$PORT_TO_KILL"
127
+ ;;
128
+ *)
129
+ echo "→ Unsupported platform, skipping proxy stop"
130
+ ;;
131
+ esac
132
+
133
+ ############### 4. Remove stale models.json so it gets regenerated with apiKey ###############
134
+ echo "→ Cleaning models cache..."
135
+ rm -f ~/.openclaw/agents/main/agent/models.json 2>/dev/null || true
136
+
137
+ ############### 5. Inject auth profile ###############
138
+ echo "→ Injecting auth profile..."
139
+
140
+ AUTH_DIR="$HOME/.openclaw/agents/main/agent"
141
+ AUTH_PATH="$AUTH_DIR/auth-profiles.json"
142
+ PROFILE_KEY="ckcloud:default"
143
+
144
+ mkdir -p "$AUTH_DIR"
145
+
146
+ reset_auth_store() {
147
+ cat <<'EOF' > "$AUTH_PATH"
148
+ {
149
+ "version": 1,
150
+ "profiles": {}
151
+ }
152
+ EOF
153
+ }
154
+
155
+ if [ -f "$AUTH_PATH" ]; then
156
+ if jq empty "$AUTH_PATH" >/dev/null 2>&1; then
157
+ if ! jq -e '.version and .profiles' "$AUTH_PATH" >/dev/null 2>&1; then
158
+ echo " Warning: auth-profiles.json missing version/profiles, recreating"
159
+ reset_auth_store
160
+ fi
161
+ else
162
+ echo " Warning: Could not parse auth-profiles.json, creating fresh"
163
+ reset_auth_store
164
+ fi
165
+ else
166
+ reset_auth_store
167
+ fi
168
+
169
+ tmp_auth=$(mktemp)
170
+ if jq --arg key "$PROFILE_KEY" \
171
+ --arg type "api_key" \
172
+ --arg provider "ckcloud" \
173
+ --arg api_key "x402-proxy-handles-auth" \
174
+ 'if .profiles[$key] then . else .profiles[$key] = {type: $type, provider: $provider, key: $api_key} end' \
175
+ "$AUTH_PATH" > "$tmp_auth"; then
176
+ if cmp -s "$AUTH_PATH" "$tmp_auth"; then
177
+ echo " Auth profile already exists"
178
+ rm -f "$tmp_auth"
179
+ else
180
+ mv "$tmp_auth" "$AUTH_PATH"
181
+ echo " Auth profile created"
182
+ fi
183
+ else
184
+ echo " ERROR: Failed to update auth profile"
185
+ rm -f "$tmp_auth"
186
+ fi
187
+
188
+ ############### 6. Ensure apiKey is present for /model picker (but DON'T override default model) ###############
189
+ #!/usr/bin/env bash
190
+ if [ ! -f "$CONFIG" ]; then
191
+ echo " No openclaw.json found, skipping"
192
+ exit 0
193
+ fi
194
+
195
+ APIKEY=$(jq -r '.models.providers.ckcloud.apiKey // empty' "$CONFIG")
196
+
197
+ if [ -z "$APIKEY" ]; then
198
+ echo " Added apiKey to ckcloud provider config"
199
+
200
+ tmp=$(mktemp)
201
+
202
+ jq '.models.providers.ckcloud.apiKey = "x402-proxy-handles-auth"' \
203
+ "$CONFIG" > "$tmp" && mv "$tmp" "$CONFIG"
204
+ fi
205
+
206
+
207
+ ############### 7. Populate model allowlist so top ckcloud models appear in /model picker ###############
208
+ TMP=$(mktemp)
209
+
210
+ TOP_MODELS=(
211
+ auto free eco premium
212
+ anthropic/claude-sonnet-4.6
213
+ )
214
+ TOP_JSON=$(printf '"ckcloud/%s",' "${TOP_MODELS[@]}")
215
+ TOP_JSON="[${TOP_JSON%,}]"
216
+
217
+ # 确保 provider + apiKey
218
+ jq '
219
+ .models |= (. // {}) |
220
+ .models.providers |= (. // {}) |
221
+ .models.providers.ckcloud |= (. // {api:"openai-completions",models:[],baseUrl:"http://127.0.0.1:8402/v1"}) |
222
+ .models.providers.ckcloud.baseUrl |= (. // "http://127.0.0.1:8402/v1") |
223
+ .models.providers.ckcloud.apiKey |= (. // "x402-proxy-handles-auth") |
224
+ .models.providers.ckcloud.models |= (. // [])
225
+ ' "$CONFIG" > "$TMP"
226
+
227
+ mv "$TMP" "$CONFIG"
228
+
229
+ # 清理旧 ckcloud/*
230
+ TMP=$(mktemp)
231
+
232
+ jq --argjson top "$TOP_JSON" '
233
+ .agents |= (. // {}) |
234
+ .agents.defaults |= (. // {}) |
235
+ .agents.defaults.models |= (. // {}) |
236
+ .agents.defaults.models |= with_entries(
237
+ if (.key | startswith("ckcloud/")) and
238
+ (.key as $k | ($top | index($k)) | not)
239
+ then empty
240
+ else .
241
+ end
242
+ )
243
+ ' "$CONFIG" > "$TMP"
244
+
245
+ mv "$TMP" "$CONFIG"
246
+
247
+ # 添加 TOP_MODELS
248
+ added=0
249
+
250
+ for id in "${TOP_MODELS[@]}"; do
251
+ key="ckcloud/$id"
252
+
253
+ if ! jq -e --arg k "$key" '.agents.defaults.models[$k]' "$CONFIG" >/dev/null; then
254
+ TMP=$(mktemp)
255
+
256
+ jq --arg k "$key" '
257
+ .agents.defaults.models[$k] = {}
258
+ ' "$CONFIG" > "$TMP"
259
+
260
+ mv "$TMP" "$CONFIG"
261
+ added=$((added+1))
262
+ fi
263
+ done
264
+
265
+ if [ "$added" -gt 0 ]; then
266
+ echo " Added $added models to allowlist (${#TOP_MODELS[@]} total)"
267
+ else
268
+ echo " Allowlist already up to date"
269
+ fi
270
+
271
+ ############### 8. Ensure default primary model uses ckcloud/auto ###############
272
+ echo "→ Ensuring default primary model..."
273
+
274
+ current_model=$(jq -r '.agents.defaults.model.primary // empty' "$CONFIG")
275
+
276
+ if [ "$current_model" = "ckcloud/auto" ]; then
277
+ echo " Default primary already ckcloud/auto"
278
+ else
279
+ TMP=$(mktemp)
280
+
281
+ if jq '
282
+ .agents |= (. // {}) |
283
+ .agents.defaults |= (. // {}) |
284
+ .agents.defaults.model |= (. // {}) |
285
+ .agents.defaults.model.primary = "ckcloud/auto"
286
+ ' "$CONFIG" > "$TMP"; then
287
+ mv "$TMP" "$CONFIG"
288
+ if [ -z "$current_model" ]; then
289
+ echo " Set primary to ckcloud/auto"
290
+ else
291
+ echo " Replaced primary ($current_model) → ckcloud/auto"
292
+ fi
293
+ else
294
+ echo " Failed to update default model"
295
+ rm -f "$TMP"
296
+ fi
297
+ fi
298
+
299
+ ############### 9. Install plugin (config is ready, but no allow list yet to avoid validation error) ###############
300
+ echo "→ Installing ckcloud plugin..."
301
+
302
+ openclaw plugins install @ckcloudai.com/clawrouter
303
+
304
+ echo "→ Verifying installation..."
305
+ DIST_PATH="$HOME/.openclaw/extensions/ckcloud/dist/index.js"
306
+ if [ ! -f "$DIST_PATH" ]; then
307
+ echo " ⚠️ dist/ files missing, clearing npm cache and retrying..."
308
+ npm cache clean --force 2>/dev/null || true
309
+ rm -rf ~/.openclaw/extensions/ckcloud
310
+
311
+ openclaw plugins install @ckcloudai.com/clawrouter
312
+
313
+ if [ ! -f "$DIST_PATH" ]; then
314
+ echo " ❌ Installation failed - dist/index.js still missing"
315
+ echo " Please report this issue"
316
+ exit 1
317
+ fi
318
+ fi
319
+ echo " ✓ dist/index.js verified"
320
+
321
+ ############### 10. Add plugin to allow list (done AFTER install so plugin files exist for validation) ###############
322
+ TMP_FILE=$(mktemp)
323
+
324
+ if jq '
325
+ .plugins = (.plugins // {}) |
326
+ .plugins.allow = (.plugins.allow // []) |
327
+ if (.plugins.allow | index("ckcloud")) or (.plugins.allow | index("@ckcloudai.com/clawrouter")) then
328
+ .
329
+ else
330
+ .plugins.allow += ["ckcloud"]
331
+ end
332
+ ' "$CONFIG" > "$TMP_FILE"; then
333
+
334
+ if jq -e '.plugins.allow | index("ckcloud")' "$CONFIG" >/dev/null 2>&1 || \
335
+ jq -e '.plugins.allow | index("@ckcloudai.com/clawrouter")' "$CONFIG" >/dev/null 2>&1; then
336
+ echo " Plugin already in allow list"
337
+ else
338
+ echo " Added ckcloud to plugins.allow"
339
+ fi
340
+
341
+ mv "$TMP_FILE" "$CONFIG"
342
+ else
343
+ echo " Could not update config"
344
+ rm -f "$TMP_FILE"
345
+ fi
346
+
347
+
348
+ ############### Final: verify wallet survived reinstall ###############
349
+ echo "→ Verifying wallet integrity..."
350
+ if [ -f "$WALLET_FILE" ]; then
351
+ CURRENT_KEY=$(cat "$WALLET_FILE" | tr -d '[:space:]')
352
+ CURRENT_LEN=${#CURRENT_KEY}
353
+ if [[ "$CURRENT_KEY" == 0x* ]] && [ "$CURRENT_LEN" -eq 66 ]; then
354
+ echo " ✓ Wallet key intact"
355
+ else
356
+ if [ -n "$WALLET_BACKUP" ] && [ -f "$WALLET_BACKUP" ]; then
357
+ cp "$WALLET_BACKUP" "$WALLET_FILE"
358
+ chmod 600 "$WALLET_FILE"
359
+ echo " ✓ Wallet restored from backup"
360
+ else
361
+ echo " ⚠ wallet.key corrupted AND no backup available. Manual recovery required."
362
+ echo " Run: npx @ckcloudai.com/clawrouter wallet recover"
363
+ fi
364
+ fi
365
+ else
366
+ if [ -n "$WALLET_BACKUP" ] && [ -f "$WALLET_BACKUP" ]; then
367
+ mkdir -p "$(dirname "$WALLET_FILE")"
368
+ cp "$WALLET_BACKUP" "$WALLET_FILE"
369
+ chmod 600 "$WALLET_FILE"
370
+ echo " ✓ Wallet restored from backup: $WALLET_BACKUP"
371
+ else
372
+ echo " ⚠ wallet.key missing and no backup available. Manual recovery required."
373
+ echo " Run: npx @ckcloudai.com/clawrouter wallet recover"
374
+ fi
375
+ fi
376
+
377
+ echo ""
378
+ echo "✓ Done! Smart routing enabled by default."
379
+ echo ""
380
+ echo "Run: openclaw gateway restart"
381
+
382
+ echo "To uninstall: bash ~/.openclaw/extensions/ckcloud/scripts/uninstall.sh"