fix launch error
Browse files- .agent/memory/session.json +2 -2
- Dockerfile +9 -5
- lib/docker/manager.ts +5 -2
- lib/idx/idx-engine.ts +38 -11
.agent/memory/session.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
{
|
| 2 |
"version": "1.0.0",
|
| 3 |
-
"session_id": "
|
| 4 |
-
"started_at": "2026-04-
|
| 5 |
"workspace": "D:\\Code\\codeverse",
|
| 6 |
"active_task_id": null,
|
| 7 |
"active_agent": null,
|
|
|
|
| 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,
|
Dockerfile
CHANGED
|
@@ -21,8 +21,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
| 21 |
&& rm -rf /var/lib/apt/lists/*
|
| 22 |
|
| 23 |
# Install Hugging Face CLI & code-server in a single hardening pass
|
| 24 |
-
|
| 25 |
-
|
| 26 |
|
| 27 |
# 2. Nix Installation (Hardened for Hugging Face 2026)
|
| 28 |
RUN mkdir -p /nix && chown node:node /nix && \
|
|
@@ -34,8 +34,9 @@ USER node
|
|
| 34 |
WORKDIR /home/node
|
| 35 |
SHELL ["/bin/bash", "-c"]
|
| 36 |
|
| 37 |
-
# Note: ulimit is set to the builder's maximum during install
|
| 38 |
-
#
|
|
|
|
| 39 |
RUN export XDG_CACHE_HOME=/home/node/.cache && \
|
| 40 |
ulimit -s $(ulimit -Hs) 2>/dev/null || true && \
|
| 41 |
rm -rf /home/node/.nix-defexpr /home/node/.nix-profile /home/node/.nix-channels && \
|
|
@@ -44,11 +45,14 @@ RUN export XDG_CACHE_HOME=/home/node/.cache && \
|
|
| 44 |
/home/node/.nix-profile/bin/nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs && \
|
| 45 |
/home/node/.nix-profile/bin/nix-channel --update
|
| 46 |
|
| 47 |
-
ENV PATH="/home/node/.nix-profile/bin:/home/node/.nix-profile/sbin:${PATH}"
|
| 48 |
ENV NIX_PATH="nixpkgs=/home/node/.nix-defexpr/channels/nixpkgs"
|
| 49 |
|
| 50 |
# 3. Application Provisioning
|
| 51 |
USER root
|
|
|
|
|
|
|
|
|
|
| 52 |
RUN mkdir -p /home/node/app && chown -R node:node /home/node/app
|
| 53 |
WORKDIR /home/node/app
|
| 54 |
|
|
|
|
| 21 |
&& rm -rf /var/lib/apt/lists/*
|
| 22 |
|
| 23 |
# Install Hugging Face CLI & code-server in a single hardening pass
|
| 24 |
+
# Install code-server globally (as root)
|
| 25 |
+
RUN curl -fsSL https://code-server.dev/install.sh | sh
|
| 26 |
|
| 27 |
# 2. Nix Installation (Hardened for Hugging Face 2026)
|
| 28 |
RUN mkdir -p /nix && chown node:node /nix && \
|
|
|
|
| 34 |
WORKDIR /home/node
|
| 35 |
SHELL ["/bin/bash", "-c"]
|
| 36 |
|
| 37 |
+
# Note: ulimit is set to the builder's maximum during install.
|
| 38 |
+
# If you see 'Stack size hard limit is 10485760...', this is an expected, benign warning
|
| 39 |
+
# on Hugging Face Spaces (10MB limit). Nix prefers 60MB but 10MB is sufficient for CodeVerse.
|
| 40 |
RUN export XDG_CACHE_HOME=/home/node/.cache && \
|
| 41 |
ulimit -s $(ulimit -Hs) 2>/dev/null || true && \
|
| 42 |
rm -rf /home/node/.nix-defexpr /home/node/.nix-profile /home/node/.nix-channels && \
|
|
|
|
| 45 |
/home/node/.nix-profile/bin/nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs && \
|
| 46 |
/home/node/.nix-profile/bin/nix-channel --update
|
| 47 |
|
| 48 |
+
ENV PATH="/home/node/.local/bin:/home/node/.nix-profile/bin:/home/node/.nix-profile/sbin:${PATH}"
|
| 49 |
ENV NIX_PATH="nixpkgs=/home/node/.nix-defexpr/channels/nixpkgs"
|
| 50 |
|
| 51 |
# 3. Application Provisioning
|
| 52 |
USER root
|
| 53 |
+
RUN pip3 install --no-cache-dir --upgrade "huggingface_hub[cli]"
|
| 54 |
+
# Use Nix to install Cachix globally (for the container baseline)
|
| 55 |
+
RUN /home/node/.nix-profile/bin/nix profile add nixpkgs#cachix
|
| 56 |
RUN mkdir -p /home/node/app && chown -R node:node /home/node/app
|
| 57 |
WORKDIR /home/node/app
|
| 58 |
|
lib/docker/manager.ts
CHANGED
|
@@ -185,7 +185,8 @@ async function performProvisioning(config: WorkspaceConfig): Promise<WorkspaceOp
|
|
| 185 |
|
| 186 |
if (idxConfig.onStart) {
|
| 187 |
log(`Executing onStart lifecycle hook...`);
|
| 188 |
-
|
|
|
|
| 189 |
}
|
| 190 |
|
| 191 |
// 4. Identify Target Port
|
|
@@ -238,9 +239,11 @@ async function performProvisioning(config: WorkspaceConfig): Promise<WorkspaceOp
|
|
| 238 |
return finalResult;
|
| 239 |
}
|
| 240 |
} catch {
|
|
|
|
|
|
|
|
|
|
| 241 |
await delay(1000);
|
| 242 |
attempts++;
|
| 243 |
-
if (attempts % 3 === 0) log(`Warming up IDE core (attempt ${attempts}/15)...`);
|
| 244 |
}
|
| 245 |
}
|
| 246 |
|
|
|
|
| 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
|
|
|
|
| 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 |
}
|
| 248 |
}
|
| 249 |
|
lib/idx/idx-engine.ts
CHANGED
|
@@ -23,7 +23,7 @@ export class IdxEngine {
|
|
| 23 |
return {
|
| 24 |
packages: ['pkgs.nodejs', 'pkgs.go', 'pkgs.python3', 'pkgs.docker'],
|
| 25 |
onCreate: 'npm install',
|
| 26 |
-
onStart: 'npm run dev'
|
| 27 |
};
|
| 28 |
}
|
| 29 |
|
|
@@ -89,6 +89,15 @@ export class IdxEngine {
|
|
| 89 |
}
|
| 90 |
|
| 91 |
if (hasCachix) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
log(`Cachix acceleration detected. Setting up cache: ${cachixName}...`);
|
| 93 |
try {
|
| 94 |
await new Promise<void>((resolve, reject) => {
|
|
@@ -136,28 +145,46 @@ export class IdxEngine {
|
|
| 136 |
|
| 137 |
/**
|
| 138 |
* Executes the 'onCreate' and 'onStart' hooks.
|
| 139 |
-
*
|
| 140 |
*/
|
| 141 |
-
static async runHook(workspacePath: string, hookName: 'onCreate' | 'onStart', script: string, onLog?: (msg: string) => void): Promise<void> {
|
| 142 |
const log = (msg: string) => { if (onLog) onLog(`[IDX:HOOK] ${hookName}: ${msg}`); };
|
| 143 |
-
log(`Executing script...`);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
|
| 145 |
-
await new Promise<void>((resolve, reject) => {
|
| 146 |
const child = spawn('/bin/bash', ['-c', script], {
|
| 147 |
cwd: workspacePath,
|
| 148 |
-
env:
|
| 149 |
});
|
| 150 |
|
| 151 |
child.stdout.on('data', (data) => log(data.toString().trim()));
|
| 152 |
child.stderr.on('data', (data) => log(`[WARN] ${data.toString().trim()}`));
|
| 153 |
|
| 154 |
child.on('close', (code) => {
|
| 155 |
-
if (code === 0)
|
| 156 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
});
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
|
|
|
|
|
|
|
|
|
| 161 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
}
|
| 163 |
}
|
|
|
|
| 23 |
return {
|
| 24 |
packages: ['pkgs.nodejs', 'pkgs.go', 'pkgs.python3', 'pkgs.docker'],
|
| 25 |
onCreate: 'npm install',
|
| 26 |
+
onStart: 'sleep 5 && npm run dev'
|
| 27 |
};
|
| 28 |
}
|
| 29 |
|
|
|
|
| 89 |
}
|
| 90 |
|
| 91 |
if (hasCachix) {
|
| 92 |
+
const cachixToken = process.env.CACHIX_AUTH_TOKEN;
|
| 93 |
+
if (cachixToken) {
|
| 94 |
+
log(`Cachix authentication detected. Configuring access...`);
|
| 95 |
+
await new Promise<void>((resolve) => {
|
| 96 |
+
const auth = spawn('cachix', ['authtoken', cachixToken], { env: { ...process.env, HOME: workspacePath } });
|
| 97 |
+
auth.on('close', () => resolve());
|
| 98 |
+
});
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
log(`Cachix acceleration detected. Setting up cache: ${cachixName}...`);
|
| 102 |
try {
|
| 103 |
await new Promise<void>((resolve, reject) => {
|
|
|
|
| 145 |
|
| 146 |
/**
|
| 147 |
* Executes the 'onCreate' and 'onStart' hooks.
|
| 148 |
+
* supports background execution for 'onStart' to prevent blocking the IDE handshake.
|
| 149 |
*/
|
| 150 |
+
static async runHook(workspacePath: string, hookName: 'onCreate' | 'onStart', script: string, onLog?: (msg: string) => void, background = false): Promise<void> {
|
| 151 |
const log = (msg: string) => { if (onLog) onLog(`[IDX:HOOK] ${hookName}: ${msg}`); };
|
| 152 |
+
log(`Executing script... ${background ? '(Background)' : ''}`);
|
| 153 |
+
|
| 154 |
+
const hookPromise = new Promise<void>((resolve, reject) => {
|
| 155 |
+
// 🟢 PORT DE-CONFLICTION: Ensure hooks don't inherit the main orchestrator's port 7860
|
| 156 |
+
const spawnEnv: any = { ...process.env, HOME: workspacePath };
|
| 157 |
+
delete spawnEnv.PORT;
|
| 158 |
+
delete spawnEnv.SERVER_PORT;
|
| 159 |
|
|
|
|
| 160 |
const child = spawn('/bin/bash', ['-c', script], {
|
| 161 |
cwd: workspacePath,
|
| 162 |
+
env: spawnEnv
|
| 163 |
});
|
| 164 |
|
| 165 |
child.stdout.on('data', (data) => log(data.toString().trim()));
|
| 166 |
child.stderr.on('data', (data) => log(`[WARN] ${data.toString().trim()}`));
|
| 167 |
|
| 168 |
child.on('close', (code) => {
|
| 169 |
+
if (code === 0) {
|
| 170 |
+
log(`Hook ${hookName} completed successfully.`);
|
| 171 |
+
resolve();
|
| 172 |
+
} else {
|
| 173 |
+
const err = new Error(`Hook ${hookName} failed with code ${code}`);
|
| 174 |
+
log(`[ERROR] ${err.message}`);
|
| 175 |
+
reject(err);
|
| 176 |
+
}
|
| 177 |
});
|
| 178 |
+
|
| 179 |
+
// If background, resolve immediately after spawn
|
| 180 |
+
if (background) {
|
| 181 |
+
log(`Hook detached and running in baseline context.`);
|
| 182 |
+
resolve();
|
| 183 |
+
}
|
| 184 |
});
|
| 185 |
+
|
| 186 |
+
if (!background) {
|
| 187 |
+
await hookPromise.catch(() => {}); // Catch handled in promise
|
| 188 |
+
}
|
| 189 |
}
|
| 190 |
}
|