browser4-cli 4.13.7 → 4.13.8

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.
package/README.md CHANGED
@@ -144,18 +144,19 @@ npm install -g browser4-cli
144
144
  browser4-cli install
145
145
  ```
146
146
 
147
- Or bootstrap the native binary directly with a single command:
147
+ Or bootstrap the native binary directly with a single command. The scripts
148
+ also install the Browser4 backend (runtime bundle) afterwards — running
149
+ `browser4-cli install` on a fresh machine, or `browser4-cli upgrade` when a
150
+ backend is already present (pass `--skip-backend` to skip this step):
148
151
 
149
152
  **Windows (PowerShell):**
150
153
  ```powershell
151
154
  irm https://browser4.oss-cn-beijing.aliyuncs.com/scripts/install-browser4-cli.ps1 | iex
152
- browser4-cli install
153
155
  ```
154
156
 
155
157
  **Linux / macOS (bash):**
156
158
  ```bash
157
159
  curl -fsSL https://browser4.oss-cn-beijing.aliyuncs.com/scripts/install-browser4-cli.sh | bash
158
- browser4-cli install
159
160
  ```
160
161
 
161
162
  ## 💡 CLI Guide for Humans
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browser4-cli",
3
- "version": "4.13.7",
3
+ "version": "4.13.8",
4
4
  "description": "Browser automation CLI for AI agents",
5
5
  "type": "module",
6
6
  "files": [
package/scripts/README.md CHANGED
@@ -32,6 +32,8 @@ Options: `--skip-docker-build`, `--dry-run`.
32
32
 
33
33
  Both scripts auto-detect OS, CPU architecture, and libc variant (glibc vs musl on Linux). They download the matching binary from GitHub Releases or Alibaba Cloud OSS (auto-selected by locale: OSS first in China mainland). The binary is installed to a user-local directory and optionally added to PATH.
34
34
 
35
+ After the CLI binary is in place, both scripts install the Browser4 backend (runtime bundle) using the freshly installed CLI: `browser4-cli install` on a fresh machine, or `browser4-cli upgrade` when a backend is already present (upgrades to the latest version). Pass `--skip-backend` / `-SkipBackend` to install the CLI only. When `--version TAG` is given, the backend is installed/upgraded with the matching `--tag TAG`.
36
+
35
37
  ### Common options
36
38
 
37
39
  | Option | Description |
@@ -44,6 +46,7 @@ Both scripts auto-detect OS, CPU architecture, and libc variant (glibc vs musl o
44
46
  | `--dry-run` / `-DryRun` | Print what would be done without doing it. |
45
47
  | `--skip-if-installed` / `-SkipIfInstalled` | Skip download if binary already exists. |
46
48
  | `--skip-local` / `-SkipLocal` | Skip local bundled binary check; always download. |
49
+ | `--skip-backend` / `-SkipBackend` | Skip installing/upgrading the Browser4 backend. |
47
50
  | `--force` / `-Force` (pwsh) | Force reinstallation even if the binary already exists at the target path. |
48
51
  | `--locate` / `-Locate` | Print detection results (OS, arch, locale) and exit (no install). |
49
52
 
@@ -52,6 +52,12 @@
52
52
  Force reinstallation even if the binary is already installed at the target path.
53
53
  Overrides -SkipIfInstalled and bypasses locked-file workarounds.
54
54
 
55
+ .PARAMETER SkipBackend
56
+ Skip installing/upgrading the Browser4 backend (runtime bundle).
57
+ By default, after the CLI binary is in place the script runs
58
+ `browser4-cli install` (or `browser4-cli upgrade` when a backend is
59
+ already installed).
60
+
55
61
  .PARAMETER Locate
56
62
  Print detection results (OS, architecture, script location, China locale)
57
63
  and exit without installing. Useful for diagnostics.
@@ -103,6 +109,7 @@ param(
103
109
  [switch]$SkipIfInstalled,
104
110
  [switch]$SkipLocal,
105
111
  [switch]$Force,
112
+ [switch]$SkipBackend,
106
113
  [switch]$Locate
107
114
  )
108
115
 
@@ -604,6 +611,89 @@ function Add-DirectoryToUserPath {
604
611
  $env:Path = "$env:Path;$Dir"
605
612
  }
606
613
 
614
+ # ----------------------------------------------
615
+ # Backend (runtime bundle) install / upgrade
616
+ # ----------------------------------------------
617
+
618
+ <#
619
+ .SYNOPSIS
620
+ Decide which backend command to run based on `browser4-cli status` output.
621
+ Returns "install" when no runtime bundle is installed, otherwise "upgrade".
622
+ #>
623
+ function Get-BackendAction {
624
+ param([string]$StatusOutput)
625
+ if ($StatusOutput -match 'Installed bundle: not installed') {
626
+ return "install"
627
+ }
628
+ return "upgrade"
629
+ }
630
+
631
+ <#
632
+ .SYNOPSIS
633
+ Install or upgrade the Browser4 backend (runtime bundle) with the CLI
634
+ binary that was just installed:
635
+ - no backend installed yet -> browser4-cli install
636
+ - backend already present -> browser4-cli upgrade (to the latest)
637
+ Passes -Version through as --tag so the backend matches the CLI version.
638
+ Non-fatal: failures print guidance and leave the CLI usable.
639
+ #>
640
+ function Install-Backend {
641
+ param([string]$CliPath, [string]$Tag)
642
+
643
+ if ($SkipBackend) {
644
+ Write-Step "Skipping backend install/upgrade (-SkipBackend)"
645
+ return
646
+ }
647
+
648
+ Write-Step "Checking for an existing Browser4 backend..."
649
+
650
+ $statusOutput = ""
651
+ try {
652
+ $statusOutput = (& $CliPath status 2>&1 | Out-String)
653
+ } catch {
654
+ # Binary missing or not runnable yet (e.g. --dry-run) -- fall through.
655
+ $statusOutput = ""
656
+ }
657
+
658
+ $action = Get-BackendAction -StatusOutput $statusOutput
659
+
660
+ $backendArgs = @($action)
661
+ if ($Tag) { $backendArgs += @('--tag', $Tag) }
662
+
663
+ if ($action -eq 'install') {
664
+ Write-Step "No backend installed -- running 'browser4-cli install'..."
665
+ } else {
666
+ Write-Step "Backend already installed -- running 'browser4-cli upgrade'..."
667
+ }
668
+
669
+ if ($DryRun) {
670
+ Write-Check "[DRY-RUN] Would run: $CliPath $($backendArgs -join ' ')"
671
+ return
672
+ }
673
+
674
+ if ($Silent) {
675
+ $backendOutput = ""
676
+ try {
677
+ $backendOutput = (& $CliPath @backendArgs 2>&1 | Out-String)
678
+ } catch {
679
+ $backendOutput = $_.Exception.Message
680
+ }
681
+ if ($LASTEXITCODE -eq 0) {
682
+ Write-Check "Backend $action succeeded ($($backendArgs -join ' '))."
683
+ } else {
684
+ Write-WarnMsg "Backend $action failed ($($backendArgs -join ' ')). Retry with: browser4-cli $($backendArgs -join ' ')"
685
+ Write-Host $backendOutput -ForegroundColor Red
686
+ }
687
+ } else {
688
+ & $CliPath @backendArgs
689
+ if ($LASTEXITCODE -eq 0) {
690
+ Write-Check "Backend $action succeeded ($($backendArgs -join ' '))."
691
+ } else {
692
+ Write-WarnMsg "Backend $action failed ($($backendArgs -join ' ')). Retry with: browser4-cli $($backendArgs -join ' ')"
693
+ }
694
+ }
695
+ }
696
+
607
697
  # ----------------------------------------------
608
698
  # Main
609
699
  # ----------------------------------------------
@@ -800,6 +890,12 @@ Please check:
800
890
  Write-Summary "[DRY-RUN] Installation plan complete" -Color Yellow
801
891
  }
802
892
 
893
+ # Install / upgrade the Browser4 backend (runtime bundle) using the CLI
894
+ # binary we just installed. Fresh machines get `browser4-cli install`;
895
+ # machines that already have a backend get `browser4-cli upgrade`.
896
+ Write-Summary ""
897
+ Install-Backend -CliPath $binaryPath -Tag $Version
898
+
803
899
  Write-Summary ""
804
900
  Write-Summary "Run 'browser4-cli --help' to get started." -Color Cyan
805
901
 
@@ -4,7 +4,9 @@
4
4
  #
5
5
  # Detects OS, CPU architecture, and libc variant (glibc / musl), downloads
6
6
  # the matching binary from GitHub Releases or Alibaba Cloud OSS, and installs
7
- # it to a user-local directory.
7
+ # it to a user-local directory. After the CLI binary is in place it also
8
+ # installs the Browser4 backend (runtime bundle) via `browser4-cli install`,
9
+ # or upgrades an existing backend via `browser4-cli upgrade`.
8
10
  #
9
11
  # Usage:
10
12
  # curl -fsSL https://.../install-browser4-cli.sh | bash
@@ -23,6 +25,7 @@
23
25
  # --silent, -s Suppress non-error output.
24
26
  # --dry-run Print what would be done without doing it.
25
27
  # --skip-if-installed Skip download if binary already exists at install path.
28
+ # --skip-backend Skip installing/upgrading the Browser4 backend.
26
29
  # --help, -h Show this message.
27
30
 
28
31
  set -euo pipefail
@@ -42,6 +45,7 @@ SILENT=false
42
45
  DRY_RUN=false
43
46
  SKIP_IF_INSTALLED=false
44
47
  SKIP_LOCAL=false
48
+ SKIP_BACKEND=false
45
49
  LOCATE_MODE=false
46
50
  CHINA_DETECTED=false
47
51
  SCRIPT_DIR=""
@@ -130,6 +134,7 @@ Options:
130
134
  --silent, -s Suppress non-error output.
131
135
  --dry-run Print what would be done without doing it.
132
136
  --skip-if-installed Skip download if binary already exists at install path.
137
+ --skip-backend Skip installing/upgrading the Browser4 backend.
133
138
  --help, -h Show this message.
134
139
 
135
140
  Examples:
@@ -141,6 +146,7 @@ Examples:
141
146
  $(basename "$0") --skip-local # Force download, ignore bundled binary
142
147
  $(basename "$0") --source oss # Force Aliyun OSS (China mainland)
143
148
  $(basename "$0") --skip-if-installed # Skip download if already installed
149
+ $(basename "$0") --skip-backend # CLI only, skip backend install/upgrade
144
150
  EOF
145
151
  }
146
152
 
@@ -168,6 +174,7 @@ while [[ $# -gt 0 ]]; do
168
174
  --silent|-s) SILENT=true; shift ;;
169
175
  --dry-run) DRY_RUN=true; shift ;;
170
176
  --skip-if-installed) SKIP_IF_INSTALLED=true; shift ;;
177
+ --skip-backend) SKIP_BACKEND=true; shift ;;
171
178
  --help|-h) usage; exit 0 ;;
172
179
  *) die "Unknown argument: $1 (use --help)";;
173
180
  esac
@@ -542,6 +549,72 @@ create_symlinks() {
542
549
  fi
543
550
  }
544
551
 
552
+ # ----------------------------------------------
553
+ # Backend (runtime bundle) install / upgrade
554
+ # ----------------------------------------------
555
+
556
+ # Decide which backend command to run based on `browser4-cli status` output.
557
+ # Echoes "install" when no runtime bundle is installed yet, otherwise
558
+ # "upgrade" (refresh CLI + runtime to the latest version).
559
+ pick_backend_action() {
560
+ local status_output="$1"
561
+ if echo "$status_output" | grep -q "Installed bundle: not installed"; then
562
+ echo "install"
563
+ else
564
+ echo "upgrade"
565
+ fi
566
+ }
567
+
568
+ # After the CLI binary is in place, install the Browser4 backend:
569
+ # - no backend installed yet -> browser4-cli install
570
+ # - backend already present -> browser4-cli upgrade (to the latest)
571
+ # A --version tag is passed through as --tag so the backend matches the CLI.
572
+ # Non-fatal: a failed backend step leaves a working CLI behind.
573
+ install_backend() {
574
+ local cli_path="$1"
575
+ local tag="$2"
576
+
577
+ if [[ "$SKIP_BACKEND" == true ]]; then
578
+ step "Skipping backend install/upgrade (--skip-backend)"
579
+ return 0
580
+ fi
581
+
582
+ step "Checking for an existing Browser4 backend..."
583
+
584
+ local status_output
585
+ status_output=$("$cli_path" status 2>&1 || true)
586
+
587
+ local action
588
+ action=$(pick_backend_action "$status_output")
589
+
590
+ local args=("$action")
591
+ if [[ -n "$tag" ]]; then
592
+ args+=(--tag "$tag")
593
+ fi
594
+
595
+ if [[ "$action" == "install" ]]; then
596
+ step "No backend installed -- running 'browser4-cli install'..."
597
+ else
598
+ step "Backend already installed -- running 'browser4-cli upgrade'..."
599
+ fi
600
+
601
+ if [[ "$DRY_RUN" == true ]]; then
602
+ ok "[DRY-RUN] Would run: $cli_path ${args[*]}"
603
+ return 0
604
+ fi
605
+
606
+ local backend_output
607
+ if backend_output=$("$cli_path" "${args[@]}" 2>&1); then
608
+ ok "Backend ${action} succeeded (${args[*]})."
609
+ if [[ "$SILENT" != true ]]; then
610
+ echo "$backend_output"
611
+ fi
612
+ else
613
+ echo " [!] Backend ${action} failed (${args[*]}). Retry manually with: browser4-cli ${args[*]}" >&2
614
+ echo "$backend_output" >&2
615
+ fi
616
+ }
617
+
545
618
  # ----------------------------------------------
546
619
  # Main
547
620
  # ----------------------------------------------
@@ -743,6 +816,12 @@ main() {
743
816
  echo -e "${color_yellow}[DRY-RUN] Installation plan complete${color_reset}"
744
817
  fi
745
818
 
819
+ # Install / upgrade the Browser4 backend (runtime bundle) using the CLI
820
+ # we just installed. Fresh machines get `browser4-cli install`; machines
821
+ # that already have a backend get `browser4-cli upgrade` to the latest.
822
+ say ""
823
+ install_backend "$binary_path" "$VERSION"
824
+
746
825
  say ""
747
826
  echo -e "${color_cyan}Run 'browser4-cli --help' to get started.${color_reset}"
748
827
 
@@ -102,7 +102,8 @@ $ast = [System.Management.Automation.Language.Parser]::ParseInput($content, [ref
102
102
 
103
103
  Test "param block defines all expected parameters" {
104
104
  $expected = @('Version', 'InstallDir', 'Source', 'AddToPath',
105
- 'Silent', 'DryRun', 'SkipIfInstalled', 'SkipLocal', 'Locate')
105
+ 'Silent', 'DryRun', 'SkipIfInstalled', 'SkipLocal',
106
+ 'Force', 'SkipBackend', 'Locate')
106
107
  # Extract param block text via AST extents
107
108
  $paramAst = $ast.ParamBlock
108
109
  if (-not $paramAst) { throw "Could not find param block AST" }
@@ -189,6 +190,28 @@ Test "-SkipIfInstalled flag accepted" {
189
190
  if ($ec3 -ne 0) { throw "Exit code: $ec3, output: $($r3.Output)" }
190
191
  }
191
192
 
193
+ Test "-SkipBackend flag accepted" {
194
+ $ecSkipBackend = 0
195
+ $rSkipBackend = RunScript -scriptArgs "-SkipBackend -DryRun" -exitCode ([ref]$ecSkipBackend)
196
+ if ($ecSkipBackend -ne 0) { throw "Exit code: $ecSkipBackend, output: $($rSkipBackend.Output)" }
197
+ }
198
+
199
+ Test "-DryRun prints backend plan" {
200
+ $ecPlan = 0
201
+ $rPlan = RunScript -scriptArgs "-DryRun -AddToPath:`$false" -exitCode ([ref]$ecPlan)
202
+ if ($rPlan.Output -notmatch 'Would run:') {
203
+ throw "Expected backend plan ('Would run:') in: $($rPlan.Output.Substring(0, [Math]::Min(800, $rPlan.Output.Length)))"
204
+ }
205
+ }
206
+
207
+ Test "-SkipBackend suppresses backend plan" {
208
+ $ecSkip = 0
209
+ $rSkip = RunScript -scriptArgs "-SkipBackend -DryRun -AddToPath:`$false" -exitCode ([ref]$ecSkip)
210
+ if ($rSkip.Output -match 'Would run:') {
211
+ throw "Expected no backend plan with -SkipBackend, got: $($rSkip.Output.Substring(0, [Math]::Min(800, $rSkip.Output.Length)))"
212
+ }
213
+ }
214
+
192
215
  Test "-SkipLocal flag accepted" {
193
216
  $ec4 = 0; $r4 = RunScript -scriptArgs "-SkipLocal -DryRun" -exitCode ([ref]$ec4)
194
217
  if ($ec4 -ne 0) { throw "Exit code: $ec4, output: $($r4.Output)" }
@@ -297,6 +320,21 @@ $sb = [ScriptBlock]::Create($scriptContent)
297
320
  Test "Test-LocalBinary returns false for null" {
298
321
  if (Test-LocalBinary -Path $null) { throw "Should be false" }
299
322
  }
323
+
324
+ Test "Get-BackendAction returns install when not installed" {
325
+ $action = Get-BackendAction -StatusOutput "Installed bundle: not installed (run 'browser4-cli install')"
326
+ if ($action -ne "install") { throw "Expected 'install', got: $action" }
327
+ }
328
+
329
+ Test "Get-BackendAction returns upgrade when installed" {
330
+ $action = Get-BackendAction -StatusOutput "Installed bundle: v4.13.0 (at 2026-01-01T00:00:00Z)"
331
+ if ($action -ne "upgrade") { throw "Expected 'upgrade', got: $action" }
332
+ }
333
+
334
+ Test "Get-BackendAction defaults to upgrade on empty status" {
335
+ $action = Get-BackendAction -StatusOutput ""
336
+ if ($action -ne "upgrade") { throw "Expected 'upgrade', got: $action" }
337
+ }
300
338
  }
301
339
 
302
340
  Write-Host ""
@@ -263,9 +263,22 @@ test "test_local_binary returns error for nonexistent" bash -c "
263
263
  ! test_local_binary '/nonexistent/path/binary' 2>/dev/null
264
264
  "
265
265
 
266
- echo ""
266
+ test "pick_backend_action returns install when not installed" bash -c "
267
+ source '$FUNC_TEST_SCRIPT' >/dev/null 2>&1
268
+ [[ \"\$(pick_backend_action 'Installed bundle: not installed (run browser4-cli install)')\" == 'install' ]]
269
+ "
270
+
271
+ test "pick_backend_action returns upgrade when installed" bash -c "
272
+ source '$FUNC_TEST_SCRIPT' >/dev/null 2>&1
273
+ [[ \"\$(pick_backend_action 'Installed bundle: v4.13.0 (at 2026-01-01T00:00:00Z)')\" == 'upgrade' ]]
274
+ "
267
275
 
268
- # ── --skip-if-installed behavior ───────────────────────
276
+ test "pick_backend_action defaults to upgrade on empty status" bash -c "
277
+ source '$FUNC_TEST_SCRIPT' >/dev/null 2>&1
278
+ [[ \"\$(pick_backend_action '')\" == 'upgrade' ]]
279
+ "
280
+
281
+ echo ""
269
282
 
270
283
  echo "--- --skip-if-installed ---" | cyan
271
284
 
@@ -275,6 +288,32 @@ test "--skip-if-installed flag accepted" bash -c "
275
288
 
276
289
  echo ""
277
290
 
291
+ # ── Backend install/upgrade ────────────────────────────
292
+
293
+ echo "--- Backend install/upgrade ---" | cyan
294
+
295
+ test "--help mentions --skip-backend" bash -c "
296
+ bash '$INSTALL_SCRIPT' --help 2>&1 | grep -q 'skip-backend'
297
+ "
298
+
299
+ test "--skip-backend flag accepted" bash -c "
300
+ bash '$INSTALL_SCRIPT' --skip-backend --dry-run 2>&1 | grep -qi 'skip-backend\|DRY-RUN'
301
+ "
302
+
303
+ test "--dry-run prints backend plan" bash -c "
304
+ bash '$INSTALL_SCRIPT' --dry-run --no-path 2>&1 | grep -q 'Would run:'
305
+ "
306
+
307
+ test "--skip-backend suppresses backend plan" bash -c "
308
+ ! bash '$INSTALL_SCRIPT' --skip-backend --dry-run --no-path 2>&1 | grep -q 'Would run:'
309
+ "
310
+
311
+ test "--version passes tag to backend plan" bash -c "
312
+ bash '$INSTALL_SCRIPT' --dry-run --no-path --version v4.11.0 2>&1 | grep -q 'Would run:.*--tag v4\.11\.0'
313
+ "
314
+
315
+ echo ""
316
+
278
317
  # ── Header UX ──────────────────────────────────────────
279
318
 
280
319
  echo "--- Header ---" | cyan