nstantpage-agent 0.5.12 → 0.5.14

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.
@@ -24,8 +24,8 @@ import { getConfig, getProjectConfig, setProjectConfig, clearProjectConfig, getD
24
24
  import { TunnelClient } from '../tunnel.js';
25
25
  import { LocalServer } from '../localServer.js';
26
26
  import { PackageInstaller } from '../packageInstaller.js';
27
- import { probeLocalPostgres, ensureLocalProjectDb, closeAdminPool } from '../projectDb.js';
28
- const VERSION = '0.5.12';
27
+ import { probeLocalPostgres, ensureLocalProjectDb, closeAdminPool, writeDatabaseUrlToEnv } from '../projectDb.js';
28
+ const VERSION = '0.5.14';
29
29
  /**
30
30
  * Resolve the backend API base URL.
31
31
  * - If --backend is passed, use it
@@ -283,6 +283,7 @@ export async function startCommand(directory, options) {
283
283
  databaseUrl = await ensureLocalProjectDb(projectId);
284
284
  if (databaseUrl) {
285
285
  console.log(chalk.green(` ✓ Database ready: project_${projectId}`));
286
+ writeDatabaseUrlToEnv(projectDir, databaseUrl);
286
287
  }
287
288
  }
288
289
  }
@@ -615,6 +616,7 @@ async function startAdditionalProject(projectId, opts) {
615
616
  databaseUrl = await ensureLocalProjectDb(projectId);
616
617
  if (databaseUrl) {
617
618
  console.log(chalk.green(` ✓ Database ready: project_${projectId}`));
619
+ writeDatabaseUrlToEnv(projectDir, databaseUrl);
618
620
  }
619
621
  }
620
622
  }
@@ -14,6 +14,7 @@
14
14
  */
15
15
  import http from 'http';
16
16
  import fs from 'fs';
17
+ import path from 'path';
17
18
  import os from 'os';
18
19
  import { createRequire } from 'module';
19
20
  import { spawn } from 'child_process';
@@ -22,7 +23,7 @@ import { FileManager } from './fileManager.js';
22
23
  import { Checker } from './checker.js';
23
24
  import { ErrorStore, structuredErrorToString } from './errorStore.js';
24
25
  import { PackageInstaller } from './packageInstaller.js';
25
- import { probeLocalPostgres, ensureLocalProjectDb } from './projectDb.js';
26
+ import { probeLocalPostgres, ensureLocalProjectDb, writeDatabaseUrlToEnv } from './projectDb.js';
26
27
  // ─── Try to load node-pty for real PTY support ─────────────────
27
28
  let ptyModule = null;
28
29
  try {
@@ -131,6 +132,8 @@ export class LocalServer {
131
132
  if (!this.options.env)
132
133
  this.options.env = {};
133
134
  this.options.env['DATABASE_URL'] = dbUrl;
135
+ // Write to .env so manual `npm run dev` also works
136
+ writeDatabaseUrlToEnv(this.options.projectDir, dbUrl);
134
137
  // Also update the DevServer's env
135
138
  this.devServer = new DevServer({
136
139
  projectDir: this.options.projectDir,
@@ -742,8 +745,28 @@ export class LocalServer {
742
745
  // ─── /live/dev/restart ───────────────────────────────────────
743
746
  async handleDevRestart(_req, res) {
744
747
  try {
745
- await this.devServer.restart();
746
- this.json(res, { success: true, message: 'Dev server restarted' });
748
+ // Full recovery: stop dev server, ensure deps installed, ensure DB, restart
749
+ console.log(' [LocalServer] Full dev server restart with recovery...');
750
+ // 1. Stop dev server
751
+ await this.devServer.stop();
752
+ // 2. Check if project dir has files (could be wiped)
753
+ const pkgPath = path.join(this.options.projectDir, 'package.json');
754
+ if (!fs.existsSync(pkgPath)) {
755
+ console.log(' [LocalServer] ⚠ package.json missing — project files may have been deleted');
756
+ // Can't install deps without package.json —the .NET backend /restart-dev-server
757
+ // should have already synced files before calling us. If files still missing, error out.
758
+ res.statusCode = 500;
759
+ this.json(res, { success: false, error: 'Project files missing (no package.json). Sync files first.' });
760
+ return;
761
+ }
762
+ // 3. Ensure database is provisioned
763
+ await this.ensureDatabase();
764
+ // 4. Ensure dependencies are installed
765
+ await this.packageInstaller.ensureDependencies();
766
+ // 5. Restart dev server
767
+ await new Promise(r => setTimeout(r, 300));
768
+ await this.devServer.start();
769
+ this.json(res, { success: true, message: 'Dev server restarted with full recovery' });
747
770
  }
748
771
  catch (err) {
749
772
  res.statusCode = 500;
@@ -24,6 +24,14 @@ export declare function isLocalPgAvailable(): boolean;
24
24
  * Returns null if PostgreSQL is not available.
25
25
  */
26
26
  export declare function ensureLocalProjectDb(projectId: string): Promise<string | null>;
27
+ /**
28
+ * Write DATABASE_URL to the project's .env file so manual `npm run dev` works.
29
+ * - Creates .env if it doesn't exist
30
+ * - Updates DATABASE_URL if already present but different
31
+ * - Appends DATABASE_URL if not present
32
+ * Idempotent — safe to call multiple times.
33
+ */
34
+ export declare function writeDatabaseUrlToEnv(projectDir: string, databaseUrl: string): void;
27
35
  /**
28
36
  * Close the admin pool (for graceful shutdown).
29
37
  */
package/dist/projectDb.js CHANGED
@@ -10,6 +10,8 @@
10
10
  * // → "postgresql://username:@127.0.0.1:5432/project_131"
11
11
  */
12
12
  import os from 'os';
13
+ import fs from 'fs';
14
+ import path from 'path';
13
15
  // Connection config — detect environment
14
16
  const PG_HOST = process.env.PG_HOST || '127.0.0.1';
15
17
  const PG_PORT = process.env.PG_PORT || '5432';
@@ -120,6 +122,44 @@ export async function ensureLocalProjectDb(projectId) {
120
122
  return null;
121
123
  }
122
124
  }
125
+ /**
126
+ * Write DATABASE_URL to the project's .env file so manual `npm run dev` works.
127
+ * - Creates .env if it doesn't exist
128
+ * - Updates DATABASE_URL if already present but different
129
+ * - Appends DATABASE_URL if not present
130
+ * Idempotent — safe to call multiple times.
131
+ */
132
+ export function writeDatabaseUrlToEnv(projectDir, databaseUrl) {
133
+ const envPath = path.join(projectDir, '.env');
134
+ try {
135
+ let content = '';
136
+ if (fs.existsSync(envPath)) {
137
+ content = fs.readFileSync(envPath, 'utf-8');
138
+ }
139
+ const lines = content.split('\n');
140
+ const dbLineIdx = lines.findIndex(l => l.startsWith('DATABASE_URL='));
141
+ if (dbLineIdx >= 0) {
142
+ // Already has DATABASE_URL — update if different
143
+ const existing = lines[dbLineIdx].split('=').slice(1).join('=');
144
+ if (existing === databaseUrl)
145
+ return; // already correct
146
+ lines[dbLineIdx] = `DATABASE_URL=${databaseUrl}`;
147
+ }
148
+ else {
149
+ // Append DATABASE_URL
150
+ // Ensure there's a newline before appending if file doesn't end with one
151
+ if (content.length > 0 && !content.endsWith('\n')) {
152
+ lines.push('');
153
+ }
154
+ lines.push(`DATABASE_URL=${databaseUrl}`);
155
+ }
156
+ fs.writeFileSync(envPath, lines.join('\n'), 'utf-8');
157
+ console.log(` [ProjectDb] Wrote DATABASE_URL to ${envPath}`);
158
+ }
159
+ catch (err) {
160
+ console.warn(` [ProjectDb] Failed to write .env: ${err.message}`);
161
+ }
162
+ }
123
163
  /**
124
164
  * Close the admin pool (for graceful shutdown).
125
165
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nstantpage-agent",
3
- "version": "0.5.12",
3
+ "version": "0.5.14",
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": {