deepdebug-local-agent 1.0.18 → 1.0.20
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/Dockerfile +32 -16
- package/cloudbuild-agent-qa.yaml +43 -0
- package/docker-compose.yml +2 -2
- package/package.json +1 -1
- package/src/exec-utils.js +126 -23
- package/src/server.js +563 -45
- package/src/vercel-proxy.js +226 -0
- package/tunnel-manager.js +70 -0
package/Dockerfile
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# ║ DeepDebug Local Agent - Enterprise Docker ║
|
|
3
3
|
# ║ ║
|
|
4
4
|
# ║ Security-hardened container for enterprise deployments ║
|
|
5
|
-
# ║ Supports:
|
|
5
|
+
# ║ Supports: Cloud Run with NFS (GCP Filestore) ║
|
|
6
6
|
# ╚══════════════════════════════════════════════════════════════╝
|
|
7
7
|
|
|
8
8
|
# ===========================================
|
|
@@ -12,14 +12,9 @@ FROM node:20-alpine AS builder
|
|
|
12
12
|
|
|
13
13
|
WORKDIR /build
|
|
14
14
|
|
|
15
|
-
# Copy package files first (better cache)
|
|
16
15
|
COPY package*.json ./
|
|
17
|
-
|
|
18
|
-
# Install dependencies (production only)
|
|
19
|
-
# Using npm install instead of npm ci for repos without package-lock.json
|
|
20
16
|
RUN npm install --omit=dev && npm cache clean --force
|
|
21
17
|
|
|
22
|
-
# Copy source code
|
|
23
18
|
COPY src/ ./src/
|
|
24
19
|
|
|
25
20
|
# ===========================================
|
|
@@ -27,48 +22,69 @@ COPY src/ ./src/
|
|
|
27
22
|
# ===========================================
|
|
28
23
|
FROM node:20-alpine AS production
|
|
29
24
|
|
|
30
|
-
# Security: Add labels for compliance
|
|
31
25
|
LABEL org.opencontainers.image.title="DeepDebug Local Agent"
|
|
32
26
|
LABEL org.opencontainers.image.description="Enterprise debugging agent for code analysis"
|
|
33
27
|
LABEL org.opencontainers.image.vendor="InspTech AI"
|
|
34
|
-
LABEL org.opencontainers.image.version="1.
|
|
28
|
+
LABEL org.opencontainers.image.version="1.2.0"
|
|
35
29
|
LABEL org.opencontainers.image.licenses="Proprietary"
|
|
36
30
|
LABEL security.scan.required="true"
|
|
37
31
|
|
|
38
|
-
#
|
|
32
|
+
# Create non-root user
|
|
39
33
|
RUN addgroup -g 1001 -S deepdebug && \
|
|
40
34
|
adduser -u 1001 -S deepdebug -G deepdebug
|
|
41
35
|
|
|
42
|
-
#
|
|
36
|
+
# Install dependencies including Java 17 for Maven wrapper support
|
|
43
37
|
RUN apk update && \
|
|
44
38
|
apk upgrade --no-cache && \
|
|
45
39
|
apk add --no-cache \
|
|
46
40
|
dumb-init \
|
|
47
41
|
git \
|
|
48
42
|
curl \
|
|
43
|
+
nfs-utils \
|
|
44
|
+
openjdk17-jdk \
|
|
49
45
|
&& rm -rf /var/cache/apk/*
|
|
50
46
|
|
|
47
|
+
# Set JAVA_HOME so ./mvnw can find Java
|
|
48
|
+
# Alpine stores JVM under java-17-openjdk with arch suffix - use readlink to resolve
|
|
49
|
+
RUN ln -sf $(dirname $(dirname $(readlink -f $(which java)))) /usr/local/java-home
|
|
50
|
+
ENV JAVA_HOME=/usr/local/java-home
|
|
51
|
+
ENV PATH="$JAVA_HOME/bin:$PATH"
|
|
52
|
+
|
|
53
|
+
# Create NFS mount point with correct ownership
|
|
54
|
+
RUN mkdir -p /mnt/workspaces && \
|
|
55
|
+
chown deepdebug:deepdebug /mnt/workspaces
|
|
56
|
+
|
|
57
|
+
# Install cloudflared for tunnel support (Vibe preview)
|
|
58
|
+
RUN wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 \
|
|
59
|
+
-O /usr/local/bin/cloudflared && \
|
|
60
|
+
chmod +x /usr/local/bin/cloudflared && \
|
|
61
|
+
cloudflared --version
|
|
62
|
+
|
|
63
|
+
# Install GitHub CLI (gh) for PR creation
|
|
64
|
+
RUN wget -q https://github.com/cli/cli/releases/download/v2.63.2/gh_2.63.2_linux_amd64.tar.gz \
|
|
65
|
+
-O /tmp/gh.tar.gz && \
|
|
66
|
+
tar -xzf /tmp/gh.tar.gz -C /tmp && \
|
|
67
|
+
mv /tmp/gh_2.63.2_linux_amd64/bin/gh /usr/local/bin/gh && \
|
|
68
|
+
chmod +x /usr/local/bin/gh && \
|
|
69
|
+
rm -rf /tmp/gh* && \
|
|
70
|
+
gh --version
|
|
71
|
+
|
|
51
72
|
WORKDIR /app
|
|
52
73
|
|
|
53
|
-
# Copy from builder with correct ownership
|
|
54
74
|
COPY --from=builder --chown=deepdebug:deepdebug /build/node_modules ./node_modules
|
|
55
75
|
COPY --from=builder --chown=deepdebug:deepdebug /build/src ./src
|
|
56
76
|
COPY --chown=deepdebug:deepdebug package*.json ./
|
|
57
77
|
|
|
58
|
-
# Security: Switch to non-root user
|
|
59
78
|
USER deepdebug
|
|
60
79
|
|
|
61
|
-
# Health check
|
|
62
80
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
|
63
81
|
CMD curl -f http://localhost:5055/health || exit 1
|
|
64
82
|
|
|
65
|
-
# Environment
|
|
66
83
|
ENV NODE_ENV=production
|
|
67
84
|
ENV PORT=5055
|
|
85
|
+
ENV WORKSPACES_MOUNT=/mnt/workspaces
|
|
68
86
|
|
|
69
|
-
# Expose port
|
|
70
87
|
EXPOSE 5055
|
|
71
88
|
|
|
72
|
-
# Security: Use dumb-init to handle signals properly
|
|
73
89
|
ENTRYPOINT ["dumb-init", "--"]
|
|
74
90
|
CMD ["node", "src/server.js"]
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
steps:
|
|
2
|
+
# Step 1: Build Docker image
|
|
3
|
+
- name: 'gcr.io/cloud-builders/docker'
|
|
4
|
+
args:
|
|
5
|
+
- 'build'
|
|
6
|
+
- '--platform=linux/amd64'
|
|
7
|
+
- '-t'
|
|
8
|
+
- 'us-central1-docker.pkg.dev/insptechai/deepdebug-docker/local-agent-qa:latest'
|
|
9
|
+
- '.'
|
|
10
|
+
timeout: '600s'
|
|
11
|
+
|
|
12
|
+
# Step 2: Push to Artifact Registry
|
|
13
|
+
- name: 'gcr.io/cloud-builders/docker'
|
|
14
|
+
args:
|
|
15
|
+
- 'push'
|
|
16
|
+
- 'us-central1-docker.pkg.dev/insptechai/deepdebug-docker/local-agent-qa:latest'
|
|
17
|
+
|
|
18
|
+
# Step 3: Deploy to Cloud Run QA
|
|
19
|
+
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
|
|
20
|
+
entrypoint: 'gcloud'
|
|
21
|
+
args:
|
|
22
|
+
- 'run'
|
|
23
|
+
- 'deploy'
|
|
24
|
+
- 'deepdebug-local-agent-qa'
|
|
25
|
+
- '--image=us-central1-docker.pkg.dev/insptechai/deepdebug-docker/local-agent-qa:latest'
|
|
26
|
+
- '--region=us-central1'
|
|
27
|
+
- '--platform=managed'
|
|
28
|
+
- '--allow-unauthenticated'
|
|
29
|
+
- '--memory=1Gi'
|
|
30
|
+
- '--cpu=1'
|
|
31
|
+
- '--min-instances=1'
|
|
32
|
+
- '--max-instances=3'
|
|
33
|
+
- '--port=5055'
|
|
34
|
+
- '--timeout=300'
|
|
35
|
+
- '--update-env-vars=NODE_ENV=qa'
|
|
36
|
+
|
|
37
|
+
images:
|
|
38
|
+
- 'us-central1-docker.pkg.dev/insptechai/deepdebug-docker/local-agent-qa:latest'
|
|
39
|
+
|
|
40
|
+
options:
|
|
41
|
+
logging: CLOUD_LOGGING_ONLY
|
|
42
|
+
|
|
43
|
+
timeout: '1200s'
|
package/docker-compose.yml
CHANGED
|
@@ -52,8 +52,8 @@ services:
|
|
|
52
52
|
# Volumes
|
|
53
53
|
# ─────────────────────────────────────────
|
|
54
54
|
volumes:
|
|
55
|
-
# Project source code
|
|
56
|
-
-
|
|
55
|
+
# Project source code - writable so agent can apply patches
|
|
56
|
+
- /Users/macintosh/IdeaProjects:/workspace
|
|
57
57
|
# Temp directory for container writes
|
|
58
58
|
- agent-tmp:/tmp
|
|
59
59
|
|
package/package.json
CHANGED
package/src/exec-utils.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { spawn } from "child_process";
|
|
2
2
|
import stripAnsi from "strip-ansi";
|
|
3
3
|
|
|
4
|
-
export function run(cmd, args, cwd, timeoutMs = 10 * 60 * 1000) {
|
|
4
|
+
export function run(cmd, args, cwd, timeoutMs = 10 * 60 * 1000, env = null) {
|
|
5
5
|
return new Promise((resolve) => {
|
|
6
6
|
const start = Date.now();
|
|
7
|
-
const
|
|
7
|
+
const spawnOpts = { cwd, shell: true };
|
|
8
|
+
if (env) spawnOpts.env = env;
|
|
9
|
+
const child = spawn(cmd, args, spawnOpts);
|
|
8
10
|
let stdout = "";
|
|
9
11
|
let stderr = "";
|
|
10
12
|
const timer = setTimeout(() => {
|
|
@@ -47,20 +49,121 @@ export function run(cmd, args, cwd, timeoutMs = 10 * 60 * 1000) {
|
|
|
47
49
|
* @returns {Promise<{code: number, stdout: string, stderr: string, duration: number}>}
|
|
48
50
|
*/
|
|
49
51
|
export async function compileAndTest({ language, buildTool, cwd, skipTests = false }) {
|
|
50
|
-
console.log(
|
|
52
|
+
console.log(`[BUILD] [COMPILE] Language: ${language}, BuildTool: ${buildTool}, SkipTests: ${skipTests}`);
|
|
51
53
|
|
|
52
54
|
let result;
|
|
53
55
|
const start = Date.now();
|
|
54
56
|
|
|
55
57
|
try {
|
|
56
58
|
if (language === "java" && buildTool === "maven") {
|
|
57
|
-
//
|
|
59
|
+
// Prefer ./mvnw wrapper over system mvn
|
|
60
|
+
const fs = await import("fs");
|
|
61
|
+
const path = await import("path");
|
|
62
|
+
const hasMvnw = fs.existsSync(path.join(cwd, "mvnw"));
|
|
63
|
+
const mvnCmd = hasMvnw ? "./mvnw" : "mvn";
|
|
64
|
+
|
|
65
|
+
// Verify build tool is available before attempting
|
|
66
|
+
if (!hasMvnw) {
|
|
67
|
+
const check = await run("which mvn", [], cwd);
|
|
68
|
+
if (check.code !== 0) {
|
|
69
|
+
return {
|
|
70
|
+
code: 1,
|
|
71
|
+
stdout: "",
|
|
72
|
+
stderr: "Maven not found: neither ./mvnw nor mvn is available in this environment.",
|
|
73
|
+
duration: Date.now() - start
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Fix for maven-compiler-plugin 3.8.1 + Java 17:
|
|
79
|
+
// plexus-compiler-javac 2.8.4 does not support --release 17.
|
|
80
|
+
// Workaround: disable the --release flag entirely and use -source/-target instead.
|
|
81
|
+
// Also pass JAVA_HOME explicitly so mvnw uses the correct JDK.
|
|
82
|
+
// Dynamically prepare Maven environment and fix common Java version issues
|
|
83
|
+
const fs2 = await import("fs");
|
|
84
|
+
const path2 = await import("path");
|
|
85
|
+
|
|
86
|
+
// 1. Detect Java version available
|
|
87
|
+
const javaHome = process.env.JAVA_HOME || "/usr/local/java-home";
|
|
88
|
+
const javacPath = `${javaHome}/bin/javac`;
|
|
89
|
+
const hasJavac = fs2.existsSync(javacPath);
|
|
90
|
+
const mavenEnv = {
|
|
91
|
+
...process.env,
|
|
92
|
+
JAVA_HOME: javaHome,
|
|
93
|
+
PATH: `${javaHome}/bin:${process.env.PATH}`
|
|
94
|
+
};
|
|
95
|
+
console.log(`[BUILD] JAVA_HOME=${javaHome}, javac available=${hasJavac}`);
|
|
96
|
+
|
|
97
|
+
// 2. Detect Java version from javac
|
|
98
|
+
let javaVersion = 11; // default fallback
|
|
99
|
+
try {
|
|
100
|
+
const versionResult = await run(`${javaHome}/bin/java`, ["-version"], cwd, 5000, mavenEnv);
|
|
101
|
+
const versionOutput = versionResult.stdout + versionResult.stderr;
|
|
102
|
+
const match = versionOutput.match(/version "(\d+)/);
|
|
103
|
+
if (match) javaVersion = parseInt(match[1]);
|
|
104
|
+
console.log(`[BUILD] Detected Java version: ${javaVersion}`);
|
|
105
|
+
} catch {}
|
|
106
|
+
|
|
107
|
+
// 3. Patch pom.xml dynamically based on what's in it
|
|
108
|
+
const pomPath = path2.join(cwd, "pom.xml");
|
|
109
|
+
const javaCompatFlags = [];
|
|
110
|
+
if (fs2.existsSync(pomPath)) {
|
|
111
|
+
try {
|
|
112
|
+
let pomContent = fs2.readFileSync(pomPath, "utf8");
|
|
113
|
+
let patched = pomContent;
|
|
114
|
+
|
|
115
|
+
// Detect configured java version in pom
|
|
116
|
+
const javaVersionMatch = pomContent.match(/<java\.version>(\d+)<\/java\.version>/);
|
|
117
|
+
const pomJavaVersion = javaVersionMatch ? parseInt(javaVersionMatch[1]) : javaVersion;
|
|
118
|
+
console.log(`[BUILD] pom.xml java.version=${pomJavaVersion}`);
|
|
119
|
+
|
|
120
|
+
// Detect maven-compiler-plugin version
|
|
121
|
+
const compilerVersionMatch = pomContent.match(/<artifactId>maven-compiler-plugin<\/artifactId>\s*<version>([^<]+)<\/version>/);
|
|
122
|
+
const compilerVersion = compilerVersionMatch ? compilerVersionMatch[1] : "unknown";
|
|
123
|
+
console.log(`[BUILD] maven-compiler-plugin version=${compilerVersion}`);
|
|
124
|
+
|
|
125
|
+
// If compiler plugin < 3.10 and java >= 17: upgrade to 3.11.0
|
|
126
|
+
// (3.8.x uses plexus-compiler-javac 2.8.4 which doesn't support --release 17)
|
|
127
|
+
const [compMajor, compMinor] = compilerVersion.split(".").map(Number);
|
|
128
|
+
if (!isNaN(compMajor) && (compMajor < 3 || (compMajor === 3 && compMinor < 10)) && pomJavaVersion >= 17) {
|
|
129
|
+
patched = patched.replace(
|
|
130
|
+
new RegExp("(<artifactId>maven-compiler-plugin<\/artifactId>\\s*<version>)[^<]+(<\/version>)"),
|
|
131
|
+
"$1" + "3.11.0" + "$2"
|
|
132
|
+
);
|
|
133
|
+
console.log(`[BUILD] Patched: maven-compiler-plugin ${compilerVersion} -> 3.11.0`);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// If pom uses <release> tag that might fail, replace with <source>/<target>
|
|
137
|
+
if (pomContent.includes("<release>") && pomJavaVersion >= 17) {
|
|
138
|
+
patched = patched.replace(
|
|
139
|
+
/<release>\d+<\/release>/g,
|
|
140
|
+
`<source>${pomJavaVersion}</source>
|
|
141
|
+
<target>${pomJavaVersion}</target>`
|
|
142
|
+
);
|
|
143
|
+
console.log(`[BUILD] Patched: replaced <release> with <source>/<target> for Java ${pomJavaVersion}`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (patched !== pomContent) {
|
|
147
|
+
fs2.writeFileSync(pomPath, patched, "utf8");
|
|
148
|
+
console.log("[BUILD] pom.xml patched successfully");
|
|
149
|
+
} else {
|
|
150
|
+
console.log("[BUILD] pom.xml no patches needed");
|
|
151
|
+
}
|
|
152
|
+
} catch (patchErr) {
|
|
153
|
+
console.warn("[BUILD] Could not patch pom.xml:", patchErr.message);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
58
157
|
const args = skipTests
|
|
59
|
-
? ["
|
|
60
|
-
: ["
|
|
158
|
+
? ["compile", "-DskipTests", ...javaCompatFlags]
|
|
159
|
+
: ["test", ...javaCompatFlags];
|
|
61
160
|
|
|
62
|
-
console.log(
|
|
63
|
-
result = await run(
|
|
161
|
+
console.log(`[BUILD] [COMPILE] Running: ${mvnCmd} ${args.join(" ")}`);
|
|
162
|
+
result = await run(mvnCmd, args, cwd, 10 * 60 * 1000, mavenEnv);
|
|
163
|
+
if (result.code !== 0) {
|
|
164
|
+
console.error("[ERR] [COMPILE] stdout:", result.stdout.substring(0, 2000));
|
|
165
|
+
console.error("[ERR] [COMPILE] stderr:", result.stderr.substring(0, 2000));
|
|
166
|
+
}
|
|
64
167
|
}
|
|
65
168
|
else if (language === "java" && buildTool === "gradle") {
|
|
66
169
|
// Gradle: clean build
|
|
@@ -68,12 +171,12 @@ export async function compileAndTest({ language, buildTool, cwd, skipTests = fal
|
|
|
68
171
|
? ["clean", "build", "-x", "test"]
|
|
69
172
|
: ["clean", "build"];
|
|
70
173
|
|
|
71
|
-
console.log(
|
|
174
|
+
console.log(`[BUILD] [COMPILE] Running: ./gradlew ${args.join(" ")}`);
|
|
72
175
|
result = await run("./gradlew", args, cwd);
|
|
73
176
|
}
|
|
74
177
|
else if (language === "node" || buildTool === "npm") {
|
|
75
178
|
// Node/npm: install and optionally test
|
|
76
|
-
console.log(
|
|
179
|
+
console.log(`[BUILD] [COMPILE] Running: npm install`);
|
|
77
180
|
const installResult = await run("npm", ["install", "--silent"], cwd);
|
|
78
181
|
|
|
79
182
|
if (installResult.code !== 0) {
|
|
@@ -81,7 +184,7 @@ export async function compileAndTest({ language, buildTool, cwd, skipTests = fal
|
|
|
81
184
|
}
|
|
82
185
|
|
|
83
186
|
if (!skipTests) {
|
|
84
|
-
console.log(
|
|
187
|
+
console.log(`[BUILD] [COMPILE] Running: npm test`);
|
|
85
188
|
result = await run("npm", ["test", "--silent"], cwd);
|
|
86
189
|
} else {
|
|
87
190
|
result = installResult;
|
|
@@ -89,7 +192,7 @@ export async function compileAndTest({ language, buildTool, cwd, skipTests = fal
|
|
|
89
192
|
}
|
|
90
193
|
else if (language === "node" || buildTool === "yarn") {
|
|
91
194
|
// Yarn
|
|
92
|
-
console.log(
|
|
195
|
+
console.log(`[BUILD] [COMPILE] Running: yarn install`);
|
|
93
196
|
const installResult = await run("yarn", ["install", "--silent"], cwd);
|
|
94
197
|
|
|
95
198
|
if (installResult.code !== 0) {
|
|
@@ -97,7 +200,7 @@ export async function compileAndTest({ language, buildTool, cwd, skipTests = fal
|
|
|
97
200
|
}
|
|
98
201
|
|
|
99
202
|
if (!skipTests) {
|
|
100
|
-
console.log(
|
|
203
|
+
console.log(`[BUILD] [COMPILE] Running: yarn test`);
|
|
101
204
|
result = await run("yarn", ["test", "--silent"], cwd);
|
|
102
205
|
} else {
|
|
103
206
|
result = installResult;
|
|
@@ -106,7 +209,7 @@ export async function compileAndTest({ language, buildTool, cwd, skipTests = fal
|
|
|
106
209
|
else if (language === "python") {
|
|
107
210
|
// Python: pytest
|
|
108
211
|
if (!skipTests) {
|
|
109
|
-
console.log(
|
|
212
|
+
console.log(`[BUILD] [COMPILE] Running: pytest`);
|
|
110
213
|
result = await run("pytest", [], cwd);
|
|
111
214
|
} else {
|
|
112
215
|
// Python doesn't have a compile step, just return success
|
|
@@ -115,7 +218,7 @@ export async function compileAndTest({ language, buildTool, cwd, skipTests = fal
|
|
|
115
218
|
}
|
|
116
219
|
else if (language === "go") {
|
|
117
220
|
// Go: build and optionally test
|
|
118
|
-
console.log(
|
|
221
|
+
console.log(`[BUILD] [COMPILE] Running: go build ./...`);
|
|
119
222
|
const buildResult = await run("go", ["build", "./..."], cwd);
|
|
120
223
|
|
|
121
224
|
if (buildResult.code !== 0) {
|
|
@@ -123,7 +226,7 @@ export async function compileAndTest({ language, buildTool, cwd, skipTests = fal
|
|
|
123
226
|
}
|
|
124
227
|
|
|
125
228
|
if (!skipTests) {
|
|
126
|
-
console.log(
|
|
229
|
+
console.log(`[BUILD] [COMPILE] Running: go test ./...`);
|
|
127
230
|
result = await run("go", ["test", "./..."], cwd);
|
|
128
231
|
} else {
|
|
129
232
|
result = buildResult;
|
|
@@ -131,7 +234,7 @@ export async function compileAndTest({ language, buildTool, cwd, skipTests = fal
|
|
|
131
234
|
}
|
|
132
235
|
else if (language === ".net" || language === "dotnet") {
|
|
133
236
|
// .NET: build and optionally test
|
|
134
|
-
console.log(
|
|
237
|
+
console.log(`[BUILD] [COMPILE] Running: dotnet build`);
|
|
135
238
|
const buildResult = await run("dotnet", ["build"], cwd);
|
|
136
239
|
|
|
137
240
|
if (buildResult.code !== 0) {
|
|
@@ -139,14 +242,14 @@ export async function compileAndTest({ language, buildTool, cwd, skipTests = fal
|
|
|
139
242
|
}
|
|
140
243
|
|
|
141
244
|
if (!skipTests) {
|
|
142
|
-
console.log(
|
|
245
|
+
console.log(`[BUILD] [COMPILE] Running: dotnet test`);
|
|
143
246
|
result = await run("dotnet", ["test"], cwd);
|
|
144
247
|
} else {
|
|
145
248
|
result = buildResult;
|
|
146
249
|
}
|
|
147
250
|
}
|
|
148
251
|
else {
|
|
149
|
-
console.error(
|
|
252
|
+
console.error(`[ERR] [COMPILE] Unsupported: ${language}/${buildTool}`);
|
|
150
253
|
return {
|
|
151
254
|
code: 1,
|
|
152
255
|
stdout: "",
|
|
@@ -157,18 +260,18 @@ export async function compileAndTest({ language, buildTool, cwd, skipTests = fal
|
|
|
157
260
|
|
|
158
261
|
// Log result
|
|
159
262
|
if (result.code === 0) {
|
|
160
|
-
console.log(
|
|
263
|
+
console.log(`[OK] [COMPILE] Success in ${result.duration}ms`);
|
|
161
264
|
} else {
|
|
162
|
-
console.error(
|
|
265
|
+
console.error(`[ERR] [COMPILE] Failed with code ${result.code}`);
|
|
163
266
|
if (result.stderr) {
|
|
164
|
-
console.error(
|
|
267
|
+
console.error(`[ERR] [COMPILE] Error: ${result.stderr.substring(0, 500)}`);
|
|
165
268
|
}
|
|
166
269
|
}
|
|
167
270
|
|
|
168
271
|
return result;
|
|
169
272
|
|
|
170
273
|
} catch (err) {
|
|
171
|
-
console.error(
|
|
274
|
+
console.error(`[ERR] [COMPILE] Exception: ${err.message}`);
|
|
172
275
|
return {
|
|
173
276
|
code: 1,
|
|
174
277
|
stdout: "",
|