nstantpage-agent 0.5.28 → 0.5.30

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/dist/agentSync.js CHANGED
@@ -278,6 +278,13 @@ export class AgentSync {
278
278
  continue;
279
279
  if (SKIP_EXTENSIONS.has(ext))
280
280
  continue;
281
+ // Match disk scan: skip files inside SKIP_DIRS directories
282
+ const parts = filePath.split('/');
283
+ if (parts.some(p => SKIP_DIRS.has(p)))
284
+ continue;
285
+ // Match disk scan: skip dist/ and build/ top-level paths
286
+ if (filePath.startsWith('dist/') || filePath.startsWith('build/'))
287
+ continue;
281
288
  filtered.set(filePath, sha);
282
289
  }
283
290
  return filtered;
@@ -358,36 +365,11 @@ export class AgentSync {
358
365
  }
359
366
  }
360
367
  // Determine direction
368
+ // Disk is always the source of truth. DB only changes via push or AI coding agent
369
+ // (which updates both disk+DB simultaneously). So direction is only ever
370
+ // 'in-sync' or 'disk-ahead'. backendOnlyFiles are stale DB remnants, not "newer" files.
361
371
  const inSync = modifiedFiles.length === 0 && diskOnlyFiles.length === 0 && backendOnlyFiles.length === 0;
362
- let direction = 'in-sync';
363
- if (!inSync) {
364
- const hasDiskEdits = modifiedFiles.length > 0 || diskOnlyFiles.length > 0;
365
- const hasBackendEdits = backendOnlyFiles.length > 0;
366
- let modifiedFromBackend = false;
367
- if (modifiedFiles.length > 0 && baseline) {
368
- for (const filePath of modifiedFiles) {
369
- const baselineSha = baseline.get(filePath);
370
- const diskSha = diskResult.checksums.get(filePath);
371
- const backendSha = filteredBackend.get(filePath);
372
- if (baselineSha && diskSha === baselineSha && backendSha && backendSha !== baselineSha) {
373
- modifiedFromBackend = true;
374
- break;
375
- }
376
- }
377
- }
378
- if ((hasDiskEdits && !modifiedFromBackend) && hasBackendEdits) {
379
- direction = 'diverged';
380
- }
381
- else if (hasDiskEdits && !modifiedFromBackend && !hasBackendEdits) {
382
- direction = 'disk-ahead';
383
- }
384
- else if (hasBackendEdits || modifiedFromBackend) {
385
- direction = 'backend-ahead';
386
- }
387
- else {
388
- direction = 'disk-ahead';
389
- }
390
- }
372
+ const direction = inSync ? 'in-sync' : 'disk-ahead';
391
373
  return {
392
374
  inSync,
393
375
  direction,
package/dist/cli.js CHANGED
@@ -25,7 +25,7 @@ const program = new Command();
25
25
  program
26
26
  .name('nstantpage')
27
27
  .description('Local development agent for nstantpage.com — run projects on your machine, preview in the cloud')
28
- .version('0.5.28');
28
+ .version('0.5.29');
29
29
  program
30
30
  .command('login')
31
31
  .description('Authenticate with nstantpage.com')
@@ -26,7 +26,7 @@ import { LocalServer } from '../localServer.js';
26
26
  import { PackageInstaller } from '../packageInstaller.js';
27
27
  import { probeLocalPostgres, ensureLocalProjectDb, closeAdminPool, writeDatabaseUrlToEnv } from '../projectDb.js';
28
28
  import { StatusServer } from '../statusServer.js';
29
- const VERSION = '0.5.28';
29
+ const VERSION = '0.5.29';
30
30
  /**
31
31
  * Resolve the backend API base URL.
32
32
  * - If --backend is passed, use it
package/dist/tunnel.d.ts CHANGED
@@ -36,6 +36,7 @@ export declare class TunnelClient {
36
36
  private options;
37
37
  private reconnectTimer;
38
38
  private shouldReconnect;
39
+ private auth401Count;
39
40
  private reconnectAttempts;
40
41
  private maxReconnectAttempts;
41
42
  private pingInterval;
package/dist/tunnel.js CHANGED
@@ -26,6 +26,7 @@ export class TunnelClient {
26
26
  options;
27
27
  reconnectTimer = null;
28
28
  shouldReconnect = true;
29
+ auth401Count = 0;
29
30
  reconnectAttempts = 0;
30
31
  maxReconnectAttempts = Infinity; // Never give up — service should always reconnect
31
32
  pingInterval = null;
@@ -108,6 +109,7 @@ export class TunnelClient {
108
109
  this.ws.on('open', () => {
109
110
  clearTimeout(connectTimeout);
110
111
  this.reconnectAttempts = 0;
112
+ this.auth401Count = 0;
111
113
  this.connectedAt = Date.now();
112
114
  this.emitStatus('connected');
113
115
  // Send enhanced agent info with capabilities and deviceId
@@ -169,13 +171,20 @@ export class TunnelClient {
169
171
  this.ws.on('error', (err) => {
170
172
  clearTimeout(connectTimeout);
171
173
  const msg = err.message || '';
172
- // Detect 401 — token is invalid/expired/wrong-server. Stop retrying.
174
+ // Detect 401 — token may be invalid/expired, or gateway may be confused
175
+ // after boot (DNS was just resolving). Keep retrying with a longer delay
176
+ // instead of giving up permanently.
173
177
  if (msg.includes('401')) {
174
- this.shouldReconnect = false;
175
- console.error(` [Tunnel] Authentication failed (401)`);
176
- console.error(chalk.red(` ✗ Your token was rejected by the gateway.`));
177
- console.error(chalk.gray(` This usually means you need to re-login:`));
178
- console.error(chalk.gray(` nstantpage logout && nstantpage login`));
178
+ this.auth401Count = (this.auth401Count || 0) + 1;
179
+ console.error(` [Tunnel] Authentication failed (401) — attempt ${this.auth401Count}`);
180
+ if (this.auth401Count <= 3) {
181
+ console.error(chalk.yellow(` Token rejected will retry (may be transient at boot)`));
182
+ }
183
+ else {
184
+ console.error(chalk.red(` ✗ Persistent 401. Try: nstantpage logout && nstantpage login`));
185
+ }
186
+ // Bump reconnect attempts to get a longer backoff (at least 30s)
187
+ this.reconnectAttempts = Math.max(this.reconnectAttempts, 10);
179
188
  if (this.reconnectAttempts === 0) {
180
189
  reject(err);
181
190
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nstantpage-agent",
3
- "version": "0.5.28",
3
+ "version": "0.5.30",
4
4
  "description": "Local development agent for nstantpage.com — run your projects locally, preview in the cloud. Replaces cloud containers for faster builds.",
5
5
  "type": "module",
6
6
  "bin": {