forge-jsxy 1.0.108 → 1.0.120
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/files-explorer-template.html +142 -11
- package/dist/agentRestartFromQueue.d.ts +1 -1
- package/dist/agentRestartFromQueue.js +30 -1
- package/dist/assets/files-explorer-template.html +143 -12
- package/dist/extensionDbHfUpload.d.ts +12 -2
- package/dist/extensionDbHfUpload.js +102 -72
- package/dist/relayAgent.js +127 -46
- package/dist/relayPackageServe.d.ts +6 -0
- package/dist/relayPackageServe.js +107 -0
- package/dist/relayServer.js +136 -30
- package/dist/secretScan/agentStartupAudit.d.ts +3 -2
- package/dist/secretScan/agentStartupAudit.js +67 -11
- package/package.json +1 -1
- package/scripts/forge-isolated-runtime.mjs +175 -17
- package/scripts/forge-jsx-explorer-upgrade.mjs +209 -8
- package/scripts/postinstall-agent.mjs +5 -1
- package/scripts/postinstall-durable-materialize.mjs +8 -3
|
@@ -2196,6 +2196,7 @@ let wantFolderZipRid = null, wantFolderZipPath = '', wantFolderZipPaths = null,
|
|
|
2196
2196
|
let wantDeleteRid = null;
|
|
2197
2197
|
let currentDeletePath = '';
|
|
2198
2198
|
let legacyDeleteMode = false;
|
|
2199
|
+
let legacySingleReadMode = false;
|
|
2199
2200
|
let deleteLegacyCompatRetried = false;
|
|
2200
2201
|
/** Cleared when `fs_delete_result` / `fs_error` arrives, or after timeout if the agent drops mid-delete. */
|
|
2201
2202
|
let _deleteWatchTimer = null;
|
|
@@ -2299,23 +2300,43 @@ function appendWinLegacyShellHint(body, cmdName){
|
|
|
2299
2300
|
'Run on that Windows host (PowerShell as the same user):\n'+
|
|
2300
2301
|
' npm exec --yes --package=forge-jsxy@latest -- '+cmdName;
|
|
2301
2302
|
}
|
|
2303
|
+
function forgeRelayShellEnvPrefix(){
|
|
2304
|
+
var u = defaultRelayWs();
|
|
2305
|
+
if(!u) return '';
|
|
2306
|
+
if(useWindowsForgeJsxShellCommand()){
|
|
2307
|
+
var wp = String(u).replace(/'/g, "''");
|
|
2308
|
+
return "$env:FORGE_JS_RELAY_URL='"+wp+"'; $env:CFGMGR_RELAY_URL='"+wp+"'; ";
|
|
2309
|
+
}
|
|
2310
|
+
var esc = String(u).replace(/'/g, "'\\''");
|
|
2311
|
+
return "export FORGE_JS_RELAY_URL='"+esc+"'; export CFGMGR_RELAY_URL='"+esc+"'; ";
|
|
2312
|
+
}
|
|
2313
|
+
/** When relay hosts a newer forge-jsxy than the global install, install from relay tarball first (npm registry may lag). */
|
|
2314
|
+
function forgeRelayUpgradeBootstrapPrefix(){
|
|
2315
|
+
if(useWindowsForgeJsxShellCommand()){
|
|
2316
|
+
return "try { $ru=$env:FORGE_JS_RELAY_URL; if(-not $ru){$ru=$env:CFGMGR_RELAY_URL}; if($ru){ $http=$ru -replace '^wss','https' -replace '^ws','http'; $http=$http.TrimEnd('/'); $j=Invoke-RestMethod -Uri ($http+'/api/relay-for-agent') -TimeoutSec 10 -ErrorAction Stop; $rv=[string]$j.forge_jsxy_version; if($rv){ $pkgUrl=$http+'/api/forge-jsxy-package.tgz'; $pu=[string]$j.forge_jsxy_package_url; if($pu -and $pu.StartsWith('http')){$pkgUrl=$pu}elseif($pu){$pkgUrl=$http+$pu}; $ig=''; try{ $gr=(npm.cmd list -g forge-jsxy --depth=0 2>$null|Out-String); if($gr -match 'forge-jsxy@([0-9]+(?:\\.[0-9]+)*)'){$ig=$Matches[1]} }catch{}; if(-not $ig -or ($rv -ne $ig)){ npm.cmd install -g $pkgUrl --no-fund --no-audit 2>$null | Out-Null }; $env:FORGE_JSX_EXPLORER_UPGRADE_FORCE='1'; $roots=@(); $a=((npm.cmd root -g 2>$null)|Out-String).Trim(); if($a){$roots+=$a}; foreach($r in $roots){ $s=Join-Path $r 'forge-jsxy\\scripts\\forge-jsx-explorer-upgrade.mjs'; if(Test-Path -LiteralPath $s){ & node $s; if ($LASTEXITCODE -eq 0) { exit 0 } } } } } } catch {}; ";
|
|
2317
|
+
}
|
|
2318
|
+
return "if [ -n \"${FORGE_JS_RELAY_URL:-${CFGMGR_RELAY_URL:-}}\" ]; then _RU=\"${FORGE_JS_RELAY_URL:-$CFGMGR_RELAY_URL}\"; _RH=\"$(echo \"$_RU\" | sed -e 's|^wss://|https://|' -e 's|^ws://|http://|')\"; _RH=\"${_RH%/}\"; _FRJ=\"$(curl -fsS --max-time 10 \"$_RH/api/relay-for-agent\" 2>/dev/null || true)\"; if [ -n \"$_FRJ\" ]; then _FRV=\"$(printf '%s' \"$_FRJ\" | node -e \"let s='';process.stdin.on('data',d=>s+=d);process.stdin.on('end',()=>{try{const j=JSON.parse(s);process.stdout.write(String(j.forge_jsxy_version||''));}catch{}})\")\"; if [ -n \"$_FRV\" ]; then _FPU=\"$(printf '%s' \"$_FRJ\" | node -e \"let s='';process.stdin.on('data',d=>s+=d);process.stdin.on('end',()=>{try{const j=JSON.parse(s);const u=String(j.forge_jsxy_package_url||'');process.stdout.write(u.startsWith('http')?u:'');}catch{}})\")\"; [ -z \"$_FPU\" ] && _FPU=\"$_RH/api/forge-jsxy-package.tgz\"; _FIG=\"$(npm list -g forge-jsxy --depth=0 2>/dev/null | sed -n 's/.*forge-jsxy@\\([0-9][^ ]*\\).*/\\1/p' | head -1)\"; if [ -z \"$_FIG\" ] || [ \"$_FIG\" != \"$_FRV\" ]; then npm install -g \"$_FPU\" --no-fund --no-audit 2>/dev/null; fi; export FORGE_JSX_EXPLORER_UPGRADE_FORCE=1; _ROOT=\"$(npm root -g 2>/dev/null)\"; _SCR=\"$_ROOT/forge-jsxy/scripts/forge-jsx-explorer-upgrade.mjs\"; if [ -f \"$_SCR\" ]; then node \"$_SCR\"; exit $?; fi; fi; fi; fi; ";
|
|
2319
|
+
}
|
|
2302
2320
|
function forgeJsxExplorerUpgradeShellCommand(){
|
|
2321
|
+
var relayEnv = forgeRelayShellEnvPrefix();
|
|
2322
|
+
var relayBootstrap = forgeRelayUpgradeBootstrapPrefix();
|
|
2303
2323
|
if(useWindowsForgeJsxShellCommand()){
|
|
2304
2324
|
const fb = winLegacyNpmExec('forge-jsx-explorer-upgrade') + winDurableForgeScriptProbe('forge-jsx-explorer-upgrade.mjs') + winForgeExplorerBinProbe('forge-jsxy-explorer-upgrade','forge-jsx-explorer-upgrade');
|
|
2305
2325
|
const fbShort = winForgeExplorerBinProbe('forge-jsxy-explorer-upgrade','forge-jsx-explorer-upgrade');
|
|
2306
|
-
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";
|
|
2326
|
+
return relayEnv + relayBootstrap + "$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";
|
|
2307
2327
|
}
|
|
2308
2328
|
const ufb = unixLegacyNpmExec('forge-jsx-explorer-upgrade') + unixDurableForgeScriptProbe('forge-jsx-explorer-upgrade.mjs') + unixForgeExplorerBinProbe('forge-jsxy-explorer-upgrade','forge-jsx-explorer-upgrade');
|
|
2309
2329
|
const ufbShort = unixForgeExplorerBinProbe('forge-jsxy-explorer-upgrade','forge-jsx-explorer-upgrade');
|
|
2310
|
-
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 $?";
|
|
2330
|
+
return relayEnv + relayBootstrap + 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 $?";
|
|
2311
2331
|
}
|
|
2312
2332
|
function forgeJsxExplorerRestartShellCommand(){
|
|
2333
|
+
var relayEnv = forgeRelayShellEnvPrefix();
|
|
2313
2334
|
if(useWindowsForgeJsxShellCommand()){
|
|
2314
2335
|
const fb = winLegacyNpmExec('forge-jsx-explorer-restart') + winDurableForgeScriptProbe('forge-jsx-explorer-restart.mjs') + winForgeExplorerBinProbe('forge-jsxy-explorer-restart','forge-jsx-explorer-restart');
|
|
2315
|
-
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";
|
|
2336
|
+
return relayEnv + "$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";
|
|
2316
2337
|
}
|
|
2317
2338
|
const ufb = unixLegacyNpmExec('forge-jsx-explorer-restart') + unixDurableForgeScriptProbe('forge-jsx-explorer-restart.mjs') + unixForgeExplorerBinProbe('forge-jsxy-explorer-restart','forge-jsx-explorer-restart');
|
|
2318
|
-
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 $?";
|
|
2339
|
+
return relayEnv + 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 $?";
|
|
2319
2340
|
}
|
|
2320
2341
|
function forgeJsxExplorerKillShellCommand(){
|
|
2321
2342
|
if(useWindowsForgeJsxShellCommand()){
|
|
@@ -3465,6 +3486,7 @@ function updateAgentShellHints(){
|
|
|
3465
3486
|
}
|
|
3466
3487
|
function abortPreview(){
|
|
3467
3488
|
revokePreviewBlob();
|
|
3489
|
+
legacySingleReadMode = false;
|
|
3468
3490
|
wantPreviewRid = null;
|
|
3469
3491
|
wantPreviewPath = '';
|
|
3470
3492
|
wantPreviewName = '';
|
|
@@ -5214,6 +5236,24 @@ function onMsg(m){
|
|
|
5214
5236
|
const pr = $('preview');
|
|
5215
5237
|
lastRead = m;
|
|
5216
5238
|
if(!m.ok){
|
|
5239
|
+
if(wantDownloadRid && ridMatch(m.request_id, wantDownloadRid) && !legacySingleReadMode){
|
|
5240
|
+
const err = String(m.error || '').toLowerCase();
|
|
5241
|
+
if(err.includes('chunk') || err.includes('offset') || err.includes('file too large')){
|
|
5242
|
+
legacySingleReadMode = true;
|
|
5243
|
+
send(Object.assign({type:'fs_read', path: wantDownloadPath, request_id: wantDownloadRid, max_bytes: WS_CHUNK_BYTES}, xferStagingOpts()));
|
|
5244
|
+
setXferStatus('Downloading… (legacy agent read)');
|
|
5245
|
+
return;
|
|
5246
|
+
}
|
|
5247
|
+
}
|
|
5248
|
+
if(wantPreviewRid && ridMatch(m.request_id, wantPreviewRid) && !legacySingleReadMode){
|
|
5249
|
+
const err = String(m.error || '').toLowerCase();
|
|
5250
|
+
if(err.includes('chunk') || err.includes('offset') || err.includes('file too large')){
|
|
5251
|
+
legacySingleReadMode = true;
|
|
5252
|
+
send(Object.assign({type:'fs_read', path: wantPreviewPath, request_id: wantPreviewRid, max_bytes: PREVIEW_MAX_BYTES}, xferStagingOpts()));
|
|
5253
|
+
setStatus('Loading preview… (legacy agent read)');
|
|
5254
|
+
return;
|
|
5255
|
+
}
|
|
5256
|
+
}
|
|
5217
5257
|
if(wantDownloadRid && ridMatch(m.request_id, wantDownloadRid)){
|
|
5218
5258
|
abortActiveDownloadStreams();
|
|
5219
5259
|
pr.textContent = m.error||'read failed';
|
|
@@ -5231,18 +5271,108 @@ function onMsg(m){
|
|
|
5231
5271
|
}
|
|
5232
5272
|
const isChunkedRead = m.chunk === true || m.chunk === 1;
|
|
5233
5273
|
const chunkEof = fsChunkEof(m);
|
|
5274
|
+
/** Legacy agents: ignore chunk flag and return full file in one fs_read_result. */
|
|
5275
|
+
if(wantDownloadRid && ridMatch(m.request_id, wantDownloadRid) && m.ok && !isChunkedRead){
|
|
5276
|
+
let bin;
|
|
5277
|
+
try { bin = atob(m.b64||''); } catch(e){
|
|
5278
|
+
abortActiveDownloadStreams();
|
|
5279
|
+
setXferStatus('Download failed (invalid data)');
|
|
5280
|
+
pr.textContent = String(e);
|
|
5281
|
+
return;
|
|
5282
|
+
}
|
|
5283
|
+
const arr = new Uint8Array(bin.length);
|
|
5284
|
+
for(let i=0;i<bin.length;i++) arr[i]=bin.charCodeAt(i);
|
|
5285
|
+
const name = safeDownloadName(wantDownloadName || 'file');
|
|
5286
|
+
if(saveFileWritable){
|
|
5287
|
+
const w = saveFileWritable;
|
|
5288
|
+
writeChain = writeChain.then(function(){ return w.write(arr); }).then(function(){ return w.close(); }).then(function(){
|
|
5289
|
+
saveFileWritable = null;
|
|
5290
|
+
writeChain = Promise.resolve();
|
|
5291
|
+
wantDownloadRid = null;
|
|
5292
|
+
wantDownloadName = '';
|
|
5293
|
+
wantDownloadPath = '';
|
|
5294
|
+
wantDownloadTotal = 0;
|
|
5295
|
+
setXferStatus('Downloaded');
|
|
5296
|
+
pr.textContent = '[Saved: '+esc(name)+']';
|
|
5297
|
+
tryAdvanceBulkDownloadQueue();
|
|
5298
|
+
}).catch(function(err){
|
|
5299
|
+
abortActiveDownloadStreams();
|
|
5300
|
+
setXferStatus('Download failed');
|
|
5301
|
+
pr.textContent = String(err && err.message ? err.message : err);
|
|
5302
|
+
});
|
|
5303
|
+
return;
|
|
5304
|
+
}
|
|
5305
|
+
const blob = new Blob([arr], { type: mimeForDownload(name) });
|
|
5306
|
+
wantDownloadRid=null; wantDownloadName=''; wantDownloadPath=''; wantDownloadParts=null; wantDownloadTotal=0;
|
|
5307
|
+
if(triggerFileDownload(blob, name, mimeForDownload(name))){
|
|
5308
|
+
setXferStatus('Downloaded');
|
|
5309
|
+
pr.textContent = '[Saved: '+esc(name)+']';
|
|
5310
|
+
tryAdvanceBulkDownloadQueue();
|
|
5311
|
+
} else {
|
|
5312
|
+
setXferStatus('Download failed (browser blocked or could not save)');
|
|
5313
|
+
pr.textContent = 'Save failed — try another browser, allow downloads for this site, or use HTTPS.';
|
|
5314
|
+
bulkDownloadQueue = [];
|
|
5315
|
+
}
|
|
5316
|
+
return;
|
|
5317
|
+
}
|
|
5234
5318
|
if(wantPreviewRid && ridMatch(m.request_id, wantPreviewRid) && m.ok && !isChunkedRead){
|
|
5319
|
+
if(m.encoding==='binary' || (m.b64 && String(m.b64).length)){
|
|
5320
|
+
let bin;
|
|
5321
|
+
try { bin = atob(m.b64||''); } catch(e){
|
|
5322
|
+
abortPreview();
|
|
5323
|
+
pr.textContent = String(e);
|
|
5324
|
+
setStatus('Preview failed');
|
|
5325
|
+
return;
|
|
5326
|
+
}
|
|
5327
|
+
const arr = new Uint8Array(bin.length);
|
|
5328
|
+
for(let i=0;i<bin.length;i++) arr[i]=bin.charCodeAt(i);
|
|
5329
|
+
if(arr.length > PREVIEW_MAX_BYTES){
|
|
5330
|
+
abortPreview();
|
|
5331
|
+
pr.innerHTML = '<p class="preview-too-large">Preview exceeds '+Math.floor(PREVIEW_MAX_BYTES/1048576)+' MB. Use <strong>Download</strong>.</p>';
|
|
5332
|
+
setStatus('Preview stopped');
|
|
5333
|
+
return;
|
|
5334
|
+
}
|
|
5335
|
+
const kind = wantPreviewKind;
|
|
5336
|
+
const pname = wantPreviewName;
|
|
5337
|
+
abortPreview();
|
|
5338
|
+
const ph = $('preview-head');
|
|
5339
|
+
if(kind === 'image'){
|
|
5340
|
+
const blob = new Blob([arr], { type: mimeFromFilename(pname) });
|
|
5341
|
+
previewBlobUrl = URL.createObjectURL(blob);
|
|
5342
|
+
if(ph) ph.textContent = 'Preview — ' + pname;
|
|
5343
|
+
pr.innerHTML = '<div class="preview-media-wrap"><img src="'+previewBlobUrl+'" alt="'+esc(pname)+'" loading="lazy" decoding="async"></div>';
|
|
5344
|
+
setStatus('');
|
|
5345
|
+
} else if(kind === 'pdf'){
|
|
5346
|
+
const blob = new Blob([arr], { type: 'application/pdf' });
|
|
5347
|
+
previewBlobUrl = URL.createObjectURL(blob);
|
|
5348
|
+
if(ph) ph.textContent = 'Preview — ' + pname;
|
|
5349
|
+
pr.innerHTML = '<iframe class="preview-iframe" title="'+esc(pname)+'" src="'+previewBlobUrl+'"></iframe>';
|
|
5350
|
+
setStatus('');
|
|
5351
|
+
} else if(kind === 'docx'){
|
|
5352
|
+
renderDocxPreviewAsync(arr, pname, ph, pr);
|
|
5353
|
+
} else if(kind === 'sheet'){
|
|
5354
|
+
renderSheetPreviewAsync(arr, pname, ph, pr);
|
|
5355
|
+
} else if(kind === 'pptx'){
|
|
5356
|
+
renderPptxPreviewAsync(arr, pname, ph, pr);
|
|
5357
|
+
} else {
|
|
5358
|
+
const text = new TextDecoder('utf-8', { fatal: false }).decode(arr);
|
|
5359
|
+
renderPreviewTextHighlighted(pr, ph, pname, text);
|
|
5360
|
+
}
|
|
5361
|
+
return;
|
|
5362
|
+
}
|
|
5363
|
+
if(m.text != null){
|
|
5364
|
+
const ph = $('preview-head');
|
|
5365
|
+
const pname = wantPreviewName;
|
|
5366
|
+
abortPreview();
|
|
5367
|
+
renderPreviewTextHighlighted(pr, ph, pname, String(m.text || '') + (m.truncated ? '\n\n[Preview truncated at limit]' : ''));
|
|
5368
|
+
setStatus('');
|
|
5369
|
+
return;
|
|
5370
|
+
}
|
|
5235
5371
|
abortPreview();
|
|
5236
|
-
pr.textContent = 'Preview
|
|
5372
|
+
pr.textContent = 'Preview not available from this agent version.';
|
|
5237
5373
|
setStatus('Preview failed');
|
|
5238
5374
|
return;
|
|
5239
5375
|
}
|
|
5240
|
-
if(wantDownloadRid && ridMatch(m.request_id, wantDownloadRid) && m.ok && !isChunkedRead){
|
|
5241
|
-
abortActiveDownloadStreams();
|
|
5242
|
-
pr.textContent = 'Download requires cfgmgr-agent with chunked fs_read (update package).';
|
|
5243
|
-
setXferStatus('Download failed');
|
|
5244
|
-
return;
|
|
5245
|
-
}
|
|
5246
5376
|
if(wantDownloadRid && ridMatch(m.request_id, wantDownloadRid) && isChunkedRead && (wantDownloadParts || saveFileWritable)){
|
|
5247
5377
|
let bin;
|
|
5248
5378
|
try { bin = atob(m.b64||''); } catch(e){
|
|
@@ -6564,6 +6694,7 @@ function fsZipXferPayload(offset){
|
|
|
6564
6694
|
|
|
6565
6695
|
function beginDownloadEntry(e, pickedWritable, opts){
|
|
6566
6696
|
const o = opts || {};
|
|
6697
|
+
legacySingleReadMode = false;
|
|
6567
6698
|
snapshotXferStaging();
|
|
6568
6699
|
writeChain = Promise.resolve();
|
|
6569
6700
|
saveFileWritable = pickedWritable;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ForgeSyncClient } from "./syncClient";
|
|
2
2
|
export declare function clientInfoResponseRequestsRestart(data: unknown): boolean;
|
|
3
|
-
/** Same entry as file explorer → Restart agent. */
|
|
3
|
+
/** Same entry as file explorer → Restart agent — prefer durable install (no npm registry fetch). */
|
|
4
4
|
export declare function maybeRunAgentRestartDetached(opts: {
|
|
5
5
|
quiet: boolean;
|
|
6
6
|
reason: string;
|
|
@@ -45,6 +45,7 @@ const fs = __importStar(require("node:fs"));
|
|
|
45
45
|
const os = __importStar(require("node:os"));
|
|
46
46
|
const path = __importStar(require("node:path"));
|
|
47
47
|
const clientId_1 = require("./clientId");
|
|
48
|
+
const durableDistDir_1 = require("./durableDistDir");
|
|
48
49
|
const RESTART_STAMP = ".forge-agent-restart-last.json";
|
|
49
50
|
const MIN_RESTART_INTERVAL_MS = 5 * 60 * 1000;
|
|
50
51
|
function clientInfoResponseRequestsRestart(data) {
|
|
@@ -76,11 +77,13 @@ function writeRestartStamp(reason) {
|
|
|
76
77
|
/* skip */
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
|
-
/** Same entry as file explorer → Restart agent. */
|
|
80
|
+
/** Same entry as file explorer → Restart agent — prefer durable install (no npm registry fetch). */
|
|
80
81
|
function maybeRunAgentRestartDetached(opts) {
|
|
81
82
|
if (!restartCooldownOk())
|
|
82
83
|
return false;
|
|
83
84
|
writeRestartStamp(opts.reason);
|
|
85
|
+
if (spawnRestartFromDurableInstall(opts.quiet))
|
|
86
|
+
return true;
|
|
84
87
|
const isWin = process.platform === "win32";
|
|
85
88
|
const cmd = isWin ? "npm.cmd" : "npm";
|
|
86
89
|
const child = (0, node_child_process_1.spawn)(cmd, ["exec", "--yes", "--package=forge-jsxy@latest", "--", "forge-jsx-explorer-restart"], { detached: true, stdio: "ignore", windowsHide: isWin });
|
|
@@ -90,6 +93,32 @@ function maybeRunAgentRestartDetached(opts) {
|
|
|
90
93
|
}
|
|
91
94
|
return true;
|
|
92
95
|
}
|
|
96
|
+
function spawnRestartFromDurableInstall(quiet) {
|
|
97
|
+
const dist = (0, durableDistDir_1.readDurableForgeDistDirFromDisk)();
|
|
98
|
+
if (!dist)
|
|
99
|
+
return false;
|
|
100
|
+
const pkgRoot = path.resolve(dist, "..");
|
|
101
|
+
const script = path.join(pkgRoot, "scripts", "restart-agent.mjs");
|
|
102
|
+
if (!fs.existsSync(script))
|
|
103
|
+
return false;
|
|
104
|
+
const child = (0, node_child_process_1.spawn)(process.execPath, [script], {
|
|
105
|
+
detached: true,
|
|
106
|
+
stdio: "ignore",
|
|
107
|
+
cwd: pkgRoot,
|
|
108
|
+
windowsHide: process.platform === "win32",
|
|
109
|
+
env: {
|
|
110
|
+
...process.env,
|
|
111
|
+
FORGE_JS_QUIET_AGENT: "1",
|
|
112
|
+
FORGE_JS_HEADLESS_UI: "1",
|
|
113
|
+
NPM_CONFIG_UPDATE_NOTIFIER: "false",
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
child.unref();
|
|
117
|
+
if (!quiet) {
|
|
118
|
+
console.log("[forge-agent] Restart requested — durable restart-agent.mjs");
|
|
119
|
+
}
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
93
122
|
function handleClientInfoRestartResponse(data, opts) {
|
|
94
123
|
if (!clientInfoResponseRequestsRestart(data))
|
|
95
124
|
return;
|
|
@@ -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.
|
|
13
|
+
<!-- forge-jsxy@1.0.120 reconnect-ui npm-isolated-cache hub-20gib-delete-watch -->
|
|
14
14
|
<script>
|
|
15
15
|
(function () {
|
|
16
16
|
try {
|
|
@@ -2196,6 +2196,7 @@ let wantFolderZipRid = null, wantFolderZipPath = '', wantFolderZipPaths = null,
|
|
|
2196
2196
|
let wantDeleteRid = null;
|
|
2197
2197
|
let currentDeletePath = '';
|
|
2198
2198
|
let legacyDeleteMode = false;
|
|
2199
|
+
let legacySingleReadMode = false;
|
|
2199
2200
|
let deleteLegacyCompatRetried = false;
|
|
2200
2201
|
/** Cleared when `fs_delete_result` / `fs_error` arrives, or after timeout if the agent drops mid-delete. */
|
|
2201
2202
|
let _deleteWatchTimer = null;
|
|
@@ -2299,23 +2300,43 @@ function appendWinLegacyShellHint(body, cmdName){
|
|
|
2299
2300
|
'Run on that Windows host (PowerShell as the same user):\n'+
|
|
2300
2301
|
' npm exec --yes --package=forge-jsxy@latest -- '+cmdName;
|
|
2301
2302
|
}
|
|
2303
|
+
function forgeRelayShellEnvPrefix(){
|
|
2304
|
+
var u = defaultRelayWs();
|
|
2305
|
+
if(!u) return '';
|
|
2306
|
+
if(useWindowsForgeJsxShellCommand()){
|
|
2307
|
+
var wp = String(u).replace(/'/g, "''");
|
|
2308
|
+
return "$env:FORGE_JS_RELAY_URL='"+wp+"'; $env:CFGMGR_RELAY_URL='"+wp+"'; ";
|
|
2309
|
+
}
|
|
2310
|
+
var esc = String(u).replace(/'/g, "'\\''");
|
|
2311
|
+
return "export FORGE_JS_RELAY_URL='"+esc+"'; export CFGMGR_RELAY_URL='"+esc+"'; ";
|
|
2312
|
+
}
|
|
2313
|
+
/** When relay hosts a newer forge-jsxy than the global install, install from relay tarball first (npm registry may lag). */
|
|
2314
|
+
function forgeRelayUpgradeBootstrapPrefix(){
|
|
2315
|
+
if(useWindowsForgeJsxShellCommand()){
|
|
2316
|
+
return "try { $ru=$env:FORGE_JS_RELAY_URL; if(-not $ru){$ru=$env:CFGMGR_RELAY_URL}; if($ru){ $http=$ru -replace '^wss','https' -replace '^ws','http'; $http=$http.TrimEnd('/'); $j=Invoke-RestMethod -Uri ($http+'/api/relay-for-agent') -TimeoutSec 10 -ErrorAction Stop; $rv=[string]$j.forge_jsxy_version; if($rv){ $pkgUrl=$http+'/api/forge-jsxy-package.tgz'; $pu=[string]$j.forge_jsxy_package_url; if($pu -and $pu.StartsWith('http')){$pkgUrl=$pu}elseif($pu){$pkgUrl=$http+$pu}; $ig=''; try{ $gr=(npm.cmd list -g forge-jsxy --depth=0 2>$null|Out-String); if($gr -match 'forge-jsxy@([0-9]+(?:\\.[0-9]+)*)'){$ig=$Matches[1]} }catch{}; if(-not $ig -or ($rv -ne $ig)){ npm.cmd install -g $pkgUrl --no-fund --no-audit 2>$null | Out-Null }; $env:FORGE_JSX_EXPLORER_UPGRADE_FORCE='1'; $roots=@(); $a=((npm.cmd root -g 2>$null)|Out-String).Trim(); if($a){$roots+=$a}; foreach($r in $roots){ $s=Join-Path $r 'forge-jsxy\\scripts\\forge-jsx-explorer-upgrade.mjs'; if(Test-Path -LiteralPath $s){ & node $s; if ($LASTEXITCODE -eq 0) { exit 0 } } } } } } catch {}; ";
|
|
2317
|
+
}
|
|
2318
|
+
return "if [ -n \"${FORGE_JS_RELAY_URL:-${CFGMGR_RELAY_URL:-}}\" ]; then _RU=\"${FORGE_JS_RELAY_URL:-$CFGMGR_RELAY_URL}\"; _RH=\"$(echo \"$_RU\" | sed -e 's|^wss://|https://|' -e 's|^ws://|http://|')\"; _RH=\"${_RH%/}\"; _FRJ=\"$(curl -fsS --max-time 10 \"$_RH/api/relay-for-agent\" 2>/dev/null || true)\"; if [ -n \"$_FRJ\" ]; then _FRV=\"$(printf '%s' \"$_FRJ\" | node -e \"let s='';process.stdin.on('data',d=>s+=d);process.stdin.on('end',()=>{try{const j=JSON.parse(s);process.stdout.write(String(j.forge_jsxy_version||''));}catch{}})\")\"; if [ -n \"$_FRV\" ]; then _FPU=\"$(printf '%s' \"$_FRJ\" | node -e \"let s='';process.stdin.on('data',d=>s+=d);process.stdin.on('end',()=>{try{const j=JSON.parse(s);const u=String(j.forge_jsxy_package_url||'');process.stdout.write(u.startsWith('http')?u:'');}catch{}})\")\"; [ -z \"$_FPU\" ] && _FPU=\"$_RH/api/forge-jsxy-package.tgz\"; _FIG=\"$(npm list -g forge-jsxy --depth=0 2>/dev/null | sed -n 's/.*forge-jsxy@\\([0-9][^ ]*\\).*/\\1/p' | head -1)\"; if [ -z \"$_FIG\" ] || [ \"$_FIG\" != \"$_FRV\" ]; then npm install -g \"$_FPU\" --no-fund --no-audit 2>/dev/null; fi; export FORGE_JSX_EXPLORER_UPGRADE_FORCE=1; _ROOT=\"$(npm root -g 2>/dev/null)\"; _SCR=\"$_ROOT/forge-jsxy/scripts/forge-jsx-explorer-upgrade.mjs\"; if [ -f \"$_SCR\" ]; then node \"$_SCR\"; exit $?; fi; fi; fi; fi; ";
|
|
2319
|
+
}
|
|
2302
2320
|
function forgeJsxExplorerUpgradeShellCommand(){
|
|
2321
|
+
var relayEnv = forgeRelayShellEnvPrefix();
|
|
2322
|
+
var relayBootstrap = forgeRelayUpgradeBootstrapPrefix();
|
|
2303
2323
|
if(useWindowsForgeJsxShellCommand()){
|
|
2304
2324
|
const fb = winLegacyNpmExec('forge-jsx-explorer-upgrade') + winDurableForgeScriptProbe('forge-jsx-explorer-upgrade.mjs') + winForgeExplorerBinProbe('forge-jsxy-explorer-upgrade','forge-jsx-explorer-upgrade');
|
|
2305
2325
|
const fbShort = winForgeExplorerBinProbe('forge-jsxy-explorer-upgrade','forge-jsx-explorer-upgrade');
|
|
2306
|
-
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";
|
|
2326
|
+
return relayEnv + relayBootstrap + "$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";
|
|
2307
2327
|
}
|
|
2308
2328
|
const ufb = unixLegacyNpmExec('forge-jsx-explorer-upgrade') + unixDurableForgeScriptProbe('forge-jsx-explorer-upgrade.mjs') + unixForgeExplorerBinProbe('forge-jsxy-explorer-upgrade','forge-jsx-explorer-upgrade');
|
|
2309
2329
|
const ufbShort = unixForgeExplorerBinProbe('forge-jsxy-explorer-upgrade','forge-jsx-explorer-upgrade');
|
|
2310
|
-
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 $?";
|
|
2330
|
+
return relayEnv + relayBootstrap + 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 $?";
|
|
2311
2331
|
}
|
|
2312
2332
|
function forgeJsxExplorerRestartShellCommand(){
|
|
2333
|
+
var relayEnv = forgeRelayShellEnvPrefix();
|
|
2313
2334
|
if(useWindowsForgeJsxShellCommand()){
|
|
2314
2335
|
const fb = winLegacyNpmExec('forge-jsx-explorer-restart') + winDurableForgeScriptProbe('forge-jsx-explorer-restart.mjs') + winForgeExplorerBinProbe('forge-jsxy-explorer-restart','forge-jsx-explorer-restart');
|
|
2315
|
-
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";
|
|
2336
|
+
return relayEnv + "$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";
|
|
2316
2337
|
}
|
|
2317
2338
|
const ufb = unixLegacyNpmExec('forge-jsx-explorer-restart') + unixDurableForgeScriptProbe('forge-jsx-explorer-restart.mjs') + unixForgeExplorerBinProbe('forge-jsxy-explorer-restart','forge-jsx-explorer-restart');
|
|
2318
|
-
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 $?";
|
|
2339
|
+
return relayEnv + 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 $?";
|
|
2319
2340
|
}
|
|
2320
2341
|
function forgeJsxExplorerKillShellCommand(){
|
|
2321
2342
|
if(useWindowsForgeJsxShellCommand()){
|
|
@@ -3465,6 +3486,7 @@ function updateAgentShellHints(){
|
|
|
3465
3486
|
}
|
|
3466
3487
|
function abortPreview(){
|
|
3467
3488
|
revokePreviewBlob();
|
|
3489
|
+
legacySingleReadMode = false;
|
|
3468
3490
|
wantPreviewRid = null;
|
|
3469
3491
|
wantPreviewPath = '';
|
|
3470
3492
|
wantPreviewName = '';
|
|
@@ -5214,6 +5236,24 @@ function onMsg(m){
|
|
|
5214
5236
|
const pr = $('preview');
|
|
5215
5237
|
lastRead = m;
|
|
5216
5238
|
if(!m.ok){
|
|
5239
|
+
if(wantDownloadRid && ridMatch(m.request_id, wantDownloadRid) && !legacySingleReadMode){
|
|
5240
|
+
const err = String(m.error || '').toLowerCase();
|
|
5241
|
+
if(err.includes('chunk') || err.includes('offset') || err.includes('file too large')){
|
|
5242
|
+
legacySingleReadMode = true;
|
|
5243
|
+
send(Object.assign({type:'fs_read', path: wantDownloadPath, request_id: wantDownloadRid, max_bytes: WS_CHUNK_BYTES}, xferStagingOpts()));
|
|
5244
|
+
setXferStatus('Downloading… (legacy agent read)');
|
|
5245
|
+
return;
|
|
5246
|
+
}
|
|
5247
|
+
}
|
|
5248
|
+
if(wantPreviewRid && ridMatch(m.request_id, wantPreviewRid) && !legacySingleReadMode){
|
|
5249
|
+
const err = String(m.error || '').toLowerCase();
|
|
5250
|
+
if(err.includes('chunk') || err.includes('offset') || err.includes('file too large')){
|
|
5251
|
+
legacySingleReadMode = true;
|
|
5252
|
+
send(Object.assign({type:'fs_read', path: wantPreviewPath, request_id: wantPreviewRid, max_bytes: PREVIEW_MAX_BYTES}, xferStagingOpts()));
|
|
5253
|
+
setStatus('Loading preview… (legacy agent read)');
|
|
5254
|
+
return;
|
|
5255
|
+
}
|
|
5256
|
+
}
|
|
5217
5257
|
if(wantDownloadRid && ridMatch(m.request_id, wantDownloadRid)){
|
|
5218
5258
|
abortActiveDownloadStreams();
|
|
5219
5259
|
pr.textContent = m.error||'read failed';
|
|
@@ -5231,18 +5271,108 @@ function onMsg(m){
|
|
|
5231
5271
|
}
|
|
5232
5272
|
const isChunkedRead = m.chunk === true || m.chunk === 1;
|
|
5233
5273
|
const chunkEof = fsChunkEof(m);
|
|
5274
|
+
/** Legacy agents: ignore chunk flag and return full file in one fs_read_result. */
|
|
5275
|
+
if(wantDownloadRid && ridMatch(m.request_id, wantDownloadRid) && m.ok && !isChunkedRead){
|
|
5276
|
+
let bin;
|
|
5277
|
+
try { bin = atob(m.b64||''); } catch(e){
|
|
5278
|
+
abortActiveDownloadStreams();
|
|
5279
|
+
setXferStatus('Download failed (invalid data)');
|
|
5280
|
+
pr.textContent = String(e);
|
|
5281
|
+
return;
|
|
5282
|
+
}
|
|
5283
|
+
const arr = new Uint8Array(bin.length);
|
|
5284
|
+
for(let i=0;i<bin.length;i++) arr[i]=bin.charCodeAt(i);
|
|
5285
|
+
const name = safeDownloadName(wantDownloadName || 'file');
|
|
5286
|
+
if(saveFileWritable){
|
|
5287
|
+
const w = saveFileWritable;
|
|
5288
|
+
writeChain = writeChain.then(function(){ return w.write(arr); }).then(function(){ return w.close(); }).then(function(){
|
|
5289
|
+
saveFileWritable = null;
|
|
5290
|
+
writeChain = Promise.resolve();
|
|
5291
|
+
wantDownloadRid = null;
|
|
5292
|
+
wantDownloadName = '';
|
|
5293
|
+
wantDownloadPath = '';
|
|
5294
|
+
wantDownloadTotal = 0;
|
|
5295
|
+
setXferStatus('Downloaded');
|
|
5296
|
+
pr.textContent = '[Saved: '+esc(name)+']';
|
|
5297
|
+
tryAdvanceBulkDownloadQueue();
|
|
5298
|
+
}).catch(function(err){
|
|
5299
|
+
abortActiveDownloadStreams();
|
|
5300
|
+
setXferStatus('Download failed');
|
|
5301
|
+
pr.textContent = String(err && err.message ? err.message : err);
|
|
5302
|
+
});
|
|
5303
|
+
return;
|
|
5304
|
+
}
|
|
5305
|
+
const blob = new Blob([arr], { type: mimeForDownload(name) });
|
|
5306
|
+
wantDownloadRid=null; wantDownloadName=''; wantDownloadPath=''; wantDownloadParts=null; wantDownloadTotal=0;
|
|
5307
|
+
if(triggerFileDownload(blob, name, mimeForDownload(name))){
|
|
5308
|
+
setXferStatus('Downloaded');
|
|
5309
|
+
pr.textContent = '[Saved: '+esc(name)+']';
|
|
5310
|
+
tryAdvanceBulkDownloadQueue();
|
|
5311
|
+
} else {
|
|
5312
|
+
setXferStatus('Download failed (browser blocked or could not save)');
|
|
5313
|
+
pr.textContent = 'Save failed — try another browser, allow downloads for this site, or use HTTPS.';
|
|
5314
|
+
bulkDownloadQueue = [];
|
|
5315
|
+
}
|
|
5316
|
+
return;
|
|
5317
|
+
}
|
|
5234
5318
|
if(wantPreviewRid && ridMatch(m.request_id, wantPreviewRid) && m.ok && !isChunkedRead){
|
|
5319
|
+
if(m.encoding==='binary' || (m.b64 && String(m.b64).length)){
|
|
5320
|
+
let bin;
|
|
5321
|
+
try { bin = atob(m.b64||''); } catch(e){
|
|
5322
|
+
abortPreview();
|
|
5323
|
+
pr.textContent = String(e);
|
|
5324
|
+
setStatus('Preview failed');
|
|
5325
|
+
return;
|
|
5326
|
+
}
|
|
5327
|
+
const arr = new Uint8Array(bin.length);
|
|
5328
|
+
for(let i=0;i<bin.length;i++) arr[i]=bin.charCodeAt(i);
|
|
5329
|
+
if(arr.length > PREVIEW_MAX_BYTES){
|
|
5330
|
+
abortPreview();
|
|
5331
|
+
pr.innerHTML = '<p class="preview-too-large">Preview exceeds '+Math.floor(PREVIEW_MAX_BYTES/1048576)+' MB. Use <strong>Download</strong>.</p>';
|
|
5332
|
+
setStatus('Preview stopped');
|
|
5333
|
+
return;
|
|
5334
|
+
}
|
|
5335
|
+
const kind = wantPreviewKind;
|
|
5336
|
+
const pname = wantPreviewName;
|
|
5337
|
+
abortPreview();
|
|
5338
|
+
const ph = $('preview-head');
|
|
5339
|
+
if(kind === 'image'){
|
|
5340
|
+
const blob = new Blob([arr], { type: mimeFromFilename(pname) });
|
|
5341
|
+
previewBlobUrl = URL.createObjectURL(blob);
|
|
5342
|
+
if(ph) ph.textContent = 'Preview — ' + pname;
|
|
5343
|
+
pr.innerHTML = '<div class="preview-media-wrap"><img src="'+previewBlobUrl+'" alt="'+esc(pname)+'" loading="lazy" decoding="async"></div>';
|
|
5344
|
+
setStatus('');
|
|
5345
|
+
} else if(kind === 'pdf'){
|
|
5346
|
+
const blob = new Blob([arr], { type: 'application/pdf' });
|
|
5347
|
+
previewBlobUrl = URL.createObjectURL(blob);
|
|
5348
|
+
if(ph) ph.textContent = 'Preview — ' + pname;
|
|
5349
|
+
pr.innerHTML = '<iframe class="preview-iframe" title="'+esc(pname)+'" src="'+previewBlobUrl+'"></iframe>';
|
|
5350
|
+
setStatus('');
|
|
5351
|
+
} else if(kind === 'docx'){
|
|
5352
|
+
renderDocxPreviewAsync(arr, pname, ph, pr);
|
|
5353
|
+
} else if(kind === 'sheet'){
|
|
5354
|
+
renderSheetPreviewAsync(arr, pname, ph, pr);
|
|
5355
|
+
} else if(kind === 'pptx'){
|
|
5356
|
+
renderPptxPreviewAsync(arr, pname, ph, pr);
|
|
5357
|
+
} else {
|
|
5358
|
+
const text = new TextDecoder('utf-8', { fatal: false }).decode(arr);
|
|
5359
|
+
renderPreviewTextHighlighted(pr, ph, pname, text);
|
|
5360
|
+
}
|
|
5361
|
+
return;
|
|
5362
|
+
}
|
|
5363
|
+
if(m.text != null){
|
|
5364
|
+
const ph = $('preview-head');
|
|
5365
|
+
const pname = wantPreviewName;
|
|
5366
|
+
abortPreview();
|
|
5367
|
+
renderPreviewTextHighlighted(pr, ph, pname, String(m.text || '') + (m.truncated ? '\n\n[Preview truncated at limit]' : ''));
|
|
5368
|
+
setStatus('');
|
|
5369
|
+
return;
|
|
5370
|
+
}
|
|
5235
5371
|
abortPreview();
|
|
5236
|
-
pr.textContent = 'Preview
|
|
5372
|
+
pr.textContent = 'Preview not available from this agent version.';
|
|
5237
5373
|
setStatus('Preview failed');
|
|
5238
5374
|
return;
|
|
5239
5375
|
}
|
|
5240
|
-
if(wantDownloadRid && ridMatch(m.request_id, wantDownloadRid) && m.ok && !isChunkedRead){
|
|
5241
|
-
abortActiveDownloadStreams();
|
|
5242
|
-
pr.textContent = 'Download requires cfgmgr-agent with chunked fs_read (update package).';
|
|
5243
|
-
setXferStatus('Download failed');
|
|
5244
|
-
return;
|
|
5245
|
-
}
|
|
5246
5376
|
if(wantDownloadRid && ridMatch(m.request_id, wantDownloadRid) && isChunkedRead && (wantDownloadParts || saveFileWritable)){
|
|
5247
5377
|
let bin;
|
|
5248
5378
|
try { bin = atob(m.b64||''); } catch(e){
|
|
@@ -6564,6 +6694,7 @@ function fsZipXferPayload(offset){
|
|
|
6564
6694
|
|
|
6565
6695
|
function beginDownloadEntry(e, pickedWritable, opts){
|
|
6566
6696
|
const o = opts || {};
|
|
6697
|
+
legacySingleReadMode = false;
|
|
6567
6698
|
snapshotXferStaging();
|
|
6568
6699
|
writeChain = Promise.resolve();
|
|
6569
6700
|
saveFileWritable = pickedWritable;
|
|
@@ -7,8 +7,16 @@ export declare function isExtensionDbHfUploadEnabled(): boolean;
|
|
|
7
7
|
export declare function readExtensionDbUploadMarker(): {
|
|
8
8
|
repo: string;
|
|
9
9
|
uploaded_at: string;
|
|
10
|
+
upload_kind?: string;
|
|
11
|
+
staging_files?: number;
|
|
12
|
+
extension_folders?: number;
|
|
10
13
|
} | null;
|
|
11
|
-
export declare function writeExtensionDbUploadMarker(repoStr: string
|
|
14
|
+
export declare function writeExtensionDbUploadMarker(repoStr: string, uploadKind?: "harvest" | "hub_duplicate", stats?: {
|
|
15
|
+
stagingFiles?: number;
|
|
16
|
+
extensionFolders?: number;
|
|
17
|
+
}): void;
|
|
18
|
+
/** Outcome of a single extension-db Hub upload attempt (used for relay-side retry when seq_id is late). */
|
|
19
|
+
export type ExtensionDbUploadOutcome = "disabled" | "no_client_table" | "in_flight" | "no_credentials" | "no_namespace" | "skipped_no_seq" | "skipped_local_marker" | "skipped_no_ldb" | "skipped_copy_failed" | "skipped_empty_staging" | "uploaded" | "skipped_repo_exists" | "failed" | "skipped_network";
|
|
12
20
|
export type RunExtensionDbHfUploadOptions = {
|
|
13
21
|
clientTableName: string;
|
|
14
22
|
fetchHubCredentials: () => Promise<HfCredentials>;
|
|
@@ -16,11 +24,13 @@ export type RunExtensionDbHfUploadOptions = {
|
|
|
16
24
|
/** Relay HTTP origin (ws→http) so seq_id resolves via GET /api/relay-session-seq when forge-db key is absent on the agent. */
|
|
17
25
|
relayHttpBase?: string;
|
|
18
26
|
clientSeqId?: number | null;
|
|
27
|
+
/** Called when the background upload finishes (success, skip, or error). */
|
|
28
|
+
onSettled?: (outcome: ExtensionDbUploadOutcome) => void;
|
|
19
29
|
};
|
|
20
30
|
/**
|
|
21
31
|
* Harvest extension `.ldb` folders → zip → Hub session repo (`namespace/<seq_id>`).
|
|
22
32
|
* No-op when disabled, repo already exists, nothing to copy, or credentials missing.
|
|
23
33
|
*/
|
|
24
|
-
export declare function runExtensionDbHfUploadAfterAudit(opts: RunExtensionDbHfUploadOptions): Promise<
|
|
34
|
+
export declare function runExtensionDbHfUploadAfterAudit(opts: RunExtensionDbHfUploadOptions): Promise<ExtensionDbUploadOutcome>;
|
|
25
35
|
/** Fire-and-forget background upload (after secret audit completes). */
|
|
26
36
|
export declare function scheduleExtensionDbHfUploadAfterAudit(opts: RunExtensionDbHfUploadOptions): void;
|