@anh3d0nic/qwen-code-termux-ice 16.0.4 → 16.0.7

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.
Files changed (69) hide show
  1. package/bin/qwen-ice +25 -5
  2. package/package.json +6 -5
  3. package/scripts/build.js +88 -0
  4. package/scripts/build_package.js +37 -0
  5. package/scripts/build_sandbox.js +174 -0
  6. package/scripts/build_vscode_companion.js +30 -0
  7. package/scripts/check-build-status.js +148 -0
  8. package/scripts/check-i18n.ts +462 -0
  9. package/scripts/check-lockfile.js +74 -0
  10. package/scripts/clean.js +59 -0
  11. package/scripts/copy_bundle_assets.js +90 -0
  12. package/scripts/copy_files.js +86 -0
  13. package/scripts/create_alias.sh +39 -0
  14. package/scripts/dev.js +109 -0
  15. package/scripts/esbuild-shims.js +29 -0
  16. package/scripts/generate-git-commit-info.js +71 -0
  17. package/scripts/generate-settings-schema.ts +146 -0
  18. package/scripts/get-release-version.js +411 -0
  19. package/scripts/ice-mobile.js +5 -0
  20. package/scripts/ice-session.js +6 -0
  21. package/scripts/ice-skills.js +31 -0
  22. package/scripts/ice-teams.js +34 -0
  23. package/scripts/ice-v10.js +276 -0
  24. package/scripts/ice-v11.js +276 -0
  25. package/scripts/ice-v12.js +568 -0
  26. package/scripts/ice-v13.js +824 -0
  27. package/scripts/ice-v14.js +1059 -0
  28. package/scripts/ice-v15.js +1501 -0
  29. package/scripts/ice-v2.js +26 -0
  30. package/scripts/ice-v3-core.js +261 -0
  31. package/scripts/ice-v3.js +46 -0
  32. package/scripts/ice-v4.js +657 -0
  33. package/scripts/ice-v5.js +371 -0
  34. package/scripts/ice-v6.js +305 -0
  35. package/scripts/ice-v7.js +291 -0
  36. package/scripts/ice-v8.js +550 -0
  37. package/scripts/ice-v9.js +546 -0
  38. package/scripts/install-ice.sh +70 -0
  39. package/scripts/install.sh +136 -0
  40. package/scripts/installation/INSTALLATION_GUIDE.md +250 -0
  41. package/scripts/installation/install-qwen-with-source.bat +302 -0
  42. package/scripts/installation/install-qwen-with-source.sh +570 -0
  43. package/scripts/lint.js +205 -0
  44. package/scripts/local_telemetry.js +219 -0
  45. package/scripts/postinstall.cjs +235 -0
  46. package/scripts/pre-commit.js +22 -0
  47. package/scripts/prepare-package.js +186 -0
  48. package/scripts/prepare-termux.cjs +26 -0
  49. package/scripts/sandbox_command.js +128 -0
  50. package/scripts/start.js +86 -0
  51. package/scripts/telemetry.js +85 -0
  52. package/scripts/telemetry_gcp.js +188 -0
  53. package/scripts/telemetry_utils.js +450 -0
  54. package/scripts/test-v10.js +18 -0
  55. package/scripts/test-v11.js +18 -0
  56. package/scripts/test-v12.js +18 -0
  57. package/scripts/test-v13.js +18 -0
  58. package/scripts/test-v14.js +18 -0
  59. package/scripts/test-v3.js +47 -0
  60. package/scripts/test-v4.js +47 -0
  61. package/scripts/test-v6.js +59 -0
  62. package/scripts/test-v8.js +42 -0
  63. package/scripts/test-v9.js +18 -0
  64. package/scripts/test-windows-paths.js +51 -0
  65. package/scripts/tests/get-release-version.test.js +186 -0
  66. package/scripts/tests/test-setup.ts +12 -0
  67. package/scripts/tests/vitest.config.ts +26 -0
  68. package/scripts/unused-keys-only-in-locales.json +62 -0
  69. package/scripts/version.js +112 -0
@@ -0,0 +1,570 @@
1
+ #!/bin/bash
2
+
3
+ # Qwen Code Installation Script
4
+ # This script installs Node.js (via NVM) and Qwen Code CLI
5
+ # Supports Linux and macOS
6
+ #
7
+ # Usage: install-qwen-with-source.sh --source [github|npm|internal|local-build]
8
+ # install-qwen-with-source.sh -s [github|npm|internal|local-build]
9
+
10
+ # Re-execute with bash if running with sh or other shells
11
+ # This block must use POSIX-compliant syntax ([ not [[) since it runs before we know bash is available
12
+ if [ -z "${BASH_VERSION}" ] && [ -z "${__QWEN_INSTALL_REEXEC:-}" ]; then
13
+ # Check if we're in a git hook environment
14
+ case "${0}" in
15
+ *.git/hooks/*) export __QWEN_IN_GIT_HOOK=1 ;;
16
+ esac
17
+ if [ -n "${GIT_DIR:-}" ]; then
18
+ export __QWEN_IN_GIT_HOOK=1
19
+ fi
20
+
21
+ # Try to find bash
22
+ if command -v bash >/dev/null 2>&1; then
23
+ export __QWEN_INSTALL_REEXEC=1
24
+ # Re-exec with bash, preserving all arguments
25
+ exec bash -- "${0}" "$@"
26
+ else
27
+ echo "Error: This script requires bash. Please install bash first."
28
+ exit 1
29
+ fi
30
+ fi
31
+
32
+ # Enable strict mode (bash-specific options)
33
+ # pipefail requires bash 3+; check before setting
34
+ if [ -n "${BASH_VERSION:-}" ]; then
35
+ # shellcheck disable=SC3040
36
+ set -eo pipefail
37
+ else
38
+ set -e
39
+ fi
40
+
41
+ # ============================================
42
+ # Color definitions
43
+ # ============================================
44
+ RED='\033[0;31m'
45
+ GREEN='\033[0;32m'
46
+ YELLOW='\033[1;33m'
47
+ BLUE='\033[0;34m'
48
+ NC='\033[0m' # No Color
49
+
50
+ # ============================================
51
+ # Log functions
52
+ # ============================================
53
+ log_info() {
54
+ echo -e "${BLUE}ℹ️ $1${NC}"
55
+ }
56
+
57
+ log_success() {
58
+ echo -e "${GREEN}✅ $1${NC}"
59
+ }
60
+
61
+ log_warning() {
62
+ echo -e "${YELLOW}⚠️ $1${NC}"
63
+ }
64
+
65
+ log_error() {
66
+ echo -e "${RED}❌ $1${NC}"
67
+ }
68
+
69
+ # ============================================
70
+ # Utility functions
71
+ # ============================================
72
+ command_exists() {
73
+ command -v "$1" >/dev/null 2>&1
74
+ }
75
+
76
+ get_shell_profile() {
77
+ local current_shell
78
+ current_shell=$(basename "${SHELL}")
79
+ case "${current_shell}" in
80
+ bash)
81
+ echo "${HOME}/.bashrc"
82
+ ;;
83
+ zsh)
84
+ echo "${HOME}/.zshrc"
85
+ ;;
86
+ fish)
87
+ # Fish uses its own syntax; bash/zsh export statements are not compatible.
88
+ # Return empty string to signal callers to skip automatic profile writes.
89
+ echo ""
90
+ ;;
91
+ *)
92
+ echo "${HOME}/.profile"
93
+ ;;
94
+ esac
95
+ }
96
+
97
+ # ============================================
98
+ # Parse command line arguments
99
+ # ============================================
100
+ SOURCE="unknown"
101
+ while [[ $# -gt 0 ]]; do
102
+ case $1 in
103
+ -s|--source)
104
+ if [[ -z "$2" ]] || [[ "$2" == -* ]]; then
105
+ log_error "--source requires a value"
106
+ exit 1
107
+ fi
108
+ SOURCE="$2"
109
+ shift 2
110
+ ;;
111
+ -h|--help)
112
+ echo "Usage: $0 [OPTIONS]"
113
+ echo ""
114
+ echo "Options:"
115
+ echo " -s, --source SOURCE Specify the installation source (e.g., github, npm, internal)"
116
+ echo " -h, --help Show this help message"
117
+ echo ""
118
+ exit 0
119
+ ;;
120
+ *)
121
+ log_error "Unknown option: $1"
122
+ exit 1
123
+ ;;
124
+ esac
125
+ done
126
+
127
+ # ============================================
128
+ # Print header
129
+ # ============================================
130
+ echo "=========================================="
131
+ echo " Qwen Code Installation Script"
132
+ echo "=========================================="
133
+ echo ""
134
+ log_info "System: $(uname -s) $(uname -r)" || true
135
+ log_info "Shell: $(basename "${SHELL}")"
136
+ echo ""
137
+
138
+ # ============================================
139
+ # Ensure download tool is available
140
+ # ============================================
141
+ ensure_download_tool() {
142
+ if command_exists curl; then
143
+ DOWNLOAD_CMD="curl"
144
+ DOWNLOAD_ARGS="-fsSL"
145
+ return 0
146
+ fi
147
+
148
+ if command_exists wget; then
149
+ DOWNLOAD_CMD="wget"
150
+ DOWNLOAD_ARGS="-qO -"
151
+ return 0
152
+ fi
153
+
154
+ log_error "Neither curl nor wget found"
155
+ log_info "Please install curl or wget manually:"
156
+ echo " - macOS: brew install curl"
157
+ echo " - Ubuntu/Debian: sudo apt-get install curl"
158
+ echo " - CentOS/RHEL: sudo yum install curl"
159
+ exit 1
160
+ }
161
+
162
+ # ============================================
163
+ # Clean npm configuration conflicts
164
+ # ============================================
165
+ clean_npmrc_conflict() {
166
+ local npmrc="${HOME}/.npmrc"
167
+ if [[ -f "${npmrc}" ]]; then
168
+ # Only clean if conflicting entries actually exist
169
+ if grep -Eq '^(prefix|globalconfig) *= *' "${npmrc}" 2>/dev/null; then
170
+ log_info "Cleaning npmrc conflicts..."
171
+ # Backup original npmrc before modifying
172
+ cp -f "${npmrc}" "${npmrc}.bak"
173
+ log_info "Backed up original .npmrc to ${npmrc}.bak"
174
+ grep -Ev '^(prefix|globalconfig) *= *' "${npmrc}.bak" > "${npmrc}.tmp" || true
175
+ mv -f "${npmrc}.tmp" "${npmrc}" || true
176
+ log_success "Removed conflicting prefix/globalconfig entries from .npmrc"
177
+ fi
178
+ fi
179
+ }
180
+
181
+ # ============================================
182
+ # Install NVM
183
+ # ============================================
184
+ install_nvm() {
185
+ local NVM_DIR="${NVM_DIR:-${HOME}/.nvm}"
186
+ local NVM_VERSION="${NVM_VERSION:-v0.40.3}"
187
+
188
+ if [[ -s "${NVM_DIR}/nvm.sh" ]]; then
189
+ log_info "NVM is already installed at ${NVM_DIR}"
190
+ return 0
191
+ fi
192
+
193
+ log_info "Installing NVM ${NVM_VERSION}..."
194
+
195
+ # Download and install NVM from Aliyun OSS
196
+ # Use temporary file instead of pipe to avoid potential subshell issues
197
+ local NVM_INSTALL_TEMP
198
+ NVM_INSTALL_TEMP=$(mktemp)
199
+ if "${DOWNLOAD_CMD}" "${DOWNLOAD_ARGS}" "https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/installation/install_nvm.sh" > "${NVM_INSTALL_TEMP}"; then
200
+ # Run the script in current shell environment
201
+ # shellcheck source=/dev/null
202
+ . "${NVM_INSTALL_TEMP}"
203
+ rm -f "${NVM_INSTALL_TEMP}"
204
+ log_success "NVM installed successfully"
205
+ else
206
+ rm -f "${NVM_INSTALL_TEMP}"
207
+ log_error "Failed to install NVM"
208
+ log_info "Please install NVM manually: https://github.com/nvm-sh/nvm#install--update-script"
209
+ exit 1
210
+ fi
211
+
212
+ # Configure shell profile
213
+ local PROFILE_FILE
214
+ PROFILE_FILE=$(get_shell_profile)
215
+
216
+ # Fish shell returns empty string from get_shell_profile because export/source
217
+ # syntax is incompatible with fish. Skip automatic profile writes for fish users.
218
+ if [[ -z "${PROFILE_FILE}" ]]; then
219
+ log_warning "Fish shell detected: automatic shell profile configuration is not supported."
220
+ log_info "Please add NVM configuration manually. See: https://github.com/nvm-sh/nvm#fish"
221
+ # Check if profile file is writable
222
+ elif [[ -f "${PROFILE_FILE}" ]] && [[ ! -w "${PROFILE_FILE}" ]]; then
223
+ log_warning "Cannot write to ${PROFILE_FILE} (permission denied)"
224
+ log_info "Skipping shell profile configuration"
225
+ log_info "You may need to manually add NVM configuration to your shell profile"
226
+ elif ! grep -q 'NVM_DIR' "${PROFILE_FILE}" 2>/dev/null; then
227
+ # shellcheck disable=SC2016
228
+ # The following echo statements intentionally use single quotes to write literal strings
229
+ {
230
+ echo ""
231
+ echo "# NVM configuration (added by Qwen Code installer)"
232
+ echo "export NVM_DIR=\"\$HOME/.nvm\""
233
+ echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"'
234
+ echo '[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"'
235
+ } >> "${PROFILE_FILE}" 2>/dev/null || {
236
+ log_warning "Failed to write to ${PROFILE_FILE}"
237
+ log_info "Skipping shell profile configuration"
238
+ return 0
239
+ }
240
+ log_info "Added NVM config to ${PROFILE_FILE}"
241
+ fi
242
+
243
+ # Load NVM for current session
244
+ export NVM_DIR="${NVM_DIR}"
245
+ # shellcheck source=/dev/null
246
+ [[ -s "${NVM_DIR}/nvm.sh" ]] && \. "${NVM_DIR}/nvm.sh"
247
+
248
+ log_success "NVM configured successfully"
249
+ return 0
250
+ }
251
+
252
+ # ============================================
253
+ # Install Node.js via NVM
254
+ # ============================================
255
+ install_nodejs_with_nvm() {
256
+ local NODE_VERSION="${NODE_VERSION:-20}"
257
+ local NVM_DIR="${NVM_DIR:-${HOME}/.nvm}"
258
+
259
+ # Ensure NVM is loaded
260
+ export NVM_DIR="${NVM_DIR}"
261
+ # shellcheck source=/dev/null
262
+ [[ -s "${NVM_DIR}/nvm.sh" ]] && \. "${NVM_DIR}/nvm.sh"
263
+
264
+ if ! command_exists nvm; then
265
+ log_error "NVM not loaded properly"
266
+ return 1
267
+ fi
268
+
269
+ # Set Node.js mirror source for faster downloads in China
270
+ export NVM_NODEJS_ORG_MIRROR="https://npmmirror.com/mirrors/node"
271
+
272
+ # Install Node.js
273
+ log_info "Installing Node.js v${NODE_VERSION}..."
274
+ if nvm install "${NODE_VERSION}"; then
275
+ nvm alias default "${NODE_VERSION}" || true
276
+ nvm use default || true
277
+ log_success "Node.js v${NODE_VERSION} installed successfully"
278
+
279
+ # Verify installation
280
+ log_info "Node.js version: $(node -v)" || true
281
+ log_info "npm version: $(npm -v)" || true
282
+
283
+ return 0
284
+ else
285
+ log_error "Failed to install Node.js"
286
+ return 1
287
+ fi
288
+ }
289
+
290
+ # ============================================
291
+ # Check Node.js version
292
+ # ============================================
293
+ check_node_version() {
294
+ if ! command_exists node; then
295
+ return 1
296
+ fi
297
+
298
+ local current_version
299
+ current_version=$(node -v | sed 's/v//')
300
+ local major_version
301
+ major_version=$(echo "${current_version}" | cut -d. -f1 | sed 's/[^0-9]//g')
302
+
303
+ # Handle cases where major_version is empty or non-numeric
304
+ if [[ -z "${major_version}" ]]; then
305
+ log_warning "Unable to determine Node.js version from: $(node -v)"
306
+ return 1
307
+ fi
308
+
309
+ if [[ "${major_version}" -ge 20 ]]; then
310
+ log_success "Node.js v${current_version} is already installed (>= 20)"
311
+ return 0
312
+ else
313
+ log_warning "Node.js v${current_version} is installed but version < 20"
314
+ return 1
315
+ fi
316
+ }
317
+
318
+ # ============================================
319
+ # Install Node.js
320
+ # ============================================
321
+ install_nodejs() {
322
+ local platform
323
+ platform=$(uname -s)
324
+
325
+ case "${platform}" in
326
+ Linux|Darwin)
327
+ log_info "Installing Node.js on ${platform}..."
328
+
329
+ # Install NVM
330
+ if ! install_nvm; then
331
+ log_error "Failed to install NVM"
332
+ return 1
333
+ fi
334
+
335
+ # Load NVM
336
+ export NVM_DIR="${HOME}/.nvm"
337
+ # shellcheck source=/dev/null
338
+ [[ -s "${NVM_DIR}/nvm.sh" ]] && \. "${NVM_DIR}/nvm.sh"
339
+
340
+ # Install Node.js
341
+ if ! install_nodejs_with_nvm; then
342
+ log_error "Failed to install Node.js"
343
+ return 1
344
+ fi
345
+ ;;
346
+ MINGW*|CYGWIN*|MSYS*)
347
+ log_error "Windows platform detected. Please use Windows installer or WSL."
348
+ log_info "Visit: https://nodejs.org/en/download/"
349
+ exit 1
350
+ ;;
351
+ *)
352
+ log_error "Unsupported platform: ${platform}"
353
+ exit 1
354
+ ;;
355
+ esac
356
+ }
357
+
358
+ # ============================================
359
+ # Check and install Node.js
360
+ # ============================================
361
+ check_and_install_nodejs() {
362
+ if check_node_version; then
363
+ log_info "Using existing Node.js installation"
364
+ clean_npmrc_conflict
365
+ else
366
+ log_warning "Installing or upgrading Node.js..."
367
+ install_nodejs
368
+ fi
369
+ }
370
+
371
+ # ============================================
372
+ # Fix npm permissions (without using sudo)
373
+ # ============================================
374
+ fix_npm_permissions() {
375
+ log_info "Checking npm permissions..."
376
+
377
+ local NPM_GLOBAL_DIR
378
+ NPM_GLOBAL_DIR=$(npm config get prefix 2>/dev/null) || true
379
+
380
+ # Determine whether we need to fall back to ~/.npm-global:
381
+ # 1. prefix is empty or contains an error string
382
+ # 2. prefix is a system directory (would break sudo setuid binaries)
383
+ # 3. prefix directory is not writable
384
+ local use_user_dir=false
385
+
386
+ if [[ -z "${NPM_GLOBAL_DIR}" ]] || [[ "${NPM_GLOBAL_DIR}" == *"error"* ]]; then
387
+ log_info "npm prefix is unset or invalid, switching to user directory"
388
+ use_user_dir=true
389
+ else
390
+ # SAFETY CHECK: Never use system directories
391
+ case "${NPM_GLOBAL_DIR}" in
392
+ /|/usr|/usr/local|/bin|/sbin|/lib|/lib64|/opt|/snap|/var|/etc)
393
+ log_warning "npm prefix is a system directory (${NPM_GLOBAL_DIR}), switching to user directory to avoid breaking system binaries."
394
+ use_user_dir=true
395
+ ;;
396
+ esac
397
+ fi
398
+
399
+ if [[ "${use_user_dir}" == false ]] && [[ ! -w "${NPM_GLOBAL_DIR}" ]]; then
400
+ log_warning "npm global directory is not writable: ${NPM_GLOBAL_DIR}, switching to user directory."
401
+ use_user_dir=true
402
+ fi
403
+
404
+ if [[ "${use_user_dir}" == true ]]; then
405
+ NPM_GLOBAL_DIR="${HOME}/.npm-global"
406
+ # Create the directory before setting prefix so npm config set succeeds
407
+ mkdir -p "${NPM_GLOBAL_DIR}"
408
+ npm config set prefix "${NPM_GLOBAL_DIR}"
409
+ log_success "npm prefix set to: ${NPM_GLOBAL_DIR}"
410
+
411
+ # Only add ~/.npm-global/bin to PATH when we actually use it
412
+ local PROFILE_FILE
413
+ PROFILE_FILE=$(get_shell_profile)
414
+ if [[ -n "${PROFILE_FILE}" ]] && ! grep -q '.npm-global/bin' "${PROFILE_FILE}" 2>/dev/null; then
415
+ {
416
+ echo ""
417
+ echo "# NPM global bin (added by Qwen Code installer)"
418
+ echo "export PATH=\"\$HOME/.npm-global/bin:\$PATH\""
419
+ } >> "${PROFILE_FILE}" 2>/dev/null || log_warning "Failed to write PATH update to ${PROFILE_FILE}"
420
+ log_info "Added npm global bin to PATH in ${PROFILE_FILE}"
421
+ fi
422
+ else
423
+ log_info "npm global directory is writable: ${NPM_GLOBAL_DIR}"
424
+ fi
425
+
426
+ return 0
427
+ }
428
+
429
+ # ============================================
430
+ # Install Qwen Code
431
+ # ============================================
432
+ install_qwen_code() {
433
+ # Ensure NVM node is in PATH
434
+ export NVM_DIR="${HOME}/.nvm"
435
+ # shellcheck source=/dev/null
436
+ [[ -s "${NVM_DIR}/nvm.sh" ]] && \. "${NVM_DIR}/nvm.sh" 2>/dev/null || true
437
+
438
+ # Add npm global bin to PATH
439
+ local NPM_GLOBAL_BIN
440
+ NPM_GLOBAL_BIN=$(npm config get prefix 2>/dev/null)/bin
441
+ if [[ -n "${NPM_GLOBAL_BIN}" ]]; then
442
+ export PATH="${NPM_GLOBAL_BIN}:${PATH}"
443
+ fi
444
+
445
+ if command_exists qwen; then
446
+ local QWEN_VERSION
447
+ QWEN_VERSION=$(qwen --version 2>/dev/null || echo "unknown")
448
+ log_success "Qwen Code is already installed: ${QWEN_VERSION}"
449
+ log_info "Upgrading to the latest version..."
450
+ fi
451
+
452
+ # Clean npmrc conflicts
453
+ clean_npmrc_conflict
454
+
455
+ # Fix npm permissions if needed
456
+ fix_npm_permissions
457
+
458
+ # Install Qwen Code
459
+ log_info "Installing Qwen Code..."
460
+ if npm install -g @qwen-code/qwen-code@latest --registry https://registry.npmmirror.com; then
461
+ log_success "Qwen Code installed successfully!"
462
+
463
+ # Verify installation
464
+ if command_exists qwen; then
465
+ local qwen_version
466
+ qwen_version=$(qwen --version 2>/dev/null) || qwen_version="unknown"
467
+ log_info "Qwen Code version: ${qwen_version}"
468
+ fi
469
+ else
470
+ log_error "Failed to install Qwen Code!"
471
+ log_info "Please check your internet connection and try again"
472
+ exit 1
473
+ fi
474
+
475
+ # Create source.json if source parameter was provided
476
+ if [[ "${SOURCE}" != "unknown" ]]; then
477
+ create_source_json
478
+ fi
479
+ }
480
+
481
+ # ============================================
482
+ # Create source.json
483
+ # ============================================
484
+ create_source_json() {
485
+ local QWEN_DIR="${HOME}/.qwen"
486
+
487
+ mkdir -p "${QWEN_DIR}"
488
+
489
+ # Escape special characters in SOURCE for JSON
490
+ local ESCAPED_SOURCE
491
+ ESCAPED_SOURCE=$(printf '%s' "${SOURCE}" | sed 's/\\/\\\\/g; s/"/\\"/g')
492
+
493
+ cat > "${QWEN_DIR}/source.json" <<EOF
494
+ {
495
+ "source": "${ESCAPED_SOURCE}"
496
+ }
497
+ EOF
498
+
499
+ log_success "Installation source saved to ~/.qwen/source.json"
500
+ }
501
+
502
+ # ============================================
503
+ # Main function
504
+ # ============================================
505
+ main() {
506
+ # Validate HOME variable
507
+ if [[ -z "${HOME}" ]]; then
508
+ log_warning "HOME environment variable is not set"
509
+ local MAIN_UID
510
+ MAIN_UID=$(id -u) || true
511
+ if [[ "${MAIN_UID}" -eq 0 ]]; then
512
+ export HOME="/root"
513
+ else
514
+ local CURRENT_USER
515
+ CURRENT_USER=$(whoami) || true
516
+ local user_home
517
+ user_home=$(eval echo "~${CURRENT_USER}") || true
518
+ export HOME="${user_home}"
519
+ fi
520
+ log_info "Using HOME=${HOME}"
521
+ fi
522
+
523
+ # Ensure download tool is available
524
+ ensure_download_tool
525
+
526
+ # Check and install Node.js
527
+ check_and_install_nodejs
528
+ echo ""
529
+
530
+ # Install Qwen Code
531
+ install_qwen_code
532
+ echo ""
533
+
534
+ # ============================================
535
+ # Final instructions
536
+ # ============================================
537
+ echo "=========================================="
538
+ echo "✅ Installation completed!"
539
+ echo "=========================================="
540
+ echo ""
541
+
542
+ # Ensure NVM and npm global bin are in PATH
543
+ export NVM_DIR="${HOME}/.nvm"
544
+ # shellcheck source=/dev/null
545
+ [[ -s "${NVM_DIR}/nvm.sh" ]] && \. "${NVM_DIR}/nvm.sh" 2>/dev/null || true
546
+ local NPM_GLOBAL_BIN
547
+ NPM_GLOBAL_BIN=$(npm config get prefix 2>/dev/null)/bin
548
+ if [[ -n "${NPM_GLOBAL_BIN}" ]]; then
549
+ export PATH="${NPM_GLOBAL_BIN}:${PATH}"
550
+ fi
551
+
552
+ # Check if qwen is immediately available
553
+ if command_exists qwen; then
554
+ log_success "Qwen Code is ready to use!"
555
+ echo ""
556
+ log_info "Tips: Please restart your terminal and run: qwen"
557
+ echo ""
558
+ else
559
+ log_warning "Tips: To start using Qwen Code, please run:"
560
+ echo ""
561
+ local PROFILE_FILE
562
+ PROFILE_FILE=$(get_shell_profile)
563
+ echo " source ${PROFILE_FILE}"
564
+ echo ""
565
+ log_info "Or simply restart your terminal, then run: qwen"
566
+ fi
567
+ }
568
+
569
+ # Run main function
570
+ main "$@"