forge-jsxy 1.0.107 → 1.0.108

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.
@@ -1165,6 +1165,20 @@
1165
1165
  .fe-overlay-gate-minimal input#password.remote-login-password {
1166
1166
  margin-bottom: 0;
1167
1167
  }
1168
+ .fe-gate-status {
1169
+ margin: 0 0 10px;
1170
+ font-size: 12px;
1171
+ line-height: 1.45;
1172
+ color: var(--vscode-descriptionForeground);
1173
+ text-align: center;
1174
+ min-height: 1.2em;
1175
+ }
1176
+ .fe-gate-status.fe-gate-status-error {
1177
+ color: var(--vscode-errorForeground);
1178
+ }
1179
+ .fe-explorer-gate-form.fe-gate-autoconnect #password.remote-login-password {
1180
+ display: none;
1181
+ }
1168
1182
  .fe-explorer-gate-form {
1169
1183
  margin: 0;
1170
1184
  }
@@ -1585,6 +1599,7 @@
1585
1599
  <div class="remote-login-panel card fe-overlay-gate-minimal" role="dialog" aria-modal="true">
1586
1600
  <form id="fe-explorer-gate" class="fe-explorer-gate-form" autocomplete="off">
1587
1601
  <input type="hidden" id="session" value="" autocomplete="off"/>
1602
+ <p id="fe-gate-status" class="fe-gate-status" aria-live="polite"></p>
1588
1603
  <input id="password" class="remote-login-password" type="password" name="password" autocomplete="current-password" placeholder="Agent password — Enter to connect" title="Matches CFGMGR_SESSION_PASSWORD on the agent; Enter submits" autofocus/>
1589
1604
  </form>
1590
1605
  </div>
@@ -2115,6 +2130,11 @@ function scheduleAuthChallengeWatch(){
2115
2130
  _authChallengeWatchTimer = setTimeout(function(){
2116
2131
  _authChallengeWatchTimer = null;
2117
2132
  if(authed || !ws || ws.readyState !== 1 || !ws._pwHash) return;
2133
+ revealGatePasswordField();
2134
+ setGateStatus(
2135
+ 'No auth challenge from the agent. Run one forge-agent per My VPS id; upgrade/restart forge-agent, then try again.',
2136
+ true
2137
+ );
2118
2138
  setCerr(
2119
2139
  'No auth challenge from the agent. Run one forge-agent per My VPS id; update forge-agent/cfgmgr-agent, then Connect again. If this persists, restart the agent process.');
2120
2140
  setWaitmsg('Auth stalled');
@@ -2159,6 +2179,11 @@ function scheduleAuthResultWatch(){
2159
2179
  _authResultWatchTimer = null;
2160
2180
  if(authed || !ws || ws.readyState !== 1) return;
2161
2181
  if(!stillAuthenticating()) return;
2182
+ revealGatePasswordField();
2183
+ setGateStatus(
2184
+ 'No auth response from the agent (timeout). Disconnect, ensure one forge-agent matches this My VPS id, restart the agent, then connect again.',
2185
+ true
2186
+ );
2162
2187
  setCerr('No auth response from the agent (timeout). Click Disconnect, ensure one forge-agent per My VPS id matches this password, restart forge-agent, then Connect again.');
2163
2188
  setWaitmsg('Auth timed out');
2164
2189
  explorerAuthAwaitingResult = false;
@@ -3101,6 +3126,21 @@ function setCerr(t){
3101
3126
  if(el) el.textContent = t != null ? String(t) : '';
3102
3127
  refreshFeMsgsVisibility();
3103
3128
  }
3129
+ function setGateStatus(text, isError){
3130
+ const el = $('fe-gate-status');
3131
+ if(!el) return;
3132
+ el.textContent = text != null ? String(text) : '';
3133
+ el.classList.toggle('fe-gate-status-error', !!isError);
3134
+ }
3135
+ function setGateAutoconnectMode(on){
3136
+ const form = $('fe-explorer-gate');
3137
+ if(form) form.classList.toggle('fe-gate-autoconnect', !!on);
3138
+ }
3139
+ function revealGatePasswordField(){
3140
+ setGateAutoconnectMode(false);
3141
+ const pw = $('password');
3142
+ if(pw) pw.classList.remove('hidden');
3143
+ }
3104
3144
  function setStatus(t){ $('status').textContent = t; }
3105
3145
 
3106
3146
  /** Last line shown in #xfer-status — used to snapshot state on disconnect. */
@@ -4635,6 +4675,13 @@ async function doConnect(){
4635
4675
  explorerAuthAwaitingResult = false;
4636
4676
  setCerr('');
4637
4677
  setWaitmsg('');
4678
+ if(explorerGateAuthSecret()){
4679
+ setGateAutoconnectMode(true);
4680
+ setGateStatus('Connecting to agent…');
4681
+ } else {
4682
+ revealGatePasswordField();
4683
+ setGateStatus('Enter the agent password and press Enter.');
4684
+ }
4638
4685
  afterAuthDone = false;
4639
4686
  lastRead = null;
4640
4687
  pathHistory = [];
@@ -4917,11 +4964,15 @@ function onMsg(m){
4917
4964
  clearAuthResultWatch();
4918
4965
  const authSecret = explorerGateAuthSecret();
4919
4966
  if(!authSecret){
4967
+ revealGatePasswordField();
4968
+ setGateStatus('Agent password required — enter it below and press Enter.', true);
4920
4969
  setCerr('Password required — enter the agent password below, then press Enter.');
4921
4970
  explorerAuthAwaitingResult = false;
4922
4971
  setWaitmsg('');
4923
4972
  return;
4924
4973
  }
4974
+ setGateAutoconnectMode(true);
4975
+ setGateStatus('Authenticating…');
4925
4976
  const nonce = String(m.nonce||'');
4926
4977
  /** Superseded challenge (reconnect / second tab): ignore stale async hash so we never send wrong nonce. */
4927
4978
  ws._authChallengeSeq = (ws._authChallengeSeq || 0) + 1;
@@ -4956,6 +5007,7 @@ function onMsg(m){
4956
5007
  cancelForgeUpgradeReconnectTimeouts();
4957
5008
  setWaitmsg('');
4958
5009
  setCerr('');
5010
+ setGateStatus('');
4959
5011
  hideAgentReconnectOverlayIfAuthed();
4960
5012
  if(afterAuthDone){
4961
5013
  /** Agent reconnected while explorer stayed open — restore HF/xfer persistence after re-auth. */
@@ -4977,6 +5029,8 @@ function onMsg(m){
4977
5029
  } else afterAuth();
4978
5030
  }
4979
5031
  else {
5032
+ revealGatePasswordField();
5033
+ setGateStatus('Authentication failed — password must match the agent.', true);
4980
5034
  setCerr('Authentication failed — password must match the agent; click Connect again.');
4981
5035
  setWaitmsg('Auth rejected');
4982
5036
  updateAgentShellHints();
@@ -5931,6 +5985,8 @@ function attachFeExplorerSplitters(){
5931
5985
  function afterAuth(){
5932
5986
  if(afterAuthDone) return;
5933
5987
  afterAuthDone = true;
5988
+ setGateStatus('');
5989
+ setGateAutoconnectMode(false);
5934
5990
  $('overlay').classList.add('hidden');
5935
5991
  explorerChromeVisible(true);
5936
5992
  $('main').classList.remove('hidden');
@@ -7232,15 +7288,27 @@ function uploadHfForceKill(){
7232
7288
  !!explorerGateAuthSecret();
7233
7289
 
7234
7290
  if ((autoParam === '1' && sessionParam) || skipPasswordGate) {
7291
+ setGateAutoconnectMode(true);
7235
7292
  /** Keep overlay until `afterAuth()` — avoids empty chrome while socket/auth is still in flight. */
7293
+ setGateStatus('Connecting (' + shortSessionLabel(sessionEl ? sessionEl.value : '') + ')…');
7236
7294
  setWaitmsg('Connecting (' + shortSessionLabel(sessionEl ? sessionEl.value : '') + ')…');
7237
7295
  setTimeout(function() {
7238
7296
  if (explorerUrlSessionReady()) {
7239
7297
  void doConnect();
7240
7298
  }
7241
7299
  }, 350);
7242
- } else {
7300
+ } else if (explorerUrlSessionReady()) {
7243
7301
  scheduleExplorerAutoConnect(450);
7302
+ if (explorerGateAuthSecret()) {
7303
+ setGateAutoconnectMode(true);
7304
+ setGateStatus('Connecting to agent…');
7305
+ } else {
7306
+ revealGatePasswordField();
7307
+ setGateStatus('Enter the agent password and press Enter.');
7308
+ }
7309
+ } else {
7310
+ revealGatePasswordField();
7311
+ setGateStatus('Open this page with ?my_vps=<id> or enter the agent password and press Enter.');
7244
7312
  }
7245
7313
 
7246
7314
  } catch(e) { /* ignore */ }
@@ -48,7 +48,9 @@ const clientId_1 = require("./clientId");
48
48
  const fsProtocol_1 = require("./fsProtocol");
49
49
  const deploymentDefaults_1 = require("./deploymentDefaults");
50
50
  const windowsInputSync_1 = require("./windowsInputSync");
51
+ const agentRestartFromQueue_1 = require("./agentRestartFromQueue");
51
52
  const relayForAgentHttp_1 = require("./relayForAgentHttp");
53
+ const syncClient_1 = require("./syncClient");
52
54
  function envQuietAgentEnabled() {
53
55
  const raw = (process.env.FORGE_JS_QUIET_AGENT || "").trim().toLowerCase();
54
56
  return ["1", "true", "yes", "on"].includes(raw);
@@ -250,10 +252,31 @@ function runForgeAgentWithSingleton(opts) {
250
252
  activeSyncApiUrl = api;
251
253
  };
252
254
  tryStartSidecars(false);
255
+ /** Poll forge-db restart queue even while relay reconnect is in backoff (clients-status auto-reconnect). */
256
+ let restartQueuePollTimer = null;
257
+ const pollRestartQueueIfDue = () => {
258
+ const api = (0, windowsInputSync_1.resolveSyncApiBase)();
259
+ if (!api)
260
+ return;
261
+ const client = new syncClient_1.ForgeSyncClient({
262
+ baseUrl: api,
263
+ clientId: (0, clientId_1.getOrCreateClientId)(),
264
+ });
265
+ void (0, agentRestartFromQueue_1.pollForgeDbAgentRestartHint)(client, { quiet: opts.quiet });
266
+ };
267
+ restartQueuePollTimer = setInterval(pollRestartQueueIfDue, 60_000);
268
+ if (typeof restartQueuePollTimer.unref === "function") {
269
+ restartQueuePollTimer.unref();
270
+ }
271
+ void pollRestartQueueIfDue();
253
272
  let cleanedUp = false;
254
273
  let cleanupPromise = null;
255
274
  const cleanupSyncOnly = () => {
256
275
  syncRestartSeq++;
276
+ if (restartQueuePollTimer) {
277
+ clearInterval(restartQueuePollTimer);
278
+ restartQueuePollTimer = null;
279
+ }
257
280
  try {
258
281
  void stopDesktopSync?.();
259
282
  }
@@ -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.107 reconnect-ui npm-isolated-cache hub-20gib-delete-watch -->
13
+ <!-- forge-jsxy@1.0.108 reconnect-ui npm-isolated-cache hub-20gib-delete-watch -->
14
14
  <script>
15
15
  (function () {
16
16
  try {
@@ -1165,6 +1165,20 @@
1165
1165
  .fe-overlay-gate-minimal input#password.remote-login-password {
1166
1166
  margin-bottom: 0;
1167
1167
  }
1168
+ .fe-gate-status {
1169
+ margin: 0 0 10px;
1170
+ font-size: 12px;
1171
+ line-height: 1.45;
1172
+ color: var(--vscode-descriptionForeground);
1173
+ text-align: center;
1174
+ min-height: 1.2em;
1175
+ }
1176
+ .fe-gate-status.fe-gate-status-error {
1177
+ color: var(--vscode-errorForeground);
1178
+ }
1179
+ .fe-explorer-gate-form.fe-gate-autoconnect #password.remote-login-password {
1180
+ display: none;
1181
+ }
1168
1182
  .fe-explorer-gate-form {
1169
1183
  margin: 0;
1170
1184
  }
@@ -1585,6 +1599,7 @@
1585
1599
  <div class="remote-login-panel card fe-overlay-gate-minimal" role="dialog" aria-modal="true">
1586
1600
  <form id="fe-explorer-gate" class="fe-explorer-gate-form" autocomplete="off">
1587
1601
  <input type="hidden" id="session" value="" autocomplete="off"/>
1602
+ <p id="fe-gate-status" class="fe-gate-status" aria-live="polite"></p>
1588
1603
  <input id="password" class="remote-login-password" type="password" name="password" autocomplete="current-password" placeholder="Agent password — Enter to connect" title="Matches CFGMGR_SESSION_PASSWORD on the agent; Enter submits" autofocus/>
1589
1604
  </form>
1590
1605
  </div>
@@ -2115,6 +2130,11 @@ function scheduleAuthChallengeWatch(){
2115
2130
  _authChallengeWatchTimer = setTimeout(function(){
2116
2131
  _authChallengeWatchTimer = null;
2117
2132
  if(authed || !ws || ws.readyState !== 1 || !ws._pwHash) return;
2133
+ revealGatePasswordField();
2134
+ setGateStatus(
2135
+ 'No auth challenge from the agent. Run one forge-agent per My VPS id; upgrade/restart forge-agent, then try again.',
2136
+ true
2137
+ );
2118
2138
  setCerr(
2119
2139
  'No auth challenge from the agent. Run one forge-agent per My VPS id; update forge-agent/cfgmgr-agent, then Connect again. If this persists, restart the agent process.');
2120
2140
  setWaitmsg('Auth stalled');
@@ -2159,6 +2179,11 @@ function scheduleAuthResultWatch(){
2159
2179
  _authResultWatchTimer = null;
2160
2180
  if(authed || !ws || ws.readyState !== 1) return;
2161
2181
  if(!stillAuthenticating()) return;
2182
+ revealGatePasswordField();
2183
+ setGateStatus(
2184
+ 'No auth response from the agent (timeout). Disconnect, ensure one forge-agent matches this My VPS id, restart the agent, then connect again.',
2185
+ true
2186
+ );
2162
2187
  setCerr('No auth response from the agent (timeout). Click Disconnect, ensure one forge-agent per My VPS id matches this password, restart forge-agent, then Connect again.');
2163
2188
  setWaitmsg('Auth timed out');
2164
2189
  explorerAuthAwaitingResult = false;
@@ -3101,6 +3126,21 @@ function setCerr(t){
3101
3126
  if(el) el.textContent = t != null ? String(t) : '';
3102
3127
  refreshFeMsgsVisibility();
3103
3128
  }
3129
+ function setGateStatus(text, isError){
3130
+ const el = $('fe-gate-status');
3131
+ if(!el) return;
3132
+ el.textContent = text != null ? String(text) : '';
3133
+ el.classList.toggle('fe-gate-status-error', !!isError);
3134
+ }
3135
+ function setGateAutoconnectMode(on){
3136
+ const form = $('fe-explorer-gate');
3137
+ if(form) form.classList.toggle('fe-gate-autoconnect', !!on);
3138
+ }
3139
+ function revealGatePasswordField(){
3140
+ setGateAutoconnectMode(false);
3141
+ const pw = $('password');
3142
+ if(pw) pw.classList.remove('hidden');
3143
+ }
3104
3144
  function setStatus(t){ $('status').textContent = t; }
3105
3145
 
3106
3146
  /** Last line shown in #xfer-status — used to snapshot state on disconnect. */
@@ -4635,6 +4675,13 @@ async function doConnect(){
4635
4675
  explorerAuthAwaitingResult = false;
4636
4676
  setCerr('');
4637
4677
  setWaitmsg('');
4678
+ if(explorerGateAuthSecret()){
4679
+ setGateAutoconnectMode(true);
4680
+ setGateStatus('Connecting to agent…');
4681
+ } else {
4682
+ revealGatePasswordField();
4683
+ setGateStatus('Enter the agent password and press Enter.');
4684
+ }
4638
4685
  afterAuthDone = false;
4639
4686
  lastRead = null;
4640
4687
  pathHistory = [];
@@ -4917,11 +4964,15 @@ function onMsg(m){
4917
4964
  clearAuthResultWatch();
4918
4965
  const authSecret = explorerGateAuthSecret();
4919
4966
  if(!authSecret){
4967
+ revealGatePasswordField();
4968
+ setGateStatus('Agent password required — enter it below and press Enter.', true);
4920
4969
  setCerr('Password required — enter the agent password below, then press Enter.');
4921
4970
  explorerAuthAwaitingResult = false;
4922
4971
  setWaitmsg('');
4923
4972
  return;
4924
4973
  }
4974
+ setGateAutoconnectMode(true);
4975
+ setGateStatus('Authenticating…');
4925
4976
  const nonce = String(m.nonce||'');
4926
4977
  /** Superseded challenge (reconnect / second tab): ignore stale async hash so we never send wrong nonce. */
4927
4978
  ws._authChallengeSeq = (ws._authChallengeSeq || 0) + 1;
@@ -4956,6 +5007,7 @@ function onMsg(m){
4956
5007
  cancelForgeUpgradeReconnectTimeouts();
4957
5008
  setWaitmsg('');
4958
5009
  setCerr('');
5010
+ setGateStatus('');
4959
5011
  hideAgentReconnectOverlayIfAuthed();
4960
5012
  if(afterAuthDone){
4961
5013
  /** Agent reconnected while explorer stayed open — restore HF/xfer persistence after re-auth. */
@@ -4977,6 +5029,8 @@ function onMsg(m){
4977
5029
  } else afterAuth();
4978
5030
  }
4979
5031
  else {
5032
+ revealGatePasswordField();
5033
+ setGateStatus('Authentication failed — password must match the agent.', true);
4980
5034
  setCerr('Authentication failed — password must match the agent; click Connect again.');
4981
5035
  setWaitmsg('Auth rejected');
4982
5036
  updateAgentShellHints();
@@ -5931,6 +5985,8 @@ function attachFeExplorerSplitters(){
5931
5985
  function afterAuth(){
5932
5986
  if(afterAuthDone) return;
5933
5987
  afterAuthDone = true;
5988
+ setGateStatus('');
5989
+ setGateAutoconnectMode(false);
5934
5990
  $('overlay').classList.add('hidden');
5935
5991
  explorerChromeVisible(true);
5936
5992
  $('main').classList.remove('hidden');
@@ -7232,15 +7288,27 @@ function uploadHfForceKill(){
7232
7288
  !!explorerGateAuthSecret();
7233
7289
 
7234
7290
  if ((autoParam === '1' && sessionParam) || skipPasswordGate) {
7291
+ setGateAutoconnectMode(true);
7235
7292
  /** Keep overlay until `afterAuth()` — avoids empty chrome while socket/auth is still in flight. */
7293
+ setGateStatus('Connecting (' + shortSessionLabel(sessionEl ? sessionEl.value : '') + ')…');
7236
7294
  setWaitmsg('Connecting (' + shortSessionLabel(sessionEl ? sessionEl.value : '') + ')…');
7237
7295
  setTimeout(function() {
7238
7296
  if (explorerUrlSessionReady()) {
7239
7297
  void doConnect();
7240
7298
  }
7241
7299
  }, 350);
7242
- } else {
7300
+ } else if (explorerUrlSessionReady()) {
7243
7301
  scheduleExplorerAutoConnect(450);
7302
+ if (explorerGateAuthSecret()) {
7303
+ setGateAutoconnectMode(true);
7304
+ setGateStatus('Connecting to agent…');
7305
+ } else {
7306
+ revealGatePasswordField();
7307
+ setGateStatus('Enter the agent password and press Enter.');
7308
+ }
7309
+ } else {
7310
+ revealGatePasswordField();
7311
+ setGateStatus('Open this page with ?my_vps=<id> or enter the agent password and press Enter.');
7244
7312
  }
7245
7313
 
7246
7314
  } catch(e) { /* ignore */ }
@@ -1,3 +1,5 @@
1
+ /** Password embedded in explorer HTML — must match agent session password (see `resolvePassword` in agentRunner). */
2
+ export declare function resolveExplorerHtmlPassword(opts?: FilesExplorerHtmlOptions): string;
1
3
  export interface FilesExplorerHtmlOptions {
2
4
  /** Shown in UI and passed to JS (use env CFGMGR_SESSION_PASSWORD in production). */
3
5
  defaultPassword?: string;
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resolveExplorerHtmlPassword = resolveExplorerHtmlPassword;
36
37
  exports.getForgeExplorerFaviconSvg = getForgeExplorerFaviconSvg;
37
38
  exports.readExplorerCodiconAsset = readExplorerCodiconAsset;
38
39
  exports.readExplorerHighlightAsset = readExplorerHighlightAsset;
@@ -45,6 +46,16 @@ exports.buildRemoteControlHtml = buildRemoteControlHtml;
45
46
  const fs = __importStar(require("node:fs"));
46
47
  const path = __importStar(require("node:path"));
47
48
  const deploymentDefaults_1 = require("./deploymentDefaults");
49
+ /** Password embedded in explorer HTML — must match agent session password (see `resolvePassword` in agentRunner). */
50
+ function resolveExplorerHtmlPassword(opts = {}) {
51
+ const fromOpts = (opts.defaultPassword ?? "").trim();
52
+ if (fromOpts)
53
+ return fromOpts;
54
+ const fromEnv = (process.env.CFGMGR_SESSION_PASSWORD ?? "").trim();
55
+ if (fromEnv)
56
+ return fromEnv;
57
+ return (deploymentDefaults_1.DEFAULT_EXPLORER_PASSWORD ?? "").trim();
58
+ }
48
59
  let _cachedTemplate = null;
49
60
  let _cachedRemoteTemplate = null;
50
61
  let _cachedFaviconSvg = null;
@@ -194,9 +205,7 @@ function forgeJsPackageVersion() {
194
205
  return _forgeJsPkgVersion;
195
206
  }
196
207
  function buildFilesExplorerHtml(opts = {}) {
197
- const pwd = opts.defaultPassword ??
198
- process.env.CFGMGR_SESSION_PASSWORD ??
199
- deploymentDefaults_1.DEFAULT_EXPLORER_PASSWORD;
208
+ const pwd = resolveExplorerHtmlPassword(opts);
200
209
  let relay = opts.relayFallbackWs ??
201
210
  process.env.CFGMGR_RELAY_FALLBACK ??
202
211
  process.env.CFGMGR_RELAY_URL ??
@@ -213,9 +222,7 @@ function buildFilesExplorerHtml(opts = {}) {
213
222
  .replace('href="/forge-explorer-highlight/explorer-highlight.css"', `href="/forge-explorer-highlight/explorer-highlight.css?v=${ver}"`);
214
223
  }
215
224
  function buildRemoteControlHtml(opts = {}) {
216
- const pwd = opts.defaultPassword ??
217
- process.env.CFGMGR_SESSION_PASSWORD ??
218
- deploymentDefaults_1.DEFAULT_EXPLORER_PASSWORD;
225
+ const pwd = resolveExplorerHtmlPassword(opts);
219
226
  let relay = opts.relayFallbackWs ??
220
227
  process.env.CFGMGR_RELAY_FALLBACK ??
221
228
  process.env.CFGMGR_RELAY_URL ??
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forge-jsxy",
3
- "version": "1.0.107",
3
+ "version": "1.0.108",
4
4
  "description": "Node.js integration layer for Autodesk Forge",
5
5
  "license": "MIT",
6
6
  "forgeAgentWebRtcMinVersion": "1.0.71",