deepdebug-local-agent 1.0.19 → 1.0.21

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/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 child = spawn(cmd, args, { cwd, shell: true });
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(() => {
@@ -54,31 +56,117 @@ export async function compileAndTest({ language, buildTool, cwd, skipTests = fal
54
56
 
55
57
  try {
56
58
  if (language === "java" && buildTool === "maven") {
57
- // Prefer ./mvnw wrapper over system mvn
59
+ // Prefer system mvn (installed in Docker), fallback to ./mvnw
58
60
  const fs = await import("fs");
59
61
  const path = await import("path");
62
+ const checkMvn = await run("which", ["mvn"], cwd, 5000);
60
63
  const hasMvnw = fs.existsSync(path.join(cwd, "mvnw"));
61
- const mvnCmd = hasMvnw ? "./mvnw" : "mvn";
62
-
63
- // Verify build tool is available before attempting
64
- if (!hasMvnw) {
65
- const check = await run("which mvn", [], cwd);
66
- if (check.code !== 0) {
67
- return {
68
- code: 1,
69
- stdout: "",
70
- stderr: "Maven not found: neither ./mvnw nor mvn is available in this environment.",
71
- duration: Date.now() - start
72
- };
64
+ let mvnCmd;
65
+ if (checkMvn.code === 0) {
66
+ mvnCmd = "mvn"; // system Maven (always works, no permission issues)
67
+ } else if (hasMvnw) {
68
+ // Fix permission on NFS-mounted mvnw
69
+ await run("chmod", ["+x", path.join(cwd, "mvnw")], cwd, 5000);
70
+ mvnCmd = "./mvnw";
71
+ } else {
72
+ return {
73
+ code: 1,
74
+ stdout: "",
75
+ stderr: "Maven not found: neither mvn nor ./mvnw is available.",
76
+ duration: Date.now() - start
77
+ };
78
+ }
79
+
80
+ // Fix for maven-compiler-plugin 3.8.1 + Java 17:
81
+ // plexus-compiler-javac 2.8.4 does not support --release 17.
82
+ // Workaround: disable the --release flag entirely and use -source/-target instead.
83
+ // Also pass JAVA_HOME explicitly so mvnw uses the correct JDK.
84
+ // Dynamically prepare Maven environment and fix common Java version issues
85
+ const fs2 = await import("fs");
86
+ const path2 = await import("path");
87
+
88
+ // 1. Detect Java version available
89
+ const javaHome = process.env.JAVA_HOME || "/usr/local/java-home";
90
+ const javacPath = `${javaHome}/bin/javac`;
91
+ const hasJavac = fs2.existsSync(javacPath);
92
+ const mavenEnv = {
93
+ ...process.env,
94
+ JAVA_HOME: javaHome,
95
+ PATH: `${javaHome}/bin:${process.env.PATH}`
96
+ };
97
+ console.log(`[BUILD] JAVA_HOME=${javaHome}, javac available=${hasJavac}`);
98
+
99
+ // 2. Detect Java version from javac
100
+ let javaVersion = 11; // default fallback
101
+ try {
102
+ const versionResult = await run(`${javaHome}/bin/java`, ["-version"], cwd, 5000, mavenEnv);
103
+ const versionOutput = versionResult.stdout + versionResult.stderr;
104
+ const match = versionOutput.match(/version "(\d+)/);
105
+ if (match) javaVersion = parseInt(match[1]);
106
+ console.log(`[BUILD] Detected Java version: ${javaVersion}`);
107
+ } catch {}
108
+
109
+ // 3. Patch pom.xml dynamically based on what's in it
110
+ const pomPath = path2.join(cwd, "pom.xml");
111
+ const javaCompatFlags = [];
112
+ if (fs2.existsSync(pomPath)) {
113
+ try {
114
+ let pomContent = fs2.readFileSync(pomPath, "utf8");
115
+ let patched = pomContent;
116
+
117
+ // Detect configured java version in pom
118
+ const javaVersionMatch = pomContent.match(/<java\.version>(\d+)<\/java\.version>/);
119
+ const pomJavaVersion = javaVersionMatch ? parseInt(javaVersionMatch[1]) : javaVersion;
120
+ console.log(`[BUILD] pom.xml java.version=${pomJavaVersion}`);
121
+
122
+ // Detect maven-compiler-plugin version
123
+ const compilerVersionMatch = pomContent.match(/<artifactId>maven-compiler-plugin<\/artifactId>\s*<version>([^<]+)<\/version>/);
124
+ const compilerVersion = compilerVersionMatch ? compilerVersionMatch[1] : "unknown";
125
+ console.log(`[BUILD] maven-compiler-plugin version=${compilerVersion}`);
126
+
127
+ // If compiler plugin < 3.10 and java >= 17: upgrade to 3.11.0
128
+ // (3.8.x uses plexus-compiler-javac 2.8.4 which doesn't support --release 17)
129
+ const [compMajor, compMinor] = compilerVersion.split(".").map(Number);
130
+ if (!isNaN(compMajor) && (compMajor < 3 || (compMajor === 3 && compMinor < 10)) && pomJavaVersion >= 17) {
131
+ patched = patched.replace(
132
+ new RegExp("(<artifactId>maven-compiler-plugin<\/artifactId>\\s*<version>)[^<]+(<\/version>)"),
133
+ "$1" + "3.11.0" + "$2"
134
+ );
135
+ console.log(`[BUILD] Patched: maven-compiler-plugin ${compilerVersion} -> 3.11.0`);
136
+ }
137
+
138
+ // If pom uses <release> tag that might fail, replace with <source>/<target>
139
+ if (pomContent.includes("<release>") && pomJavaVersion >= 17) {
140
+ patched = patched.replace(
141
+ /<release>\d+<\/release>/g,
142
+ `<source>${pomJavaVersion}</source>
143
+ <target>${pomJavaVersion}</target>`
144
+ );
145
+ console.log(`[BUILD] Patched: replaced <release> with <source>/<target> for Java ${pomJavaVersion}`);
146
+ }
147
+
148
+ if (patched !== pomContent) {
149
+ fs2.writeFileSync(pomPath, patched, "utf8");
150
+ console.log("[BUILD] pom.xml patched successfully");
151
+ } else {
152
+ console.log("[BUILD] pom.xml no patches needed");
153
+ }
154
+ } catch (patchErr) {
155
+ console.warn("[BUILD] Could not patch pom.xml:", patchErr.message);
73
156
  }
74
157
  }
75
158
 
159
+ // -e flag shows full error stack traces from Maven
76
160
  const args = skipTests
77
- ? ["compile", "-q", "-DskipTests"]
78
- : ["test", "-q"];
161
+ ? ["compile", "-DskipTests", "-e", ...javaCompatFlags]
162
+ : ["test", "-e", ...javaCompatFlags];
79
163
 
80
164
  console.log(`[BUILD] [COMPILE] Running: ${mvnCmd} ${args.join(" ")}`);
81
- result = await run(mvnCmd, args, cwd);
165
+ result = await run(mvnCmd, args, cwd, 10 * 60 * 1000, mavenEnv);
166
+ if (result.code !== 0) {
167
+ console.error("[ERR] [COMPILE] stdout:", result.stdout.substring(0, 2000));
168
+ console.error("[ERR] [COMPILE] stderr:", result.stderr.substring(0, 2000));
169
+ }
82
170
  }
83
171
  else if (language === "java" && buildTool === "gradle") {
84
172
  // Gradle: clean build
Binary file
@@ -121,9 +121,10 @@ export class MavenRuntime extends BaseRuntime {
121
121
 
122
122
  async build(workspacePath, options = {}) {
123
123
  const startTime = Date.now();
124
- const skipTests = options.skipTests ? '-DskipTests' : '';
125
- const args = ['compile', '-q'];
126
- if (skipTests) args.push(skipTests);
124
+ const skipTests = options.skipTests !== false;
125
+ // No -q flag: compilation errors must be visible to the AI agent
126
+ const args = ['compile', '-e'];
127
+ if (skipTests) args.push('-DskipTests');
127
128
 
128
129
  const result = await run('mvn', args, workspacePath);
129
130