shubhjn commited on
Commit
0632984
·
1 Parent(s): c470ff4

improve handshake

Browse files
.agent/memory/session.json CHANGED
@@ -1,7 +1,7 @@
1
  {
2
  "version": "1.0.0",
3
- "session_id": "071afedd",
4
- "started_at": "2026-04-06T22:09:51.759229+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": "625a7b0d",
4
+ "started_at": "2026-04-06T22:23:02.815736+05:30",
5
  "workspace": "D:\\Code\\codeverse",
6
  "active_task_id": null,
7
  "active_agent": null,
lib/docker/manager.ts CHANGED
@@ -131,7 +131,7 @@ export async function prewarmWorkspace(config: WorkspaceConfig): Promise<void> {
131
  const workspacePath = path.join(/*turbopackIgnore: true*/ workspaceRoot, config.id);
132
 
133
  if (!fs.existsSync(workspacePath)) {
134
- fs.mkdirSync(workspacePath, { recursive: true });
135
  }
136
 
137
  const idxConfig = IdxEngine.getIdxConfig(workspacePath);
@@ -164,7 +164,7 @@ async function performProvisioning(config: WorkspaceConfig): Promise<WorkspaceOp
164
  const userDataPath = path.join(/*turbopackIgnore: true*/ workspacePath, '.vscode-server');
165
 
166
  if (!fs.existsSync(workspacePath)) {
167
- fs.mkdirSync(workspacePath, { recursive: true });
168
  log(`Allocated isolated filesystem segment: ${config.id.slice(0, 8)}`);
169
  }
170
 
@@ -174,7 +174,7 @@ async function performProvisioning(config: WorkspaceConfig): Promise<WorkspaceOp
174
 
175
  await IdxEngine.syncNixEnvironment(workspacePath, idxConfig, (msg) => log(msg));
176
 
177
- const flagPath = path.join(workspacePath, '.idx-created');
178
  if (!fs.existsSync(flagPath)) {
179
  if (idxConfig.onCreate) {
180
  log(`Executing onCreate lifecycle hook...`);
@@ -183,10 +183,9 @@ async function performProvisioning(config: WorkspaceConfig): Promise<WorkspaceOp
183
  fs.writeFileSync(flagPath, new Date().toISOString());
184
  }
185
 
186
- if (idxConfig.onStart) {
187
- log(`Executing onStart lifecycle hook...`);
188
- // ONSTART HOOKS MUST BE BACKGROUND: They typically start servers (npm run dev) and never exit.
189
- await IdxEngine.runHook(workspacePath, 'onStart', idxConfig.onStart, (msg) => log(msg), true);
190
  }
191
 
192
  // 4. Identify Target Port
@@ -224,11 +223,18 @@ async function performProvisioning(config: WorkspaceConfig): Promise<WorkspaceOp
224
 
225
  // 7. Handshake Loop
226
  let attempts = 0;
227
- while (attempts < 15) {
228
  try {
229
  const res = await fetch(`http://127.0.0.1:${port}`);
230
  if (res.ok) {
231
  log(`Handshake verified. Studio Engine Online.`);
 
 
 
 
 
 
 
232
  const finalResult = {
233
  success: true,
234
  containerId: `native-${config.id}`,
@@ -239,9 +245,9 @@ async function performProvisioning(config: WorkspaceConfig): Promise<WorkspaceOp
239
  return finalResult;
240
  }
241
  } catch {
242
- if (attempts % 3 === 0) log(`[INFO] Scanning for IDE heartbeat... (Attempt ${attempts}/15)`);
243
- if (attempts === 5) log(`[INFO] Nix evaluation in progress. Cold boot detected.`);
244
- if (attempts === 10) log(`[WARN] Handshake threshold approaching. IDE core high load.`);
245
  await delay(1000);
246
  attempts++;
247
  }
 
131
  const workspacePath = path.join(/*turbopackIgnore: true*/ workspaceRoot, config.id);
132
 
133
  if (!fs.existsSync(workspacePath)) {
134
+ fs.mkdirSync(/*turbopackIgnore: true*/ workspacePath, { recursive: true });
135
  }
136
 
137
  const idxConfig = IdxEngine.getIdxConfig(workspacePath);
 
164
  const userDataPath = path.join(/*turbopackIgnore: true*/ workspacePath, '.vscode-server');
165
 
166
  if (!fs.existsSync(workspacePath)) {
167
+ fs.mkdirSync(/*turbopackIgnore: true*/ workspacePath, { recursive: true });
168
  log(`Allocated isolated filesystem segment: ${config.id.slice(0, 8)}`);
169
  }
170
 
 
174
 
175
  await IdxEngine.syncNixEnvironment(workspacePath, idxConfig, (msg) => log(msg));
176
 
177
+ const flagPath = path.join(/*turbopackIgnore: true*/ workspacePath, '.idx-created');
178
  if (!fs.existsSync(flagPath)) {
179
  if (idxConfig.onCreate) {
180
  log(`Executing onCreate lifecycle hook...`);
 
183
  fs.writeFileSync(flagPath, new Date().toISOString());
184
  }
185
 
186
+ if (idxConfig.onCreate) {
187
+ log(`Executing onCreate lifecycle hook...`);
188
+ await IdxEngine.runHook(workspacePath, 'onCreate', idxConfig.onCreate, (msg) => log(msg));
 
189
  }
190
 
191
  // 4. Identify Target Port
 
223
 
224
  // 7. Handshake Loop
225
  let attempts = 0;
226
+ while (attempts < 60) {
227
  try {
228
  const res = await fetch(`http://127.0.0.1:${port}`);
229
  if (res.ok) {
230
  log(`Handshake verified. Studio Engine Online.`);
231
+
232
+ // 🟢 PRIORITY SHIFT: Start hooks ONLY AFTER the IDE is confirmed ready
233
+ if (idxConfig.onStart) {
234
+ log(`Executing background onStart lifecycle hooks...`);
235
+ IdxEngine.runHook(workspacePath, 'onStart', idxConfig.onStart, (msg) => log(msg), true);
236
+ }
237
+
238
  const finalResult = {
239
  success: true,
240
  containerId: `native-${config.id}`,
 
245
  return finalResult;
246
  }
247
  } catch {
248
+ if (attempts % 5 === 0) log(`[INFO] Scanning for IDE heartbeat... (Attempt ${attempts}/60)`);
249
+ if (attempts === 15) log(`[INFO] Nix evaluation in progress. Cold boot detected.`);
250
+ if (attempts === 45) log(`[WARN] Handshake threshold approaching. IDE core high load.`);
251
  await delay(1000);
252
  attempts++;
253
  }
lib/fs/isolation.ts CHANGED
@@ -32,7 +32,7 @@ const WORKSPACE_BASE = resolveWorkspaceBase();
32
  * e.g., /path/to/codeverse/workspaces/{userId}
33
  */
34
  export async function getUserWorkspaceRoot(userId: string): Promise<string> {
35
- const userRoot = path.join(WORKSPACE_BASE, userId);
36
  try {
37
  await fs.mkdir(userRoot, { recursive: true });
38
  } catch (e: unknown) {
@@ -50,10 +50,10 @@ export async function getUserWorkspaceRoot(userId: string): Promise<string> {
50
  */
51
  export async function resolveSafeProjectPath(userId: string, projectName: string, subPath: string = ""): Promise<string> {
52
  const userRoot = await getUserWorkspaceRoot(userId);
53
- const projectRoot = path.resolve(userRoot, projectName.replace(/[^a-zA-Z0-9-_]/g, "-").slice(0, 60));
54
 
55
  // Normalize and resolve the absolute path
56
- const targetPath = path.resolve(projectRoot, subPath);
57
 
58
  // Security Check: Ensure the resolved path is still within the project root
59
  if (!targetPath.startsWith(projectRoot)) {
@@ -70,7 +70,7 @@ export async function resolveSafePath(userId: string, subPath: string): Promise<
70
  const userRoot = await getUserWorkspaceRoot(userId);
71
 
72
  // Normalize and resolve the absolute path
73
- const targetPath = path.resolve(userRoot, subPath);
74
 
75
  // Security Check: Ensure the resolved path is still within the user's root
76
  if (!targetPath.startsWith(userRoot)) {
 
32
  * e.g., /path/to/codeverse/workspaces/{userId}
33
  */
34
  export async function getUserWorkspaceRoot(userId: string): Promise<string> {
35
+ const userRoot = path.join(/*turbopackIgnore: true*/ WORKSPACE_BASE, userId);
36
  try {
37
  await fs.mkdir(userRoot, { recursive: true });
38
  } catch (e: unknown) {
 
50
  */
51
  export async function resolveSafeProjectPath(userId: string, projectName: string, subPath: string = ""): Promise<string> {
52
  const userRoot = await getUserWorkspaceRoot(userId);
53
+ const projectRoot = path.resolve(/*turbopackIgnore: true*/ userRoot, projectName.replace(/[^a-zA-Z0-9-_]/g, "-").slice(0, 60));
54
 
55
  // Normalize and resolve the absolute path
56
+ const targetPath = path.resolve(/*turbopackIgnore: true*/ projectRoot, subPath);
57
 
58
  // Security Check: Ensure the resolved path is still within the project root
59
  if (!targetPath.startsWith(projectRoot)) {
 
70
  const userRoot = await getUserWorkspaceRoot(userId);
71
 
72
  // Normalize and resolve the absolute path
73
+ const targetPath = path.resolve(/*turbopackIgnore: true*/ userRoot, subPath);
74
 
75
  // Security Check: Ensure the resolved path is still within the user's root
76
  if (!targetPath.startsWith(userRoot)) {
lib/idx/idx-engine.ts CHANGED
@@ -31,7 +31,7 @@ export class IdxEngine {
31
  * Detects and parses the .idx/dev.nix file in the workspace root.
32
  */
33
  static getIdxConfig(workspacePath: string): IdxConfig {
34
- const configPath = path.join(workspacePath, '.idx', 'dev.nix');
35
  if (!fs.existsSync(configPath)) return this.getDefaultConfig();
36
 
37
  try {
 
31
  * Detects and parses the .idx/dev.nix file in the workspace root.
32
  */
33
  static getIdxConfig(workspacePath: string): IdxConfig {
34
+ const configPath = path.join(/*turbopackIgnore: true*/ workspacePath, '.idx', 'dev.nix');
35
  if (!fs.existsSync(configPath)) return this.getDefaultConfig();
36
 
37
  try {
next.config.ts CHANGED
@@ -1,7 +1,6 @@
1
  import type { NextConfig } from "next";
2
 
3
  const nextConfig: NextConfig = {
4
- output: "standalone",
5
  enablePrerenderSourceMaps: true,
6
  serverExternalPackages: ["dockerode", "ssh2", "tar-fs", "node-pty"],
7
  };
 
1
  import type { NextConfig } from "next";
2
 
3
  const nextConfig: NextConfig = {
 
4
  enablePrerenderSourceMaps: true,
5
  serverExternalPackages: ["dockerode", "ssh2", "tar-fs", "node-pty"],
6
  };