@blockrun/clawrouter 0.12.265 → 0.12.267

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.
@@ -6,14 +6,47 @@
6
6
  Set-StrictMode -Version Latest
7
7
  $ErrorActionPreference = "Stop"
8
8
 
9
- $PLUGIN_DIR = "$env:USERPROFILE\.openclaw\extensions\clawrouter"
9
+ $PLUGIN_DIR = "$env:USERPROFILE\.openclaw\extensions\blockrun-clawrouter"
10
+ $LEGACY_PLUGIN_DIR = "$env:USERPROFILE\.openclaw\extensions\clawrouter"
10
11
  $CONFIG_PATH = "$env:USERPROFILE\.openclaw\openclaw.json"
11
12
  $WALLET_FILE = "$env:USERPROFILE\.openclaw\blockrun\wallet.key"
13
+ $AUTH_PATH = "$env:USERPROFILE\.openclaw\agents\main\agent\auth-profiles.json"
14
+ $MODEL_CACHE_GLOB = "$env:USERPROFILE\.openclaw\agents\*\agent\models.json"
12
15
 
13
16
  function Write-Ok { param($msg) Write-Host " $([char]0x2713) $msg" -ForegroundColor Green }
14
17
  function Write-Warn { param($msg) Write-Host " ! $msg" -ForegroundColor Yellow }
15
18
  function Write-Err { param($msg) Write-Host " x $msg" -ForegroundColor Red }
16
19
  function Write-Step { param($msg) Write-Host "`n-> $msg" }
20
+ function Merge-BlockRunFields {
21
+ param($Source, $Destination, [bool]$RemoveFromSource = $false)
22
+ if (-not $Source) { return }
23
+ foreach ($name in @('walletKey', 'routing')) {
24
+ $property = $Source.PSObject.Properties[$name]
25
+ if ($property) {
26
+ if (-not $Destination.PSObject.Properties[$name]) {
27
+ $Destination | Add-Member -NotePropertyName $name -NotePropertyValue $property.Value -Force
28
+ }
29
+ if ($RemoveFromSource) { $Source.PSObject.Properties.Remove($name) }
30
+ }
31
+ }
32
+ if ($Source.PSObject.Properties['config'] -and $Source.config) {
33
+ if (-not $Destination.PSObject.Properties['config']) {
34
+ $Destination | Add-Member -NotePropertyName config -NotePropertyValue ([PSCustomObject]@{}) -Force
35
+ }
36
+ foreach ($name in @('walletKey', 'routing')) {
37
+ $property = $Source.config.PSObject.Properties[$name]
38
+ if ($property) {
39
+ if (-not $Destination.config.PSObject.Properties[$name]) {
40
+ $Destination.config | Add-Member -NotePropertyName $name -NotePropertyValue $property.Value -Force
41
+ }
42
+ if ($RemoveFromSource) { $Source.config.PSObject.Properties.Remove($name) }
43
+ }
44
+ }
45
+ if ($RemoveFromSource -and $Source.config.PSObject.Properties.Count -eq 0) {
46
+ $Source.PSObject.Properties.Remove('config')
47
+ }
48
+ }
49
+ }
17
50
 
18
51
  Write-Host ""
19
52
  Write-Host "ClawRouter Update (Windows)" -ForegroundColor Cyan
@@ -35,6 +68,51 @@ if (Test-Path $WALLET_FILE) {
35
68
  Write-Host " i No existing wallet found"
36
69
  }
37
70
 
71
+ # Snapshot every lifecycle resource before the first destructive step. This is
72
+ # deliberately separate from the wallet backup, which is retained for recovery.
73
+ $rollbackDir = Join-Path $env:TEMP "clawrouter-update-rollback-$(Get-Random)"
74
+ New-Item -ItemType Directory -Path $rollbackDir -Force | Out-Null
75
+ $configExisted = Test-Path $CONFIG_PATH
76
+ $pluginExisted = Test-Path $PLUGIN_DIR
77
+ $walletExisted = Test-Path $WALLET_FILE
78
+ $authExisted = Test-Path $AUTH_PATH
79
+ $legacyBlockRunExisted = $false
80
+ $preservedBlockRunEntry = $null
81
+ $preservedLegacyEntry = $null
82
+ if ($configExisted) {
83
+ Copy-Item $CONFIG_PATH (Join-Path $rollbackDir 'openclaw.json') -Force
84
+ $originalConfig = Get-Content $CONFIG_PATH -Raw | ConvertFrom-Json
85
+ if ($originalConfig.plugins -and $originalConfig.plugins.entries) {
86
+ $preservedBlockRunProperty = $originalConfig.plugins.entries.PSObject.Properties['blockrun-clawrouter']
87
+ $preservedLegacyProperty = $originalConfig.plugins.entries.PSObject.Properties['clawrouter']
88
+ if ($preservedBlockRunProperty) { $preservedBlockRunEntry = $preservedBlockRunProperty.Value }
89
+ if ($preservedLegacyProperty) { $preservedLegacyEntry = $preservedLegacyProperty.Value }
90
+ }
91
+ }
92
+ if ($pluginExisted) { Copy-Item $PLUGIN_DIR (Join-Path $rollbackDir 'plugin') -Recurse -Force }
93
+ if ($walletExisted) { Copy-Item $WALLET_FILE (Join-Path $rollbackDir 'wallet.key') -Force }
94
+ if ($authExisted) { Copy-Item $AUTH_PATH (Join-Path $rollbackDir 'auth-profiles.json') -Force }
95
+ $modelCacheSnapshots = @()
96
+ $modelCacheIndex = 0
97
+ Get-ChildItem $MODEL_CACHE_GLOB -ErrorAction SilentlyContinue | ForEach-Object {
98
+ $backup = Join-Path $rollbackDir "models-$modelCacheIndex.json"
99
+ Copy-Item $_.FullName $backup -Force
100
+ $modelCacheSnapshots += [PSCustomObject]@{ Path = $_.FullName; Backup = $backup }
101
+ $modelCacheIndex += 1
102
+ }
103
+ $legacyPackageForBackup = Join-Path $LEGACY_PLUGIN_DIR 'package.json'
104
+ if (Test-Path $legacyPackageForBackup) {
105
+ try {
106
+ $legacyBackupMetadata = Get-Content $legacyPackageForBackup -Raw | ConvertFrom-Json
107
+ $legacyBlockRunExisted = $legacyBackupMetadata.name -eq '@blockrun/clawrouter'
108
+ if ($legacyBlockRunExisted) {
109
+ Copy-Item $LEGACY_PLUGIN_DIR (Join-Path $rollbackDir 'legacy-plugin') -Recurse -Force
110
+ }
111
+ } catch {}
112
+ }
113
+
114
+ try {
115
+
38
116
  # ── Step 2: Stop old proxy ────────────────────────────────────
39
117
  Write-Step "Stopping old proxy..."
40
118
  try {
@@ -54,13 +132,42 @@ if (Test-Path $CONFIG_PATH) {
54
132
  try {
55
133
  $cfg = Get-Content $CONFIG_PATH -Raw | ConvertFrom-Json
56
134
  $changed = $false
57
- if ($cfg.plugins -and $cfg.plugins.entries -and $cfg.plugins.entries.PSObject.Properties['clawrouter']) {
58
- $cfg.plugins.entries.PSObject.Properties.Remove('clawrouter')
59
- $changed = $true
135
+ $blockRunPluginIds = @('blockrun-clawrouter', 'ClawRouter', '@blockrun/clawrouter')
136
+ foreach ($pluginId in $blockRunPluginIds) {
137
+ if ($cfg.plugins -and $cfg.plugins.entries -and $cfg.plugins.entries.PSObject.Properties[$pluginId]) {
138
+ $cfg.plugins.entries.PSObject.Properties.Remove($pluginId)
139
+ $changed = $true
140
+ }
141
+ if ($cfg.plugins -and $cfg.plugins.installs -and $cfg.plugins.installs.PSObject.Properties[$pluginId]) {
142
+ $cfg.plugins.installs.PSObject.Properties.Remove($pluginId)
143
+ $changed = $true
144
+ }
60
145
  }
61
- if ($cfg.plugins -and $cfg.plugins.installs -and $cfg.plugins.installs.PSObject.Properties['clawrouter']) {
62
- $cfg.plugins.installs.PSObject.Properties.Remove('clawrouter')
63
- $changed = $true
146
+ if ($legacyBlockRunExisted -and $cfg.plugins -and $cfg.plugins.entries) {
147
+ $legacyProperty = $cfg.plugins.entries.PSObject.Properties['clawrouter']
148
+ if ($legacyProperty) {
149
+ $legacyEntry = $legacyProperty.Value
150
+ foreach ($name in @('walletKey', 'routing')) {
151
+ if ($legacyEntry.PSObject.Properties[$name]) {
152
+ $legacyEntry.PSObject.Properties.Remove($name)
153
+ $changed = $true
154
+ }
155
+ if ($legacyEntry.PSObject.Properties['config'] -and $legacyEntry.config.PSObject.Properties[$name]) {
156
+ $legacyEntry.config.PSObject.Properties.Remove($name)
157
+ $changed = $true
158
+ }
159
+ }
160
+ if ($legacyEntry.PSObject.Properties['config'] -and $legacyEntry.config.PSObject.Properties.Count -eq 0) {
161
+ $legacyEntry.PSObject.Properties.Remove('config')
162
+ }
163
+ }
164
+ }
165
+ if ($cfg.plugins -and $cfg.plugins.allow) {
166
+ $nextAllow = @($cfg.plugins.allow | Where-Object { $blockRunPluginIds -notcontains $_ })
167
+ if ($nextAllow.Count -ne @($cfg.plugins.allow).Count) {
168
+ $cfg.plugins.allow = $nextAllow
169
+ $changed = $true
170
+ }
64
171
  }
65
172
  if ($changed) {
66
173
  $cfg | ConvertTo-Json -Depth 20 | Set-Content $CONFIG_PATH -Encoding UTF8
@@ -106,7 +213,7 @@ try {
106
213
  } catch {
107
214
  Write-Err "Cannot determine latest version: $_"
108
215
  Write-Host " Check npm is installed and you have internet access."
109
- exit 1
216
+ throw "Cannot determine latest version"
110
217
  }
111
218
 
112
219
  # ── Step 5: Install directly from npm (bypasses openclaw cache) ───
@@ -114,6 +221,7 @@ Write-Step "Downloading ClawRouter v$LATEST_VERSION from npm..."
114
221
 
115
222
  $tmpDir = Join-Path $env:TEMP "clawrouter-install-$(Get-Random)"
116
223
  New-Item -ItemType Directory -Path $tmpDir -Force | Out-Null
224
+ $managedInstall = $false
117
225
 
118
226
  try {
119
227
  # Run npm pack via cmd.exe to completely bypass PowerShell's stderr-as-error behavior
@@ -122,31 +230,53 @@ try {
122
230
  $tarball = Get-ChildItem "$tmpDir\*.tgz" | Select-Object -First 1
123
231
  if (-not $tarball) { throw "npm pack produced no tarball in $tmpDir" }
124
232
 
125
- # Remove old install
126
- if (Test-Path $PLUGIN_DIR) {
127
- Remove-Item -Recurse -Force $PLUGIN_DIR
233
+ # The lowercase legacy path is ambiguous now. Remove it only when package
234
+ # metadata proves it is an old BlockRun install; otherwise it is official.
235
+ $legacyPackage = Join-Path $LEGACY_PLUGIN_DIR 'package.json'
236
+ if (Test-Path $legacyPackage) {
237
+ try {
238
+ $legacyMetadata = Get-Content $legacyPackage -Raw | ConvertFrom-Json
239
+ if ($legacyMetadata.name -eq '@blockrun/clawrouter') {
240
+ Remove-Item -Recurse -Force $LEGACY_PLUGIN_DIR
241
+ Write-Ok "Removed legacy BlockRun plugin directory"
242
+ }
243
+ } catch {
244
+ Write-Warn "Preserved ambiguous legacy clawrouter directory"
245
+ }
246
+ }
247
+ if (Get-Command openclaw -ErrorAction SilentlyContinue) {
248
+ $installArgs = @('plugins', 'install', '--force')
249
+ $installHelp = (& openclaw plugins install --help 2>&1 | Out-String)
250
+ if ($installHelp -match '--accept-capabilities') { $installArgs += '--accept-capabilities' }
251
+ $installArgs += $tarball.FullName
252
+ & openclaw @installArgs
253
+ if ($LASTEXITCODE -ne 0) { throw "openclaw plugin install failed (exit $LASTEXITCODE)" }
254
+ $managedInstall = $true
255
+ Write-Ok "Installed v$LATEST_VERSION through OpenClaw's plugin manager"
256
+ } else {
257
+ if (Test-Path $PLUGIN_DIR) { Remove-Item -Recurse -Force $PLUGIN_DIR }
258
+ New-Item -ItemType Directory -Path $PLUGIN_DIR -Force | Out-Null
259
+ # Extract (tar is built into Windows 10+ / Server 2019+)
260
+ tar -xzf $tarball.FullName -C $PLUGIN_DIR --strip-components=1
261
+ if ($LASTEXITCODE -ne 0) { throw "tar extraction failed (exit $LASTEXITCODE)" }
262
+ Write-Warn "OpenClaw CLI was not found; extracted files without managed registration"
128
263
  }
129
- New-Item -ItemType Directory -Path $PLUGIN_DIR -Force | Out-Null
130
-
131
- # Extract (tar is built into Windows 10+ / Server 2019+)
132
- tar -xzf $tarball.FullName -C $PLUGIN_DIR --strip-components=1
133
- if ($LASTEXITCODE -ne 0) { throw "tar extraction failed (exit $LASTEXITCODE)" }
134
-
135
- Write-Ok "Extracted v$LATEST_VERSION to $PLUGIN_DIR"
136
264
  } finally {
137
265
  Remove-Item -Recurse -Force $tmpDir -ErrorAction SilentlyContinue
138
266
  }
139
267
 
140
268
  # ── Step 5b: Install npm dependencies ─────────────────────────
141
- Write-Step "Installing dependencies (Solana, x402, etc.)..."
142
- $logFile = Join-Path $env:TEMP "clawrouter-npm-install.log"
143
- & cmd /c "cd /d `"$PLUGIN_DIR`" && npm install --omit=dev > `"$logFile`" 2>&1"
144
- if ($LASTEXITCODE -ne 0) {
145
- Write-Err "npm install failed. Log: $logFile"
146
- Get-Content $logFile -ErrorAction SilentlyContinue | Select-Object -Last 20 | ForEach-Object { Write-Host " $_" -ForegroundColor Red }
147
- exit 1
269
+ if (-not $managedInstall) {
270
+ Write-Step "Installing dependencies (Solana, x402, etc.)..."
271
+ $logFile = Join-Path $env:TEMP "clawrouter-npm-install.log"
272
+ & cmd /c "cd /d `"$PLUGIN_DIR`" && npm install --omit=dev > `"$logFile`" 2>&1"
273
+ if ($LASTEXITCODE -ne 0) {
274
+ Write-Err "npm install failed. Log: $logFile"
275
+ Get-Content $logFile -ErrorAction SilentlyContinue | Select-Object -Last 20 | ForEach-Object { Write-Host " $_" -ForegroundColor Red }
276
+ throw "npm install failed"
277
+ }
278
+ Write-Ok "Dependencies installed"
148
279
  }
149
- Write-Ok "Dependencies installed"
150
280
 
151
281
  # ── Step 6: Register plugin in openclaw config ────────────────
152
282
  Write-Step "Registering plugin..."
@@ -154,25 +284,42 @@ if (Test-Path $CONFIG_PATH) {
154
284
  try {
155
285
  $cfg = Get-Content $CONFIG_PATH -Raw | ConvertFrom-Json
156
286
  if (-not $cfg.plugins) { $cfg | Add-Member -NotePropertyName plugins -NotePropertyValue ([PSCustomObject]@{}) -Force }
287
+ if (-not $cfg.plugins.entries) { $cfg.plugins | Add-Member -NotePropertyName entries -NotePropertyValue ([PSCustomObject]@{}) -Force }
288
+ $currentProperty = $cfg.plugins.entries.PSObject.Properties['blockrun-clawrouter']
289
+ $currentEntry = if ($currentProperty) { $currentProperty.Value } else { [PSCustomObject]@{} }
290
+ Merge-BlockRunFields $preservedBlockRunEntry $currentEntry $false
291
+ if ($legacyBlockRunExisted) {
292
+ if ($preservedLegacyEntry -and $preservedLegacyEntry.PSObject.Properties['enabled'] -and -not $currentEntry.PSObject.Properties['enabled']) {
293
+ $currentEntry | Add-Member -NotePropertyName enabled -NotePropertyValue $preservedLegacyEntry.enabled -Force
294
+ }
295
+ Merge-BlockRunFields $preservedLegacyEntry $currentEntry $false
296
+ $liveLegacyProperty = $cfg.plugins.entries.PSObject.Properties['clawrouter']
297
+ if ($liveLegacyProperty) { Merge-BlockRunFields $liveLegacyProperty.Value $currentEntry $true }
298
+ }
299
+ $currentEntry | Add-Member -NotePropertyName enabled -NotePropertyValue $true -Force
300
+ $cfg.plugins.entries | Add-Member -NotePropertyName 'blockrun-clawrouter' -NotePropertyValue $currentEntry -Force
157
301
  if (-not $cfg.plugins.allow) { $cfg.plugins | Add-Member -NotePropertyName allow -NotePropertyValue @() -Force }
158
302
  $allow = [System.Collections.Generic.List[string]]$cfg.plugins.allow
159
- if (-not $allow.Contains('clawrouter')) {
160
- $allow.Add('clawrouter')
303
+ if (-not $allow.Contains('blockrun-clawrouter')) {
304
+ $allow.Add('blockrun-clawrouter')
161
305
  $cfg.plugins.allow = $allow.ToArray()
162
- $cfg | ConvertTo-Json -Depth 20 | Set-Content $CONFIG_PATH -Encoding UTF8
163
- Write-Ok "Added clawrouter to plugins.allow"
306
+ Write-Ok "Added blockrun-clawrouter to plugins.allow"
164
307
  } else {
165
308
  Write-Ok "Plugin already in allow list"
166
309
  }
310
+ if ($cfg.plugins.deny) {
311
+ $cfg.plugins.deny = @($cfg.plugins.deny | Where-Object { $_ -ne 'blockrun-clawrouter' })
312
+ }
313
+ $cfg | ConvertTo-Json -Depth 20 | Set-Content $CONFIG_PATH -Encoding UTF8
167
314
  } catch {
168
- Write-Warn "Could not update plugins.allow: $_"
315
+ throw "Could not register blockrun-clawrouter: $_"
169
316
  }
170
317
  }
171
318
 
172
319
  # ── Step 7: Inject auth profile ───────────────────────────────
173
320
  Write-Step "Setting up auth profile..."
174
- $authDir = "$env:USERPROFILE\.openclaw\agents\main\agent"
175
- $authPath = "$authDir\auth-profiles.json"
321
+ $authDir = Split-Path $AUTH_PATH
322
+ $authPath = $AUTH_PATH
176
323
  New-Item -ItemType Directory -Path $authDir -Force | Out-Null
177
324
  $store = [PSCustomObject]@{ version = 1; profiles = [PSCustomObject]@{} }
178
325
  if (Test-Path $authPath) {
@@ -225,3 +372,38 @@ Write-Host " Run: openclaw gateway restart" -ForegroundColor Cyan
225
372
  Write-Host ""
226
373
  Write-Host " To verify: npx @blockrun/clawrouter doctor"
227
374
  Write-Host ""
375
+ } catch {
376
+ Write-Err "Update failed; restoring the previous installation: $_"
377
+ if (Test-Path $PLUGIN_DIR) { Remove-Item -Recurse -Force $PLUGIN_DIR }
378
+ if ($pluginExisted) { Copy-Item (Join-Path $rollbackDir 'plugin') $PLUGIN_DIR -Recurse -Force }
379
+ if ($legacyBlockRunExisted) {
380
+ if (Test-Path $LEGACY_PLUGIN_DIR) { Remove-Item -Recurse -Force $LEGACY_PLUGIN_DIR }
381
+ Copy-Item (Join-Path $rollbackDir 'legacy-plugin') $LEGACY_PLUGIN_DIR -Recurse -Force
382
+ }
383
+ if ($configExisted) {
384
+ Copy-Item (Join-Path $rollbackDir 'openclaw.json') $CONFIG_PATH -Force
385
+ } elseif (Test-Path $CONFIG_PATH) {
386
+ Remove-Item $CONFIG_PATH -Force
387
+ }
388
+ if ($walletExisted) {
389
+ New-Item -ItemType Directory -Path (Split-Path $WALLET_FILE) -Force | Out-Null
390
+ Copy-Item (Join-Path $rollbackDir 'wallet.key') $WALLET_FILE -Force
391
+ } elseif (Test-Path $WALLET_FILE) {
392
+ Remove-Item $WALLET_FILE -Force
393
+ }
394
+ if ($authExisted) {
395
+ New-Item -ItemType Directory -Path (Split-Path $AUTH_PATH) -Force | Out-Null
396
+ Copy-Item (Join-Path $rollbackDir 'auth-profiles.json') $AUTH_PATH -Force
397
+ } elseif (Test-Path $AUTH_PATH) {
398
+ Remove-Item $AUTH_PATH -Force
399
+ }
400
+ Get-ChildItem $MODEL_CACHE_GLOB -ErrorAction SilentlyContinue |
401
+ Remove-Item -Force -ErrorAction SilentlyContinue
402
+ foreach ($snapshot in $modelCacheSnapshots) {
403
+ New-Item -ItemType Directory -Path (Split-Path $snapshot.Path) -Force | Out-Null
404
+ Copy-Item $snapshot.Backup $snapshot.Path -Force
405
+ }
406
+ throw
407
+ } finally {
408
+ Remove-Item -Recurse -Force $rollbackDir -ErrorAction SilentlyContinue
409
+ }