shubhjn commited on
Commit
4b5c9d9
·
1 Parent(s): 15b7bb6

fix server boot

Browse files
.agent/clone-body.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"repoUrl":"https://github.com/octocat/Hello-World.git","projectName":"local-repro"}
.agent/cookies.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ # Netscape HTTP Cookie File
2
+ # https://curl.se/docs/http-cookies.html
3
+ # This file was generated by libcurl! Edit at your own risk.
4
+
.agent/local-server.log ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [BOOT] Starting Next.js preparation...
2
+ ----------------------------------------------------
3
+ [READY] CodeVerse 1.0.0-stable
4
+ [READY] Interface: 0.0.0.0:7860
5
+ ----------------------------------------------------
6
+ [BOOT] Next.js payload ready.
7
+ [BOOT] Environment validated. Synchronizing database...
8
+ [SYSTEM] Dev Seeding: 'Developer Guest' user ready.
9
+ [BOOT] Database synchronized.
10
+ [BOOT] Probing filesystem segment: d:\Code\codeverse\workspaces for existing sessions...
11
+ [Auto-Sleep] Cron initialized. Running every 30 minutes.
12
+ [BOOT] Global state stabilized. Application is fully operational.
13
+ ⨯ SyntaxError: Expected property name or '}' in JSON at position 1 (line 1 column 2)
14
+ at JSON.parse (<anonymous>)
15
+ ⨯ SyntaxError: Expected property name or '}' in JSON at position 1 (line 1 column 2)
16
+ at JSON.parse (<anonymous>)
17
+ (node:7268) [DEP0190] DeprecationWarning: Passing args to a child process with shell option true can lead to security vulnerabilities, as the arguments are not escaped, only concatenated.
18
+ (Use `node --trace-deprecation ...` to show where the warning was created)
.agent/memory/session.json CHANGED
@@ -1,7 +1,7 @@
1
  {
2
  "version": "1.0.0",
3
- "session_id": "8a5947b6",
4
- "started_at": "2026-04-09T18:00:22.621238+05:30",
5
  "workspace": "D:\\Code\\codeverse",
6
  "active_task_id": null,
7
  "active_agent": null,
 
1
  {
2
  "version": "1.0.0",
3
+ "session_id": "9c33f220",
4
+ "started_at": "2026-04-09T19:43:54.970676+05:30",
5
  "workspace": "D:\\Code\\codeverse",
6
  "active_task_id": null,
7
  "active_agent": null,
.agent/start-body.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"action":"start","id":"74b4d115-7324-4cb5-bda8-6ad9027d86a4","withAndroidEmulator":false}
.gitignore CHANGED
@@ -23,7 +23,8 @@
23
  # misc
24
  .DS_Store
25
  *.pem
26
-
 
27
  # debug
28
  npm-debug.log*
29
  yarn-debug.log*
 
23
  # misc
24
  .DS_Store
25
  *.pem
26
+ *.npm-cache
27
+ *.codeverse-runtime
28
  # debug
29
  npm-debug.log*
30
  yarn-debug.log*
dist/lib/docker/manager.js CHANGED
@@ -22,6 +22,7 @@ const events_1 = require("events");
22
  const idx_engine_1 = require("../idx/idx-engine");
23
  const storage_1 = require("../hf/storage");
24
  const isolation_1 = require("../fs/isolation");
 
25
  /**
26
  * Registry for native workspace processes (IDE instances running outside Docker)
27
  * Map<workspaceId, { pid: number; port: number; process: WorkspaceProcess }>
@@ -40,7 +41,7 @@ exports.pendingProvisioning = new Map();
40
  const SHORT_WORKSPACE_ID_LENGTH = 8;
41
  const RUNTIME_ROOT_DIR_NAME = '.codeverse-runtime';
42
  function getWorkspaceRootPath() {
43
- return process.env.WORKSPACE_ROOT || path_1.default.join(/*turbopackIgnore: true*/ '/home/node/w');
44
  }
45
  function getRuntimeRootPath() {
46
  return path_1.default.join(/*turbopackIgnore: true*/ getWorkspaceRootPath(), RUNTIME_ROOT_DIR_NAME);
@@ -73,6 +74,7 @@ async function resolveWorkspaceRuntimePaths(config) {
73
  runtimeWorkspacePath: path_1.default.join(/*turbopackIgnore: true*/ runtimeRootPath, shortWorkspaceId),
74
  userDataPath: path_1.default.join(/*turbopackIgnore: true*/ runtimeRootPath, `${shortWorkspaceId}-userdata`),
75
  metadataPath: path_1.default.join(/*turbopackIgnore: true*/ runtimeRootPath, `${shortWorkspaceId}.id`),
 
76
  };
77
  }
78
  function ensureRuntimeWorkspacePath(paths, log) {
@@ -81,6 +83,7 @@ function ensureRuntimeWorkspacePath(paths, log) {
81
  }
82
  fs_1.default.mkdirSync(paths.runtimeRootPath, { recursive: true });
83
  fs_1.default.mkdirSync(paths.userDataPath, { recursive: true });
 
84
  if (fs_1.default.existsSync(paths.runtimeWorkspacePath)) {
85
  try {
86
  const existingTargetPath = fs_1.default.realpathSync(paths.runtimeWorkspacePath);
@@ -144,6 +147,22 @@ function findAvailablePort() {
144
  }
145
  return port;
146
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  /**
148
  * Checks if Docker is available in the current environment.
149
  */
@@ -255,8 +274,9 @@ async function performProvisioning(config) {
255
  fs_1.default.writeFileSync(flagPath, new Date().toISOString());
256
  }
257
  // 5. Spawn code-server
258
- const shellCommand = process.platform === 'win32' ? 'npx' : 'code-server';
259
- const args = process.platform === 'win32' ? ['code-server'] : [];
 
260
  const baseArgs = [
261
  '--auth', 'none',
262
  '--bind-addr', `127.0.0.1:${port}`,
@@ -265,16 +285,26 @@ async function performProvisioning(config) {
265
  '--disable-update-check',
266
  workspacePath
267
  ];
268
- const spawnEnv = { ...process.env, HOME: workspacePath };
 
 
 
 
 
269
  delete spawnEnv.PORT;
270
  delete spawnEnv.SERVER_PORT;
271
  const child = (0, child_process_1.spawn)(shellCommand, [...args, ...baseArgs], {
272
  env: spawnEnv,
273
  cwd: workspacePath,
274
- shell: process.platform === 'win32'
 
 
 
 
 
 
 
275
  });
276
- log(`Spawning VS Code Orchestrator (PID: ${child.pid})...`);
277
- child.on('error', (err) => log(`[FATAL] IDE binary failure: ${err.message}`));
278
  child.stdout.on('data', (data) => {
279
  const out = data.toString().trim();
280
  if (out.includes('listening on'))
@@ -288,6 +318,10 @@ async function performProvisioning(config) {
288
  log(`[IDE:ERR] ${err}`);
289
  });
290
  child.on('close', (code, signal) => {
 
 
 
 
291
  log(`[IDE:EXIT] IDE process died with code ${code} (Signal: ${signal})`);
292
  exports.nativeProcesses.delete(config.id);
293
  });
@@ -296,6 +330,16 @@ async function performProvisioning(config) {
296
  // 7. Handshake Loop
297
  let attempts = 0;
298
  while (attempts < 60) {
 
 
 
 
 
 
 
 
 
 
299
  try {
300
  const res = await fetch(`http://127.0.0.1:${port}`);
301
  if (res.ok) {
 
22
  const idx_engine_1 = require("../idx/idx-engine");
23
  const storage_1 = require("../hf/storage");
24
  const isolation_1 = require("../fs/isolation");
25
+ const env_config_1 = require("../env-config");
26
  /**
27
  * Registry for native workspace processes (IDE instances running outside Docker)
28
  * Map<workspaceId, { pid: number; port: number; process: WorkspaceProcess }>
 
41
  const SHORT_WORKSPACE_ID_LENGTH = 8;
42
  const RUNTIME_ROOT_DIR_NAME = '.codeverse-runtime';
43
  function getWorkspaceRootPath() {
44
+ return env_config_1.ENV_CONFIG.WORKSPACE_ROOT;
45
  }
46
  function getRuntimeRootPath() {
47
  return path_1.default.join(/*turbopackIgnore: true*/ getWorkspaceRootPath(), RUNTIME_ROOT_DIR_NAME);
 
74
  runtimeWorkspacePath: path_1.default.join(/*turbopackIgnore: true*/ runtimeRootPath, shortWorkspaceId),
75
  userDataPath: path_1.default.join(/*turbopackIgnore: true*/ runtimeRootPath, `${shortWorkspaceId}-userdata`),
76
  metadataPath: path_1.default.join(/*turbopackIgnore: true*/ runtimeRootPath, `${shortWorkspaceId}.id`),
77
+ npmCachePath: path_1.default.join(/*turbopackIgnore: true*/ runtimeRootPath, 'npm-cache'),
78
  };
79
  }
80
  function ensureRuntimeWorkspacePath(paths, log) {
 
83
  }
84
  fs_1.default.mkdirSync(paths.runtimeRootPath, { recursive: true });
85
  fs_1.default.mkdirSync(paths.userDataPath, { recursive: true });
86
+ fs_1.default.mkdirSync(paths.npmCachePath, { recursive: true });
87
  if (fs_1.default.existsSync(paths.runtimeWorkspacePath)) {
88
  try {
89
  const existingTargetPath = fs_1.default.realpathSync(paths.runtimeWorkspacePath);
 
147
  }
148
  return port;
149
  }
150
+ function resolveCodeServerLaunch() {
151
+ const overrideBinary = process.env.CODE_SERVER_BIN;
152
+ if (overrideBinary) {
153
+ return { command: overrideBinary, args: [], label: overrideBinary };
154
+ }
155
+ if (process.platform === 'win32') {
156
+ try {
157
+ (0, child_process_1.execSync)('where code-server.cmd', { stdio: 'ignore' });
158
+ return { command: 'code-server.cmd', args: [], label: 'code-server' };
159
+ }
160
+ catch (_a) {
161
+ return { command: 'npx.cmd', args: ['--yes', 'code-server'], label: 'npx code-server' };
162
+ }
163
+ }
164
+ return { command: 'code-server', args: [], label: 'code-server' };
165
+ }
166
  /**
167
  * Checks if Docker is available in the current environment.
168
  */
 
274
  fs_1.default.writeFileSync(flagPath, new Date().toISOString());
275
  }
276
  // 5. Spawn code-server
277
+ const codeServerLaunch = resolveCodeServerLaunch();
278
+ const shellCommand = codeServerLaunch.command;
279
+ const args = codeServerLaunch.args;
280
  const baseArgs = [
281
  '--auth', 'none',
282
  '--bind-addr', `127.0.0.1:${port}`,
 
285
  '--disable-update-check',
286
  workspacePath
287
  ];
288
+ const spawnEnv = {
289
+ ...process.env,
290
+ HOME: workspacePath,
291
+ npm_config_cache: runtimePaths.npmCachePath,
292
+ npm_config_update_notifier: 'false',
293
+ };
294
  delete spawnEnv.PORT;
295
  delete spawnEnv.SERVER_PORT;
296
  const child = (0, child_process_1.spawn)(shellCommand, [...args, ...baseArgs], {
297
  env: spawnEnv,
298
  cwd: workspacePath,
299
+ shell: false
300
+ });
301
+ log(`Spawning VS Code Orchestrator via ${codeServerLaunch.label} (PID: ${child.pid})...`);
302
+ let childExited = false;
303
+ let childFailureReason = null;
304
+ child.on('error', (err) => {
305
+ childFailureReason = `IDE_BINARY_FAILURE: ${err.message}`;
306
+ log(`[FATAL] IDE binary failure: ${err.message}`);
307
  });
 
 
308
  child.stdout.on('data', (data) => {
309
  const out = data.toString().trim();
310
  if (out.includes('listening on'))
 
318
  log(`[IDE:ERR] ${err}`);
319
  });
320
  child.on('close', (code, signal) => {
321
+ childExited = true;
322
+ if (code !== 0 || signal) {
323
+ childFailureReason = childFailureReason !== null && childFailureReason !== void 0 ? childFailureReason : `IDE_PROCESS_EXIT_${code !== null && code !== void 0 ? code : 'unknown'}${signal ? `_${signal}` : ''}`;
324
+ }
325
  log(`[IDE:EXIT] IDE process died with code ${code} (Signal: ${signal})`);
326
  exports.nativeProcesses.delete(config.id);
327
  });
 
330
  // 7. Handshake Loop
331
  let attempts = 0;
332
  while (attempts < 60) {
333
+ if (childExited) {
334
+ const rawFailureMessage = childFailureReason !== null && childFailureReason !== void 0 ? childFailureReason : 'IDE_PROCESS_EXITED_BEFORE_HANDSHAKE';
335
+ const failureMessage = shellCommand === 'npx'
336
+ ? `${rawFailureMessage}. code-server could not be bootstrapped via npx. Install code-server globally or set CODE_SERVER_BIN.`
337
+ : rawFailureMessage;
338
+ log(`[FATAL] IDE bootstrap aborted before handshake: ${failureMessage}`);
339
+ const errResult = { success: false, error: failureMessage };
340
+ exports.provisioningBus.emit(`error:${config.id}`, errResult);
341
+ return errResult;
342
+ }
343
  try {
344
  const res = await fetch(`http://127.0.0.1:${port}`);
345
  if (res.ok) {
dist/lib/env-config.js CHANGED
@@ -1,7 +1,16 @@
1
  "use strict";
 
 
 
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
  exports.ENV_CONFIG = void 0;
4
  exports.validateEnvironment = validateEnvironment;
 
 
 
 
 
 
5
  /**
6
  * CodeVerse Environment Configuration & Requirements Manifest.
7
  * Centralizing all system variables for production-grade reliability.
@@ -10,7 +19,7 @@ exports.ENV_CONFIG = {
10
  // 1. Storage & Persistence
11
  HF_TOKEN: process.env.HF_TOKEN || process.env.hfToken || process.env.HF_SPACE || process.env.HuggingFaceToken,
12
  HF_DATASET_ID: process.env.HF_DATASET_ID || process.env.hfDataset || process.env.HF_DATASET,
13
- WORKSPACE_ROOT: process.env.WORKSPACE_ROOT || '/home/node/w',
14
  // 2. Build Acceleration
15
  CACHIX_CACHE_NAME: process.env.CACHIX_CACHE_NAME || 'code-nix',
16
  CACHIX_AUTH_TOKEN: process.env.CACHIX_AUTH_TOKEN,
@@ -20,8 +29,8 @@ exports.ENV_CONFIG = {
20
  APP_BASE_URL: process.env.NEXTAUTH_URL || 'http://localhost:7860',
21
  IS_SBC: !!process.env.SPACE_ID,
22
  // 4. Database & Auth
23
- AUTH_SECRET: process.env.AUTH_SECRET || process.env.authSecret,
24
- TURSO_URL: process.env.TURSO_URL || process.env.turso_url || process.env.database_url || process.env.TURSO_DATABASE_URL || process.env.DB_URL || process.env.turso_database_url,
25
  TURSO_AUTH_TOKEN: process.env.TURSO_AUTH_TOKEN || process.env.turso_auth_token || process.env.DB_TOKEN,
26
  TMPDIR: '/tmp',
27
  HF_HOME: '/tmp/.cache/huggingface',
@@ -31,14 +40,17 @@ exports.ENV_CONFIG = {
31
  */
32
  function validateEnvironment() {
33
  const missing = [];
34
- if (!exports.ENV_CONFIG.HF_TOKEN)
35
- missing.push('HF_TOKEN (Missing Persistence Link)');
36
- if (!exports.ENV_CONFIG.HF_DATASET_ID)
37
- missing.push('HF_DATASET_ID (Missing Data Segment)');
38
  if (!exports.ENV_CONFIG.AUTH_SECRET)
39
  missing.push('AUTH_SECRET (Security Risk)');
40
  if (!exports.ENV_CONFIG.TURSO_URL)
41
  missing.push('TURSO_URL (Database Missing)');
 
 
 
 
 
 
 
42
  // Strategic Dataset Validation
43
  if (exports.ENV_CONFIG.HF_DATASET_ID && !exports.ENV_CONFIG.HF_DATASET_ID.includes('/')) {
44
  return { valid: false, missing: ['HF_DATASET_ID_FORMAT_ERROR: Must be "username/dataset"'] };
 
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
  exports.ENV_CONFIG = void 0;
7
  exports.validateEnvironment = validateEnvironment;
8
+ const path_1 = __importDefault(require("path"));
9
+ function getDefaultWorkspaceRoot() {
10
+ return process.platform === "win32"
11
+ ? path_1.default.join(process.cwd(), "workspaces")
12
+ : "/home/node/w";
13
+ }
14
  /**
15
  * CodeVerse Environment Configuration & Requirements Manifest.
16
  * Centralizing all system variables for production-grade reliability.
 
19
  // 1. Storage & Persistence
20
  HF_TOKEN: process.env.HF_TOKEN || process.env.hfToken || process.env.HF_SPACE || process.env.HuggingFaceToken,
21
  HF_DATASET_ID: process.env.HF_DATASET_ID || process.env.hfDataset || process.env.HF_DATASET,
22
+ WORKSPACE_ROOT: process.env.WORKSPACE_ROOT || getDefaultWorkspaceRoot(),
23
  // 2. Build Acceleration
24
  CACHIX_CACHE_NAME: process.env.CACHIX_CACHE_NAME || 'code-nix',
25
  CACHIX_AUTH_TOKEN: process.env.CACHIX_AUTH_TOKEN,
 
29
  APP_BASE_URL: process.env.NEXTAUTH_URL || 'http://localhost:7860',
30
  IS_SBC: !!process.env.SPACE_ID,
31
  // 4. Database & Auth
32
+ AUTH_SECRET: process.env.AUTH_SECRET || process.env.NEXTAUTH_SECRET || process.env.authSecret,
33
+ TURSO_URL: process.env.TURSO_URL || process.env.turso_url || process.env.DATABASE_URL || process.env.database_url || process.env.TURSO_DATABASE_URL || process.env.DB_URL || process.env.turso_database_url,
34
  TURSO_AUTH_TOKEN: process.env.TURSO_AUTH_TOKEN || process.env.turso_auth_token || process.env.DB_TOKEN,
35
  TMPDIR: '/tmp',
36
  HF_HOME: '/tmp/.cache/huggingface',
 
40
  */
41
  function validateEnvironment() {
42
  const missing = [];
 
 
 
 
43
  if (!exports.ENV_CONFIG.AUTH_SECRET)
44
  missing.push('AUTH_SECRET (Security Risk)');
45
  if (!exports.ENV_CONFIG.TURSO_URL)
46
  missing.push('TURSO_URL (Database Missing)');
47
+ // HF persistence is required in deployed Spaces, not for local production testing.
48
+ if (exports.ENV_CONFIG.SPACE_ID) {
49
+ if (!exports.ENV_CONFIG.HF_TOKEN)
50
+ missing.push('HF_TOKEN (Missing Persistence Link)');
51
+ if (!exports.ENV_CONFIG.HF_DATASET_ID)
52
+ missing.push('HF_DATASET_ID (Missing Data Segment)');
53
+ }
54
  // Strategic Dataset Validation
55
  if (exports.ENV_CONFIG.HF_DATASET_ID && !exports.ENV_CONFIG.HF_DATASET_ID.includes('/')) {
56
  return { valid: false, missing: ['HF_DATASET_ID_FORMAT_ERROR: Must be "username/dataset"'] };
dist/lib/hf/storage.js CHANGED
@@ -7,10 +7,14 @@ exports.HFStorage = void 0;
7
  const child_process_1 = require("child_process");
8
  const path_1 = __importDefault(require("path"));
9
  const fs_1 = __importDefault(require("fs"));
 
10
  /**
11
  * Hugging Face Storage Utility for 2026 CodeVerse Persistence.
12
  */
13
  class HFStorage {
 
 
 
14
  /**
15
  * Internal helper for asynchronous execution with logging.
16
  */
@@ -40,13 +44,14 @@ class HFStorage {
40
  else
41
  reject(new Error(`Command failed with code ${code}: ${command}`));
42
  });
 
43
  });
44
  }
45
  /**
46
  * Synchronizes the environment FROM the Hugging Face Dataset (Pull).
47
  */
48
  static async syncFromDataset(onLog) {
49
- if (!this.HF_TOKEN || !this.HF_DATASET_ID) {
50
  onLog === null || onLog === void 0 ? void 0 : onLog(`[HF:STORAGE] Persistence layer inactive. Missing credentials.`);
51
  return;
52
  }
@@ -77,7 +82,7 @@ class HFStorage {
77
  * Synchronizes the environment TO the Hugging Face Dataset (Push).
78
  */
79
  static async syncToDataset(onLog) {
80
- if (!this.HF_TOKEN || !this.HF_DATASET_ID)
81
  return;
82
  try {
83
  onLog === null || onLog === void 0 ? void 0 : onLog(`[HF:STORAGE] Saving persistent profile to '${this.HF_DATASET_ID}'...`);
@@ -99,7 +104,7 @@ class HFStorage {
99
  }
100
  }
101
  static startAutoSave(intervalMs = 300000) {
102
- if (this.autoSaveStarted)
103
  return;
104
  this.autoSaveStarted = true;
105
  console.log(`[HF:STORAGE] Persistence heartbeat initialized (Interval: ${intervalMs}ms)`);
@@ -112,7 +117,7 @@ exports.HFStorage = HFStorage;
112
  HFStorage.HF_TOKEN = process.env.HF_TOKEN;
113
  HFStorage.HF_DATASET_ID = process.env.HF_DATASET_ID;
114
  HFStorage.PROFILE_PATH = path_1.default.join(process.env.HOME || '/home/node', '.nix-profile');
115
- HFStorage.WORKSPACE_ROOT = process.env.WORKSPACE_ROOT || '/home/node/w';
116
  /**
117
  * Starts the periodic persistence interval (Singleton Heartbeat).
118
  */
 
7
  const child_process_1 = require("child_process");
8
  const path_1 = __importDefault(require("path"));
9
  const fs_1 = __importDefault(require("fs"));
10
+ const env_config_1 = require("../env-config");
11
  /**
12
  * Hugging Face Storage Utility for 2026 CodeVerse Persistence.
13
  */
14
  class HFStorage {
15
+ static get isPersistenceRuntimeEnabled() {
16
+ return Boolean(env_config_1.ENV_CONFIG.SPACE_ID && this.HF_TOKEN && this.HF_DATASET_ID && process.platform !== 'win32');
17
+ }
18
  /**
19
  * Internal helper for asynchronous execution with logging.
20
  */
 
44
  else
45
  reject(new Error(`Command failed with code ${code}: ${command}`));
46
  });
47
+ child.on('error', (error) => reject(error));
48
  });
49
  }
50
  /**
51
  * Synchronizes the environment FROM the Hugging Face Dataset (Pull).
52
  */
53
  static async syncFromDataset(onLog) {
54
+ if (!this.isPersistenceRuntimeEnabled) {
55
  onLog === null || onLog === void 0 ? void 0 : onLog(`[HF:STORAGE] Persistence layer inactive. Missing credentials.`);
56
  return;
57
  }
 
82
  * Synchronizes the environment TO the Hugging Face Dataset (Push).
83
  */
84
  static async syncToDataset(onLog) {
85
+ if (!this.isPersistenceRuntimeEnabled)
86
  return;
87
  try {
88
  onLog === null || onLog === void 0 ? void 0 : onLog(`[HF:STORAGE] Saving persistent profile to '${this.HF_DATASET_ID}'...`);
 
104
  }
105
  }
106
  static startAutoSave(intervalMs = 300000) {
107
+ if (this.autoSaveStarted || !this.isPersistenceRuntimeEnabled)
108
  return;
109
  this.autoSaveStarted = true;
110
  console.log(`[HF:STORAGE] Persistence heartbeat initialized (Interval: ${intervalMs}ms)`);
 
117
  HFStorage.HF_TOKEN = process.env.HF_TOKEN;
118
  HFStorage.HF_DATASET_ID = process.env.HF_DATASET_ID;
119
  HFStorage.PROFILE_PATH = path_1.default.join(process.env.HOME || '/home/node', '.nix-profile');
120
+ HFStorage.WORKSPACE_ROOT = env_config_1.ENV_CONFIG.WORKSPACE_ROOT;
121
  /**
122
  * Starts the periodic persistence interval (Singleton Heartbeat).
123
  */
dist/lib/idx/idx-engine.js CHANGED
@@ -12,6 +12,15 @@ const child_process_1 = require("child_process");
12
  * Refactored for 2026 Asynchronous Execution to prevent Event Loop blocking.
13
  */
14
  class IdxEngine {
 
 
 
 
 
 
 
 
 
15
  /**
16
  * Returns a robust baseline configuration for workspaces without a dev.nix.
17
  */
@@ -19,7 +28,7 @@ class IdxEngine {
19
  return {
20
  packages: ['pkgs.nodejs', 'pkgs.go', 'pkgs.python3', 'pkgs.docker', 'pkgs.python3Packages.huggingface-hub'],
21
  onCreate: 'npm install',
22
- onStart: 'sleep 5 && npm run dev'
23
  };
24
  }
25
  /**
@@ -60,25 +69,14 @@ class IdxEngine {
60
  const log = (msg) => { if (onLog)
61
  onLog(`[IDX:NIX] ${msg}`); };
62
  log(`Syncing system packages: ${config.packages.join(', ')}...`);
 
 
 
 
 
63
  // CACHIX ACCELERATION: Robust check for binary existence to prevent ENOENT crash
64
  const cachixName = process.env.CACHIX_CACHE_NAME || 'code-nix';
65
- let hasCachix = false;
66
- try {
67
- await new Promise((resolve) => {
68
- const check = (0, child_process_1.spawn)('command', ['-v', 'cachix'], { shell: true });
69
- check.on('close', (code) => {
70
- hasCachix = (code === 0);
71
- resolve();
72
- });
73
- check.on('error', () => {
74
- hasCachix = false;
75
- resolve();
76
- });
77
- });
78
- }
79
- catch (_a) {
80
- hasCachix = false;
81
- }
82
  if (hasCachix) {
83
  const cachixToken = process.env.CACHIX_AUTH_TOKEN;
84
  if (cachixToken) {
@@ -99,7 +97,7 @@ class IdxEngine {
99
  child.on('close', (code) => code === 0 ? resolve() : reject(new Error(`Cachix failed with code ${code}`)));
100
  });
101
  }
102
- catch (_b) {
103
  log(`[WARN] Cachix setup bypassed. Falling back to default binary cache.`);
104
  }
105
  }
@@ -120,7 +118,7 @@ class IdxEngine {
120
  return;
121
  }
122
  }
123
- catch (_c) {
124
  log(`[WARN] Manifest corruption detected. Forcing re-sync.`);
125
  }
126
  }
@@ -155,6 +153,7 @@ class IdxEngine {
155
  });
156
  child.stdout.on('data', (data) => log(data.toString().trim()));
157
  child.stderr.on('data', (data) => log(`[INFO] ${data.toString().trim()}`));
 
158
  child.on('close', (code) => {
159
  if (code === 0) {
160
  fs_1.default.writeFileSync(manifestPath, JSON.stringify({ packages: config.packages, timestamp: new Date().toISOString() }));
@@ -183,12 +182,18 @@ class IdxEngine {
183
  const spawnEnv = { ...process.env, HOME: workspacePath };
184
  delete spawnEnv.PORT;
185
  delete spawnEnv.SERVER_PORT;
186
- const child = (0, child_process_1.spawn)('/bin/bash', ['-c', script], {
 
 
187
  cwd: workspacePath,
188
  env: spawnEnv
189
  });
190
  child.stdout.on('data', (data) => log(data.toString().trim()));
191
  child.stderr.on('data', (data) => log(`[WARN] ${data.toString().trim()}`));
 
 
 
 
192
  child.on('close', (code) => {
193
  if (code === 0) {
194
  log(`Hook ${hookName} completed successfully.`);
 
12
  * Refactored for 2026 Asynchronous Execution to prevent Event Loop blocking.
13
  */
14
  class IdxEngine {
15
+ static async hasCommand(command) {
16
+ const probeCommand = process.platform === 'win32' ? 'where' : 'command';
17
+ const probeArgs = process.platform === 'win32' ? [command] : ['-v', command];
18
+ return await new Promise((resolve) => {
19
+ const child = (0, child_process_1.spawn)(probeCommand, probeArgs, { shell: process.platform !== 'win32' });
20
+ child.on('close', (code) => resolve(code === 0));
21
+ child.on('error', () => resolve(false));
22
+ });
23
+ }
24
  /**
25
  * Returns a robust baseline configuration for workspaces without a dev.nix.
26
  */
 
28
  return {
29
  packages: ['pkgs.nodejs', 'pkgs.go', 'pkgs.python3', 'pkgs.docker', 'pkgs.python3Packages.huggingface-hub'],
30
  onCreate: 'npm install',
31
+ onStart: process.platform === 'win32' ? 'Start-Sleep -Seconds 5; npm run dev' : 'sleep 5 && npm run dev'
32
  };
33
  }
34
  /**
 
69
  const log = (msg) => { if (onLog)
70
  onLog(`[IDX:NIX] ${msg}`); };
71
  log(`Syncing system packages: ${config.packages.join(', ')}...`);
72
+ const hasNix = await this.hasCommand('nix');
73
+ if (!hasNix) {
74
+ log(`Nix is unavailable on this host. Skipping declarative package sync.`);
75
+ return;
76
+ }
77
  // CACHIX ACCELERATION: Robust check for binary existence to prevent ENOENT crash
78
  const cachixName = process.env.CACHIX_CACHE_NAME || 'code-nix';
79
+ const hasCachix = await this.hasCommand('cachix');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  if (hasCachix) {
81
  const cachixToken = process.env.CACHIX_AUTH_TOKEN;
82
  if (cachixToken) {
 
97
  child.on('close', (code) => code === 0 ? resolve() : reject(new Error(`Cachix failed with code ${code}`)));
98
  });
99
  }
100
+ catch (_a) {
101
  log(`[WARN] Cachix setup bypassed. Falling back to default binary cache.`);
102
  }
103
  }
 
118
  return;
119
  }
120
  }
121
+ catch (_b) {
122
  log(`[WARN] Manifest corruption detected. Forcing re-sync.`);
123
  }
124
  }
 
153
  });
154
  child.stdout.on('data', (data) => log(data.toString().trim()));
155
  child.stderr.on('data', (data) => log(`[INFO] ${data.toString().trim()}`));
156
+ child.on('error', (error) => reject(error));
157
  child.on('close', (code) => {
158
  if (code === 0) {
159
  fs_1.default.writeFileSync(manifestPath, JSON.stringify({ packages: config.packages, timestamp: new Date().toISOString() }));
 
182
  const spawnEnv = { ...process.env, HOME: workspacePath };
183
  delete spawnEnv.PORT;
184
  delete spawnEnv.SERVER_PORT;
185
+ const shellCommand = process.platform === 'win32' ? 'powershell.exe' : '/bin/bash';
186
+ const shellArgs = process.platform === 'win32' ? ['-NoProfile', '-Command', script] : ['-c', script];
187
+ const child = (0, child_process_1.spawn)(shellCommand, shellArgs, {
188
  cwd: workspacePath,
189
  env: spawnEnv
190
  });
191
  child.stdout.on('data', (data) => log(data.toString().trim()));
192
  child.stderr.on('data', (data) => log(`[WARN] ${data.toString().trim()}`));
193
+ child.on('error', (error) => {
194
+ log(`[ERROR] ${error.message}`);
195
+ reject(error);
196
+ });
197
  child.on('close', (code) => {
198
  if (code === 0) {
199
  log(`Hook ${hookName} completed successfully.`);
dist/server.js CHANGED
@@ -36,6 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
  };
38
  Object.defineProperty(exports, "__esModule", { value: true });
 
39
  /**
40
  * 🛰️ GLOBAL STABILIZATION (April 2026): Catch unhandled errors that cause HF Space restarts.
41
  */
@@ -294,7 +295,9 @@ server.listen(PORT, HOST, () => {
294
  console.log("[BOOT] Database synchronized.");
295
  // Reconnect and Warmup
296
  (0, manager_1.reconnectRunningWorkspaces)().catch(() => { });
297
- (0, manager_1.prewarmWorkspace)({ id: 'baseline-warmup', userId: 'system', projectName: 'CodeVerse-Internal' }).catch(() => { });
 
 
298
  // Crons and Persistence
299
  storage_1.HFStorage.startAutoSave(constants_1.INFRA_CONFIG.PERSISTENCE_INTERVAL_MS * 5);
300
  (0, auto_sleep_1.startAutoSleepCron)();
 
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
  };
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
+ require("dotenv/config");
40
  /**
41
  * 🛰️ GLOBAL STABILIZATION (April 2026): Catch unhandled errors that cause HF Space restarts.
42
  */
 
295
  console.log("[BOOT] Database synchronized.");
296
  // Reconnect and Warmup
297
  (0, manager_1.reconnectRunningWorkspaces)().catch(() => { });
298
+ if (process.env.ENABLE_BASELINE_PREWARM === 'true') {
299
+ (0, manager_1.prewarmWorkspace)({ id: 'baseline-warmup', userId: 'system', projectName: 'CodeVerse-Internal' }).catch(() => { });
300
+ }
301
  // Crons and Persistence
302
  storage_1.HFStorage.startAutoSave(constants_1.INFRA_CONFIG.PERSISTENCE_INTERVAL_MS * 5);
303
  (0, auto_sleep_1.startAutoSleepCron)();
lib/actions/emulator.ts CHANGED
@@ -1,6 +1,7 @@
1
  "use server";
2
 
3
  import Docker from 'dockerode';
 
4
 
5
  const docker = new Docker({
6
  socketPath: process.platform === 'win32' ? '//./pipe/docker_engine' : '/var/run/docker.sock'
@@ -38,7 +39,7 @@ export async function checkDeviceAvailability(platform: string, workspaceId: str
38
  const path = await import('path');
39
 
40
  const userId = "default-user";
41
- const workspaceRoot = process.env.WORKSPACE_ROOT || path.join(/*turbopackIgnore: true*/ '/home/node/w');
42
  const dataPath = path.join(/*turbopackIgnore: true*/ workspaceRoot, userId, workspaceId);
43
 
44
  try {
 
1
  "use server";
2
 
3
  import Docker from 'dockerode';
4
+ import { ENV_CONFIG } from '@/lib/env-config';
5
 
6
  const docker = new Docker({
7
  socketPath: process.platform === 'win32' ? '//./pipe/docker_engine' : '/var/run/docker.sock'
 
39
  const path = await import('path');
40
 
41
  const userId = "default-user";
42
+ const workspaceRoot = ENV_CONFIG.WORKSPACE_ROOT || path.join(/*turbopackIgnore: true*/ '/home/node/w');
43
  const dataPath = path.join(/*turbopackIgnore: true*/ workspaceRoot, userId, workspaceId);
44
 
45
  try {
lib/docker/manager.ts CHANGED
@@ -6,6 +6,7 @@ import { EventEmitter } from 'events';
6
  import { IdxEngine } from '../idx/idx-engine';
7
  import { HFStorage } from '../hf/storage';
8
  import { resolveSafeProjectPath } from '../fs/isolation';
 
9
 
10
  /**
11
  * Lighter process interface for reconnected sessions that don't have a full Node.js ChildProcess object.
@@ -42,13 +43,14 @@ interface WorkspaceRuntimePaths {
42
  runtimeWorkspacePath: string;
43
  userDataPath: string;
44
  metadataPath: string;
 
45
  }
46
 
47
  const SHORT_WORKSPACE_ID_LENGTH = 8;
48
  const RUNTIME_ROOT_DIR_NAME = '.codeverse-runtime';
49
 
50
  function getWorkspaceRootPath(): string {
51
- return process.env.WORKSPACE_ROOT || path.join(/*turbopackIgnore: true*/ '/home/node/w');
52
  }
53
 
54
  function getRuntimeRootPath(): string {
@@ -89,6 +91,7 @@ async function resolveWorkspaceRuntimePaths(config: Pick<WorkspaceConfig, 'id' |
89
  runtimeWorkspacePath: path.join(/*turbopackIgnore: true*/ runtimeRootPath, shortWorkspaceId),
90
  userDataPath: path.join(/*turbopackIgnore: true*/ runtimeRootPath, `${shortWorkspaceId}-userdata`),
91
  metadataPath: path.join(/*turbopackIgnore: true*/ runtimeRootPath, `${shortWorkspaceId}.id`),
 
92
  };
93
  }
94
 
@@ -99,6 +102,7 @@ function ensureRuntimeWorkspacePath(paths: WorkspaceRuntimePaths, log?: (msg: st
99
 
100
  fs.mkdirSync(paths.runtimeRootPath, { recursive: true });
101
  fs.mkdirSync(paths.userDataPath, { recursive: true });
 
102
 
103
  if (fs.existsSync(paths.runtimeWorkspacePath)) {
104
  try {
@@ -166,6 +170,24 @@ function findAvailablePort(): number {
166
  return port;
167
  }
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  /**
170
  * Checks if Docker is available in the current environment.
171
  */
@@ -312,8 +334,9 @@ async function performProvisioning(config: WorkspaceConfig): Promise<WorkspaceOp
312
  }
313
 
314
  // 5. Spawn code-server
315
- const shellCommand = process.platform === 'win32' ? 'npx' : 'code-server';
316
- const args = process.platform === 'win32' ? ['code-server'] : [];
 
317
 
318
  const baseArgs = [
319
  '--auth', 'none',
@@ -324,19 +347,29 @@ async function performProvisioning(config: WorkspaceConfig): Promise<WorkspaceOp
324
  workspacePath
325
  ];
326
 
327
- const spawnEnv: NodeJS.ProcessEnv = { ...process.env, HOME: workspacePath };
 
 
 
 
 
328
  delete spawnEnv.PORT;
329
  delete spawnEnv.SERVER_PORT;
330
 
331
  const child = spawn(shellCommand, [...args, ...baseArgs], {
332
  env: spawnEnv,
333
  cwd: workspacePath,
334
- shell: process.platform === 'win32'
335
  });
336
 
337
- log(`Spawning VS Code Orchestrator (PID: ${child.pid})...`);
 
 
338
 
339
- child.on('error', (err) => log(`[FATAL] IDE binary failure: ${err.message}`));
 
 
 
340
  child.stdout.on('data', (data) => {
341
  const out = data.toString().trim();
342
  if (out.includes('listening on')) log(`[IDX:UP] ${out}`);
@@ -349,6 +382,10 @@ async function performProvisioning(config: WorkspaceConfig): Promise<WorkspaceOp
349
  });
350
 
351
  child.on('close', (code, signal) => {
 
 
 
 
352
  log(`[IDE:EXIT] IDE process died with code ${code} (Signal: ${signal})`);
353
  nativeProcesses.delete(config.id);
354
  });
@@ -359,6 +396,17 @@ async function performProvisioning(config: WorkspaceConfig): Promise<WorkspaceOp
359
  // 7. Handshake Loop
360
  let attempts = 0;
361
  while (attempts < 60) {
 
 
 
 
 
 
 
 
 
 
 
362
  try {
363
  const res = await fetch(`http://127.0.0.1:${port}`);
364
  if (res.ok) {
 
6
  import { IdxEngine } from '../idx/idx-engine';
7
  import { HFStorage } from '../hf/storage';
8
  import { resolveSafeProjectPath } from '../fs/isolation';
9
+ import { ENV_CONFIG } from '../env-config';
10
 
11
  /**
12
  * Lighter process interface for reconnected sessions that don't have a full Node.js ChildProcess object.
 
43
  runtimeWorkspacePath: string;
44
  userDataPath: string;
45
  metadataPath: string;
46
+ npmCachePath: string;
47
  }
48
 
49
  const SHORT_WORKSPACE_ID_LENGTH = 8;
50
  const RUNTIME_ROOT_DIR_NAME = '.codeverse-runtime';
51
 
52
  function getWorkspaceRootPath(): string {
53
+ return ENV_CONFIG.WORKSPACE_ROOT;
54
  }
55
 
56
  function getRuntimeRootPath(): string {
 
91
  runtimeWorkspacePath: path.join(/*turbopackIgnore: true*/ runtimeRootPath, shortWorkspaceId),
92
  userDataPath: path.join(/*turbopackIgnore: true*/ runtimeRootPath, `${shortWorkspaceId}-userdata`),
93
  metadataPath: path.join(/*turbopackIgnore: true*/ runtimeRootPath, `${shortWorkspaceId}.id`),
94
+ npmCachePath: path.join(/*turbopackIgnore: true*/ runtimeRootPath, 'npm-cache'),
95
  };
96
  }
97
 
 
102
 
103
  fs.mkdirSync(paths.runtimeRootPath, { recursive: true });
104
  fs.mkdirSync(paths.userDataPath, { recursive: true });
105
+ fs.mkdirSync(paths.npmCachePath, { recursive: true });
106
 
107
  if (fs.existsSync(paths.runtimeWorkspacePath)) {
108
  try {
 
170
  return port;
171
  }
172
 
173
+ function resolveCodeServerLaunch(): { command: string; args: string[]; label: string } {
174
+ const overrideBinary = process.env.CODE_SERVER_BIN;
175
+ if (overrideBinary) {
176
+ return { command: overrideBinary, args: [], label: overrideBinary };
177
+ }
178
+
179
+ if (process.platform === 'win32') {
180
+ try {
181
+ execSync('where code-server.cmd', { stdio: 'ignore' });
182
+ return { command: 'code-server.cmd', args: [], label: 'code-server' };
183
+ } catch {
184
+ return { command: 'npx.cmd', args: ['--yes', 'code-server'], label: 'npx code-server' };
185
+ }
186
+ }
187
+
188
+ return { command: 'code-server', args: [], label: 'code-server' };
189
+ }
190
+
191
  /**
192
  * Checks if Docker is available in the current environment.
193
  */
 
334
  }
335
 
336
  // 5. Spawn code-server
337
+ const codeServerLaunch = resolveCodeServerLaunch();
338
+ const shellCommand = codeServerLaunch.command;
339
+ const args = codeServerLaunch.args;
340
 
341
  const baseArgs = [
342
  '--auth', 'none',
 
347
  workspacePath
348
  ];
349
 
350
+ const spawnEnv: NodeJS.ProcessEnv = {
351
+ ...process.env,
352
+ HOME: workspacePath,
353
+ npm_config_cache: runtimePaths.npmCachePath,
354
+ npm_config_update_notifier: 'false',
355
+ };
356
  delete spawnEnv.PORT;
357
  delete spawnEnv.SERVER_PORT;
358
 
359
  const child = spawn(shellCommand, [...args, ...baseArgs], {
360
  env: spawnEnv,
361
  cwd: workspacePath,
362
+ shell: false
363
  });
364
 
365
+ log(`Spawning VS Code Orchestrator via ${codeServerLaunch.label} (PID: ${child.pid})...`);
366
+ let childExited = false;
367
+ let childFailureReason: string | null = null;
368
 
369
+ child.on('error', (err) => {
370
+ childFailureReason = `IDE_BINARY_FAILURE: ${err.message}`;
371
+ log(`[FATAL] IDE binary failure: ${err.message}`);
372
+ });
373
  child.stdout.on('data', (data) => {
374
  const out = data.toString().trim();
375
  if (out.includes('listening on')) log(`[IDX:UP] ${out}`);
 
382
  });
383
 
384
  child.on('close', (code, signal) => {
385
+ childExited = true;
386
+ if (code !== 0 || signal) {
387
+ childFailureReason = childFailureReason ?? `IDE_PROCESS_EXIT_${code ?? 'unknown'}${signal ? `_${signal}` : ''}`;
388
+ }
389
  log(`[IDE:EXIT] IDE process died with code ${code} (Signal: ${signal})`);
390
  nativeProcesses.delete(config.id);
391
  });
 
396
  // 7. Handshake Loop
397
  let attempts = 0;
398
  while (attempts < 60) {
399
+ if (childExited) {
400
+ const rawFailureMessage = childFailureReason ?? 'IDE_PROCESS_EXITED_BEFORE_HANDSHAKE';
401
+ const failureMessage = shellCommand === 'npx'
402
+ ? `${rawFailureMessage}. code-server could not be bootstrapped via npx. Install code-server globally or set CODE_SERVER_BIN.`
403
+ : rawFailureMessage;
404
+ log(`[FATAL] IDE bootstrap aborted before handshake: ${failureMessage}`);
405
+ const errResult = { success: false, error: failureMessage };
406
+ provisioningBus.emit(`error:${config.id}`, errResult);
407
+ return errResult;
408
+ }
409
+
410
  try {
411
  const res = await fetch(`http://127.0.0.1:${port}`);
412
  if (res.ok) {
lib/env-config.ts CHANGED
@@ -1,3 +1,11 @@
 
 
 
 
 
 
 
 
1
  /**
2
  * CodeVerse Environment Configuration & Requirements Manifest.
3
  * Centralizing all system variables for production-grade reliability.
@@ -6,7 +14,7 @@ export const ENV_CONFIG = {
6
  // 1. Storage & Persistence
7
  HF_TOKEN: process.env.HF_TOKEN || process.env.hfToken || process.env.HF_SPACE || process.env.HuggingFaceToken,
8
  HF_DATASET_ID: process.env.HF_DATASET_ID || process.env.hfDataset || process.env.HF_DATASET,
9
- WORKSPACE_ROOT: process.env.WORKSPACE_ROOT || '/home/node/w',
10
 
11
  // 2. Build Acceleration
12
  CACHIX_CACHE_NAME: process.env.CACHIX_CACHE_NAME || 'code-nix',
@@ -19,8 +27,8 @@ export const ENV_CONFIG = {
19
  IS_SBC: !!process.env.SPACE_ID,
20
 
21
  // 4. Database & Auth
22
- AUTH_SECRET: process.env.AUTH_SECRET || process.env.authSecret,
23
- TURSO_URL: process.env.TURSO_URL || process.env.turso_url || process.env.database_url || process.env.TURSO_DATABASE_URL || process.env.DB_URL || process.env.turso_database_url,
24
  TURSO_AUTH_TOKEN: process.env.TURSO_AUTH_TOKEN || process.env.turso_auth_token || process.env.DB_TOKEN,
25
  TMPDIR: '/tmp',
26
  HF_HOME: '/tmp/.cache/huggingface',
@@ -31,11 +39,15 @@ export const ENV_CONFIG = {
31
  */
32
  export function validateEnvironment() {
33
  const missing: string[] = [];
34
- if (!ENV_CONFIG.HF_TOKEN) missing.push('HF_TOKEN (Missing Persistence Link)');
35
- if (!ENV_CONFIG.HF_DATASET_ID) missing.push('HF_DATASET_ID (Missing Data Segment)');
36
  if (!ENV_CONFIG.AUTH_SECRET) missing.push('AUTH_SECRET (Security Risk)');
37
  if (!ENV_CONFIG.TURSO_URL) missing.push('TURSO_URL (Database Missing)');
38
 
 
 
 
 
 
 
39
  // Strategic Dataset Validation
40
  if (ENV_CONFIG.HF_DATASET_ID && !ENV_CONFIG.HF_DATASET_ID.includes('/')) {
41
  return { valid: false, missing: ['HF_DATASET_ID_FORMAT_ERROR: Must be "username/dataset"'] };
 
1
+ import path from "path";
2
+
3
+ function getDefaultWorkspaceRoot(): string {
4
+ return process.platform === "win32"
5
+ ? path.join(process.cwd(), "workspaces")
6
+ : "/home/node/w";
7
+ }
8
+
9
  /**
10
  * CodeVerse Environment Configuration & Requirements Manifest.
11
  * Centralizing all system variables for production-grade reliability.
 
14
  // 1. Storage & Persistence
15
  HF_TOKEN: process.env.HF_TOKEN || process.env.hfToken || process.env.HF_SPACE || process.env.HuggingFaceToken,
16
  HF_DATASET_ID: process.env.HF_DATASET_ID || process.env.hfDataset || process.env.HF_DATASET,
17
+ WORKSPACE_ROOT: process.env.WORKSPACE_ROOT || getDefaultWorkspaceRoot(),
18
 
19
  // 2. Build Acceleration
20
  CACHIX_CACHE_NAME: process.env.CACHIX_CACHE_NAME || 'code-nix',
 
27
  IS_SBC: !!process.env.SPACE_ID,
28
 
29
  // 4. Database & Auth
30
+ AUTH_SECRET: process.env.AUTH_SECRET || process.env.NEXTAUTH_SECRET || process.env.authSecret,
31
+ TURSO_URL: process.env.TURSO_URL || process.env.turso_url || process.env.DATABASE_URL || process.env.database_url || process.env.TURSO_DATABASE_URL || process.env.DB_URL || process.env.turso_database_url,
32
  TURSO_AUTH_TOKEN: process.env.TURSO_AUTH_TOKEN || process.env.turso_auth_token || process.env.DB_TOKEN,
33
  TMPDIR: '/tmp',
34
  HF_HOME: '/tmp/.cache/huggingface',
 
39
  */
40
  export function validateEnvironment() {
41
  const missing: string[] = [];
 
 
42
  if (!ENV_CONFIG.AUTH_SECRET) missing.push('AUTH_SECRET (Security Risk)');
43
  if (!ENV_CONFIG.TURSO_URL) missing.push('TURSO_URL (Database Missing)');
44
 
45
+ // HF persistence is required in deployed Spaces, not for local production testing.
46
+ if (ENV_CONFIG.SPACE_ID) {
47
+ if (!ENV_CONFIG.HF_TOKEN) missing.push('HF_TOKEN (Missing Persistence Link)');
48
+ if (!ENV_CONFIG.HF_DATASET_ID) missing.push('HF_DATASET_ID (Missing Data Segment)');
49
+ }
50
+
51
  // Strategic Dataset Validation
52
  if (ENV_CONFIG.HF_DATASET_ID && !ENV_CONFIG.HF_DATASET_ID.includes('/')) {
53
  return { valid: false, missing: ['HF_DATASET_ID_FORMAT_ERROR: Must be "username/dataset"'] };
lib/hf/storage.ts CHANGED
@@ -1,6 +1,7 @@
1
  import { spawn } from 'child_process';
2
  import path from 'path';
3
  import fs from 'fs';
 
4
 
5
  /**
6
  * Hugging Face Storage Utility for 2026 CodeVerse Persistence.
@@ -9,7 +10,11 @@ export class HFStorage {
9
  private static readonly HF_TOKEN = process.env.HF_TOKEN;
10
  private static readonly HF_DATASET_ID = process.env.HF_DATASET_ID;
11
  private static readonly PROFILE_PATH = path.join(process.env.HOME || '/home/node', '.nix-profile');
12
- private static readonly WORKSPACE_ROOT = process.env.WORKSPACE_ROOT || '/home/node/w';
 
 
 
 
13
 
14
  /**
15
  * Internal helper for asynchronous execution with logging.
@@ -40,6 +45,7 @@ export class HFStorage {
40
  if (code === 0) resolve();
41
  else reject(new Error(`Command failed with code ${code}: ${command}`));
42
  });
 
43
  });
44
  }
45
 
@@ -47,7 +53,7 @@ export class HFStorage {
47
  * Synchronizes the environment FROM the Hugging Face Dataset (Pull).
48
  */
49
  static async syncFromDataset(onLog?: (msg: string) => void): Promise<void> {
50
- if (!this.HF_TOKEN || !this.HF_DATASET_ID) {
51
  onLog?.(`[HF:STORAGE] Persistence layer inactive. Missing credentials.`);
52
  return;
53
  }
@@ -80,7 +86,7 @@ export class HFStorage {
80
  * Synchronizes the environment TO the Hugging Face Dataset (Push).
81
  */
82
  static async syncToDataset(onLog?: (msg: string) => void): Promise<void> {
83
- if (!this.HF_TOKEN || !this.HF_DATASET_ID) return;
84
 
85
  try {
86
  onLog?.(`[HF:STORAGE] Saving persistent profile to '${this.HF_DATASET_ID}'...`);
@@ -107,7 +113,7 @@ export class HFStorage {
107
  */
108
  private static autoSaveStarted = false;
109
  static startAutoSave(intervalMs: number = 300000) {
110
- if (this.autoSaveStarted) return;
111
  this.autoSaveStarted = true;
112
 
113
  console.log(`[HF:STORAGE] Persistence heartbeat initialized (Interval: ${intervalMs}ms)`);
 
1
  import { spawn } from 'child_process';
2
  import path from 'path';
3
  import fs from 'fs';
4
+ import { ENV_CONFIG } from '../env-config';
5
 
6
  /**
7
  * Hugging Face Storage Utility for 2026 CodeVerse Persistence.
 
10
  private static readonly HF_TOKEN = process.env.HF_TOKEN;
11
  private static readonly HF_DATASET_ID = process.env.HF_DATASET_ID;
12
  private static readonly PROFILE_PATH = path.join(process.env.HOME || '/home/node', '.nix-profile');
13
+ private static readonly WORKSPACE_ROOT = ENV_CONFIG.WORKSPACE_ROOT;
14
+
15
+ private static get isPersistenceRuntimeEnabled(): boolean {
16
+ return Boolean(ENV_CONFIG.SPACE_ID && this.HF_TOKEN && this.HF_DATASET_ID && process.platform !== 'win32');
17
+ }
18
 
19
  /**
20
  * Internal helper for asynchronous execution with logging.
 
45
  if (code === 0) resolve();
46
  else reject(new Error(`Command failed with code ${code}: ${command}`));
47
  });
48
+ child.on('error', (error) => reject(error));
49
  });
50
  }
51
 
 
53
  * Synchronizes the environment FROM the Hugging Face Dataset (Pull).
54
  */
55
  static async syncFromDataset(onLog?: (msg: string) => void): Promise<void> {
56
+ if (!this.isPersistenceRuntimeEnabled) {
57
  onLog?.(`[HF:STORAGE] Persistence layer inactive. Missing credentials.`);
58
  return;
59
  }
 
86
  * Synchronizes the environment TO the Hugging Face Dataset (Push).
87
  */
88
  static async syncToDataset(onLog?: (msg: string) => void): Promise<void> {
89
+ if (!this.isPersistenceRuntimeEnabled) return;
90
 
91
  try {
92
  onLog?.(`[HF:STORAGE] Saving persistent profile to '${this.HF_DATASET_ID}'...`);
 
113
  */
114
  private static autoSaveStarted = false;
115
  static startAutoSave(intervalMs: number = 300000) {
116
+ if (this.autoSaveStarted || !this.isPersistenceRuntimeEnabled) return;
117
  this.autoSaveStarted = true;
118
 
119
  console.log(`[HF:STORAGE] Persistence heartbeat initialized (Interval: ${intervalMs}ms)`);
lib/idx/idx-engine.ts CHANGED
@@ -16,6 +16,17 @@ export interface IdxConfig {
16
  * Refactored for 2026 Asynchronous Execution to prevent Event Loop blocking.
17
  */
18
  export class IdxEngine {
 
 
 
 
 
 
 
 
 
 
 
19
  /**
20
  * Returns a robust baseline configuration for workspaces without a dev.nix.
21
  */
@@ -23,7 +34,7 @@ export class IdxEngine {
23
  return {
24
  packages: ['pkgs.nodejs', 'pkgs.go', 'pkgs.python3', 'pkgs.docker', 'pkgs.python3Packages.huggingface-hub'],
25
  onCreate: 'npm install',
26
- onStart: 'sleep 5 && npm run dev'
27
  };
28
  }
29
 
@@ -68,25 +79,15 @@ export class IdxEngine {
68
  const log = (msg: string) => { if (onLog) onLog(`[IDX:NIX] ${msg}`); };
69
  log(`Syncing system packages: ${config.packages.join(', ')}...`);
70
 
 
 
 
 
 
 
71
  // CACHIX ACCELERATION: Robust check for binary existence to prevent ENOENT crash
72
  const cachixName = process.env.CACHIX_CACHE_NAME || 'code-nix';
73
- let hasCachix = false;
74
-
75
- try {
76
- await new Promise<void>((resolve) => {
77
- const check = spawn('command', ['-v', 'cachix'], { shell: true });
78
- check.on('close', (code) => {
79
- hasCachix = (code === 0);
80
- resolve();
81
- });
82
- check.on('error', () => {
83
- hasCachix = false;
84
- resolve();
85
- });
86
- });
87
- } catch {
88
- hasCachix = false;
89
- }
90
 
91
  if (hasCachix) {
92
  const cachixToken = process.env.CACHIX_AUTH_TOKEN;
@@ -170,6 +171,7 @@ export class IdxEngine {
170
 
171
  child.stdout.on('data', (data) => log(data.toString().trim()));
172
  child.stderr.on('data', (data) => log(`[INFO] ${data.toString().trim()}`));
 
173
 
174
  child.on('close', (code) => {
175
  if (code === 0) {
@@ -200,13 +202,20 @@ export class IdxEngine {
200
  delete spawnEnv.PORT;
201
  delete spawnEnv.SERVER_PORT;
202
 
203
- const child = spawn('/bin/bash', ['-c', script], {
 
 
 
204
  cwd: workspacePath,
205
  env: spawnEnv
206
  });
207
 
208
  child.stdout.on('data', (data) => log(data.toString().trim()));
209
  child.stderr.on('data', (data) => log(`[WARN] ${data.toString().trim()}`));
 
 
 
 
210
 
211
  child.on('close', (code) => {
212
  if (code === 0) {
 
16
  * Refactored for 2026 Asynchronous Execution to prevent Event Loop blocking.
17
  */
18
  export class IdxEngine {
19
+ private static async hasCommand(command: string): Promise<boolean> {
20
+ const probeCommand = process.platform === 'win32' ? 'where' : 'command';
21
+ const probeArgs = process.platform === 'win32' ? [command] : ['-v', command];
22
+
23
+ return await new Promise<boolean>((resolve) => {
24
+ const child = spawn(probeCommand, probeArgs, { shell: process.platform !== 'win32' });
25
+ child.on('close', (code) => resolve(code === 0));
26
+ child.on('error', () => resolve(false));
27
+ });
28
+ }
29
+
30
  /**
31
  * Returns a robust baseline configuration for workspaces without a dev.nix.
32
  */
 
34
  return {
35
  packages: ['pkgs.nodejs', 'pkgs.go', 'pkgs.python3', 'pkgs.docker', 'pkgs.python3Packages.huggingface-hub'],
36
  onCreate: 'npm install',
37
+ onStart: process.platform === 'win32' ? 'Start-Sleep -Seconds 5; npm run dev' : 'sleep 5 && npm run dev'
38
  };
39
  }
40
 
 
79
  const log = (msg: string) => { if (onLog) onLog(`[IDX:NIX] ${msg}`); };
80
  log(`Syncing system packages: ${config.packages.join(', ')}...`);
81
 
82
+ const hasNix = await this.hasCommand('nix');
83
+ if (!hasNix) {
84
+ log(`Nix is unavailable on this host. Skipping declarative package sync.`);
85
+ return;
86
+ }
87
+
88
  // CACHIX ACCELERATION: Robust check for binary existence to prevent ENOENT crash
89
  const cachixName = process.env.CACHIX_CACHE_NAME || 'code-nix';
90
+ const hasCachix = await this.hasCommand('cachix');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
 
92
  if (hasCachix) {
93
  const cachixToken = process.env.CACHIX_AUTH_TOKEN;
 
171
 
172
  child.stdout.on('data', (data) => log(data.toString().trim()));
173
  child.stderr.on('data', (data) => log(`[INFO] ${data.toString().trim()}`));
174
+ child.on('error', (error) => reject(error));
175
 
176
  child.on('close', (code) => {
177
  if (code === 0) {
 
202
  delete spawnEnv.PORT;
203
  delete spawnEnv.SERVER_PORT;
204
 
205
+ const shellCommand = process.platform === 'win32' ? 'powershell.exe' : '/bin/bash';
206
+ const shellArgs = process.platform === 'win32' ? ['-NoProfile', '-Command', script] : ['-c', script];
207
+
208
+ const child = spawn(shellCommand, shellArgs, {
209
  cwd: workspacePath,
210
  env: spawnEnv
211
  });
212
 
213
  child.stdout.on('data', (data) => log(data.toString().trim()));
214
  child.stderr.on('data', (data) => log(`[WARN] ${data.toString().trim()}`));
215
+ child.on('error', (error) => {
216
+ log(`[ERROR] ${error.message}`);
217
+ reject(error);
218
+ });
219
 
220
  child.on('close', (code) => {
221
  if (code === 0) {
local.db ADDED
File without changes
package-lock.json CHANGED
@@ -16,7 +16,7 @@
16
  "@libsql/client": "^0.17.2",
17
  "@modelcontextprotocol/sdk": "^1.29.0",
18
  "@monaco-editor/react": "^4.7.0",
19
- "@radix-ui/react-dialog": "^1.1.15",
20
  "@radix-ui/react-dropdown-menu": "^2.1.16",
21
  "@radix-ui/react-progress": "^1.1.8",
22
  "@radix-ui/react-scroll-area": "^1.2.10",
@@ -27,11 +27,13 @@
27
  "@types/dockerode": "^4.0.1",
28
  "@xterm/addon-fit": "^0.11.0",
29
  "@xterm/xterm": "^6.0.0",
30
- "ai": "^6.0.146",
31
  "clsx": "^2.1.1",
32
  "cmdk": "^1.1.1",
 
33
  "date-fns": "^4.1.0",
34
  "dockerode": "^4.0.10",
 
35
  "framer-motion": "^12.38.0",
36
  "http-proxy": "^1.18.1",
37
  "lib0": "^0.2.117",
@@ -59,7 +61,7 @@
59
  "ws": "^8.19.0",
60
  "y-protocols": "^1.0.7",
61
  "yjs": "^13.6.29",
62
- "zod": "^4.3.6",
63
  "zustand": "^5.0.12"
64
  },
65
  "devDependencies": {
@@ -950,6 +952,12 @@
950
  "tslib": "^2.4.0"
951
  }
952
  },
 
 
 
 
 
 
953
  "node_modules/@eslint-community/eslint-utils": {
954
  "version": "4.9.1",
955
  "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
@@ -5560,6 +5568,23 @@
5560
  "node": ">=10.0.0"
5561
  }
5562
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5563
  "node_modules/cross-fetch": {
5564
  "version": "4.1.0",
5565
  "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz",
@@ -6032,6 +6057,18 @@
6032
  "@types/trusted-types": "^2.0.7"
6033
  }
6034
  },
 
 
 
 
 
 
 
 
 
 
 
 
6035
  "node_modules/dunder-proto": {
6036
  "version": "1.0.1",
6037
  "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
 
16
  "@libsql/client": "^0.17.2",
17
  "@modelcontextprotocol/sdk": "^1.29.0",
18
  "@monaco-editor/react": "^4.7.0",
19
+ "@radix-ui/react-dialog": "1.1.15",
20
  "@radix-ui/react-dropdown-menu": "^2.1.16",
21
  "@radix-ui/react-progress": "^1.1.8",
22
  "@radix-ui/react-scroll-area": "^1.2.10",
 
27
  "@types/dockerode": "^4.0.1",
28
  "@xterm/addon-fit": "^0.11.0",
29
  "@xterm/xterm": "^6.0.0",
30
+ "ai": "6.0.146",
31
  "clsx": "^2.1.1",
32
  "cmdk": "^1.1.1",
33
+ "cross-env": "^10.1.0",
34
  "date-fns": "^4.1.0",
35
  "dockerode": "^4.0.10",
36
+ "dotenv": "^17.2.3",
37
  "framer-motion": "^12.38.0",
38
  "http-proxy": "^1.18.1",
39
  "lib0": "^0.2.117",
 
61
  "ws": "^8.19.0",
62
  "y-protocols": "^1.0.7",
63
  "yjs": "^13.6.29",
64
+ "zod": "4.3.6",
65
  "zustand": "^5.0.12"
66
  },
67
  "devDependencies": {
 
952
  "tslib": "^2.4.0"
953
  }
954
  },
955
+ "node_modules/@epic-web/invariant": {
956
+ "version": "1.0.0",
957
+ "resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz",
958
+ "integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==",
959
+ "license": "MIT"
960
+ },
961
  "node_modules/@eslint-community/eslint-utils": {
962
  "version": "4.9.1",
963
  "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
 
5568
  "node": ">=10.0.0"
5569
  }
5570
  },
5571
+ "node_modules/cross-env": {
5572
+ "version": "10.1.0",
5573
+ "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz",
5574
+ "integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==",
5575
+ "license": "MIT",
5576
+ "dependencies": {
5577
+ "@epic-web/invariant": "^1.0.0",
5578
+ "cross-spawn": "^7.0.6"
5579
+ },
5580
+ "bin": {
5581
+ "cross-env": "dist/bin/cross-env.js",
5582
+ "cross-env-shell": "dist/bin/cross-env-shell.js"
5583
+ },
5584
+ "engines": {
5585
+ "node": ">=20"
5586
+ }
5587
+ },
5588
  "node_modules/cross-fetch": {
5589
  "version": "4.1.0",
5590
  "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz",
 
6057
  "@types/trusted-types": "^2.0.7"
6058
  }
6059
  },
6060
+ "node_modules/dotenv": {
6061
+ "version": "17.4.1",
6062
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.1.tgz",
6063
+ "integrity": "sha512-k8DaKGP6r1G30Lx8V4+pCsLzKr8vLmV2paqEj1Y55GdAgJuIqpRp5FfajGF8KtwMxCz9qJc6wUIJnm053d/WCw==",
6064
+ "license": "BSD-2-Clause",
6065
+ "engines": {
6066
+ "node": ">=12"
6067
+ },
6068
+ "funding": {
6069
+ "url": "https://dotenvx.com"
6070
+ }
6071
+ },
6072
  "node_modules/dunder-proto": {
6073
  "version": "1.0.1",
6074
  "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
package.json CHANGED
@@ -6,7 +6,7 @@
6
  "dev": "next dev",
7
  "prebuild": "npx rimraf dist",
8
  "build": "next build && tsc server.ts --esModuleInterop --skipLibCheck --target es2018 --module commonjs --moduleResolution node --downlevelIteration --outDir ./dist",
9
- "start": "node dist/server.js",
10
  "lint": "eslint . --ignore-pattern dist/ --ignore-pattern .next/"
11
  },
12
  "dependencies": {
@@ -31,9 +31,11 @@
31
  "@xterm/xterm": "^6.0.0",
32
  "ai": "6.0.146",
33
  "clsx": "^2.1.1",
 
34
  "cmdk": "^1.1.1",
35
  "date-fns": "^4.1.0",
36
  "dockerode": "^4.0.10",
 
37
  "framer-motion": "^12.38.0",
38
  "http-proxy": "^1.18.1",
39
  "lib0": "^0.2.117",
 
6
  "dev": "next dev",
7
  "prebuild": "npx rimraf dist",
8
  "build": "next build && tsc server.ts --esModuleInterop --skipLibCheck --target es2018 --module commonjs --moduleResolution node --downlevelIteration --outDir ./dist",
9
+ "start": "cross-env NODE_ENV=production node dist/server.js",
10
  "lint": "eslint . --ignore-pattern dist/ --ignore-pattern .next/"
11
  },
12
  "dependencies": {
 
31
  "@xterm/xterm": "^6.0.0",
32
  "ai": "6.0.146",
33
  "clsx": "^2.1.1",
34
+ "cross-env": "^10.1.0",
35
  "cmdk": "^1.1.1",
36
  "date-fns": "^4.1.0",
37
  "dockerode": "^4.0.10",
38
+ "dotenv": "^17.2.3",
39
  "framer-motion": "^12.38.0",
40
  "http-proxy": "^1.18.1",
41
  "lib0": "^0.2.117",
server.ts CHANGED
@@ -1,3 +1,5 @@
 
 
1
  /**
2
  * 🛰️ GLOBAL STABILIZATION (April 2026): Catch unhandled errors that cause HF Space restarts.
3
  */
@@ -289,7 +291,9 @@ server.listen(PORT, HOST, () => {
289
 
290
  // Reconnect and Warmup
291
  reconnectRunningWorkspaces().catch(() => {});
292
- prewarmWorkspace({ id: 'baseline-warmup', userId: 'system', projectName: 'CodeVerse-Internal' }).catch(() => {});
 
 
293
 
294
  // Crons and Persistence
295
  HFStorage.startAutoSave(INFRA_CONFIG.PERSISTENCE_INTERVAL_MS * 5);
 
1
+ import "dotenv/config";
2
+
3
  /**
4
  * 🛰️ GLOBAL STABILIZATION (April 2026): Catch unhandled errors that cause HF Space restarts.
5
  */
 
291
 
292
  // Reconnect and Warmup
293
  reconnectRunningWorkspaces().catch(() => {});
294
+ if (process.env.ENABLE_BASELINE_PREWARM === 'true') {
295
+ prewarmWorkspace({ id: 'baseline-warmup', userId: 'system', projectName: 'CodeVerse-Internal' }).catch(() => {});
296
+ }
297
 
298
  // Crons and Persistence
299
  HFStorage.startAutoSave(INFRA_CONFIG.PERSISTENCE_INTERVAL_MS * 5);
workspaces/dev-user-id/local-repro ADDED
@@ -0,0 +1 @@
 
 
1
+ Subproject commit 7fd1a60b01f91b314f59955a4e4d4e80d8edf11d