Skip to content

Commit e4e9d51

Browse files
authored
Merge pull request #132 from rostilos/1.5.0-rc
1.5.0 rc
2 parents d8e875a + 7e61c5e commit e4e9d51

151 files changed

Lines changed: 15032 additions & 2336 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ High level components:
4545
---
4646

4747
## Contributing
48-
4948
Contributions are welcome. Please see our [Development Guide](https://codecrow.app/docs/developer/dev-setup) for more information.
5049

5150
## License
46.5 MB
Binary file not shown.

deployment/docker-compose-sample-new-relic.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,6 @@ services:
215215
- codecrow-network
216216
volumes:
217217
- web_frontend_logs:/app/logs
218-
- ./config/web-frontend/.env:/app/.env
219-
command:
220-
["sh", "-c", "serve -s dist -l 8080 >> /app/logs/web-frontend.log 2>&1"]
221218
restart: unless-stopped
222219

223220
fix-permissions:

deployment/docker-compose-sample.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,6 @@ services:
232232
- codecrow-network
233233
volumes:
234234
- web_frontend_logs:/app/logs
235-
- ./config/web-frontend/.env:/app/.env
236-
command:
237-
["sh", "-c", "serve -s dist -l 8080 >> /app/logs/web-frontend.log 2>&1"]
238235
restart: unless-stopped
239236

240237
fix-permissions:

frontend

Submodule frontend updated 35 files

java-ecosystem/libs/analysis-engine/src/main/java/module-info.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
exports org.rostilos.codecrow.analysisengine.processor;
3131
exports org.rostilos.codecrow.analysisengine.processor.analysis;
3232
exports org.rostilos.codecrow.analysisengine.service;
33+
exports org.rostilos.codecrow.analysisengine.service.gitgraph;
3334
exports org.rostilos.codecrow.analysisengine.service.rag;
3435
exports org.rostilos.codecrow.analysisengine.service.vcs;
3536
exports org.rostilos.codecrow.analysisengine.util;
@@ -39,6 +40,7 @@
3940
opens org.rostilos.codecrow.analysisengine.processor to spring.core, spring.beans, spring.context;
4041
opens org.rostilos.codecrow.analysisengine.processor.analysis to spring.core, spring.beans, spring.context;
4142
opens org.rostilos.codecrow.analysisengine.service to spring.core, spring.beans, spring.context;
43+
opens org.rostilos.codecrow.analysisengine.service.gitgraph to spring.core, spring.beans, spring.context;
4244
opens org.rostilos.codecrow.analysisengine.service.rag to spring.core, spring.beans, spring.context;
4345
opens org.rostilos.codecrow.analysisengine.service.vcs to spring.core, spring.beans, spring.context;
4446
}

java-ecosystem/libs/analysis-engine/src/main/java/org/rostilos/codecrow/analysisengine/dto/request/ai/AiAnalysisRequest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.rostilos.codecrow.core.model.codeanalysis.AnalysisMode;
55
import org.rostilos.codecrow.core.model.codeanalysis.AnalysisType;
66
import java.util.List;
7+
import java.util.Map;
78

89
public interface AiAnalysisRequest {
910
Long getProjectId();
@@ -55,4 +56,12 @@ public interface AiAnalysisRequest {
5556
String getPreviousCommitHash();
5657

5758
String getCurrentCommitHash();
59+
60+
/**
61+
* File contents pre-fetched by Java for MCP-free reconciliation.
62+
* Map of filePath → full file content. When non-null and non-empty,
63+
* Python will use these directly instead of spawning an MCP agent to
64+
* fetch files via VCS tool calls.
65+
*/
66+
default Map<String, String> getReconciliationFileContents() { return null; }
5867
}

java-ecosystem/libs/analysis-engine/src/main/java/org/rostilos/codecrow/analysisengine/dto/request/ai/AiAnalysisRequestImpl.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.rostilos.codecrow.core.model.project.ProjectVcsConnectionBinding;
1111

1212
import java.util.List;
13+
import java.util.Map;
1314
import java.util.Optional;
1415

1516
public class AiAnalysisRequestImpl implements AiAnalysisRequest {
@@ -54,6 +55,9 @@ public class AiAnalysisRequestImpl implements AiAnalysisRequest {
5455
// Custom project review rules (JSON-serializable list)
5556
protected final String projectRules;
5657

58+
// Pre-fetched file contents for MCP-free branch reconciliation
59+
protected final Map<String, String> reconciliationFileContents;
60+
5761
protected AiAnalysisRequestImpl(Builder<?> builder) {
5862
this.projectId = builder.projectId;
5963
this.projectVcsWorkspace = builder.projectVcsWorkspace;
@@ -89,6 +93,8 @@ protected AiAnalysisRequestImpl(Builder<?> builder) {
8993
this.enrichmentData = builder.enrichmentData;
9094
// Custom project review rules
9195
this.projectRules = builder.projectRules;
96+
// Pre-fetched file contents for MCP-free reconciliation
97+
this.reconciliationFileContents = builder.reconciliationFileContents;
9298
}
9399

94100
public Long getProjectId() {
@@ -210,6 +216,11 @@ public String getProjectRules() {
210216
return projectRules;
211217
}
212218

219+
@Override
220+
public Map<String, String> getReconciliationFileContents() {
221+
return reconciliationFileContents;
222+
}
223+
213224
public static Builder<?> builder() {
214225
return new Builder<>();
215226
}
@@ -250,6 +261,8 @@ public static class Builder<T extends Builder<T>> {
250261
private PrEnrichmentDataDto enrichmentData;
251262
// Custom project review rules (JSON string)
252263
private String projectRules;
264+
// Pre-fetched file contents for MCP-free reconciliation
265+
private Map<String, String> reconciliationFileContents;
253266

254267
protected Builder() {
255268
}
@@ -311,6 +324,18 @@ public T withPreviousAnalysisData(Optional<CodeAnalysis> optionalPreviousAnalysi
311324
return self();
312325
}
313326

327+
/**
328+
* Sets previous issues directly from pre-built DTOs.
329+
* Used when the caller already has the DTOs (e.g., built from BranchIssue data
330+
* via {@link AiRequestPreviousIssueDTO#fromBranchIssue}) and no entity-to-DTO
331+
* conversion is needed. This avoids lazy-initialization issues that occur when
332+
* CodeAnalysisIssue proxies are accessed outside a Hibernate session.
333+
*/
334+
public T withPreviousIssues(List<AiRequestPreviousIssueDTO> issues) {
335+
this.previousCodeAnalysisIssues = issues;
336+
return self();
337+
}
338+
314339
/**
315340
* Set previous issues from ALL PR analysis versions.
316341
* This provides the LLM with complete issue history including resolved issues,
@@ -409,6 +434,7 @@ private AiRequestPreviousIssueDTO mergeResolvedStatus(
409434
newer.id(),
410435
newer.type(),
411436
newer.severity(),
437+
newer.title(),
412438
newer.reason(),
413439
newer.suggestedFixDescription(),
414440
newer.suggestedFixDiff(),
@@ -421,7 +447,8 @@ private AiRequestPreviousIssueDTO mergeResolvedStatus(
421447
newer.prVersion(),
422448
resolvedOlder.resolvedDescription(),
423449
resolvedOlder.resolvedByCommit(),
424-
resolvedOlder.resolvedInAnalysisId());
450+
resolvedOlder.resolvedInAnalysisId(),
451+
newer.codeSnippet());
425452
}
426453

427454
public T withMaxAllowedTokens(int maxAllowedTokens) {
@@ -520,6 +547,11 @@ public T withProjectRules(String projectRules) {
520547
return self();
521548
}
522549

550+
public T withReconciliationFileContents(Map<String, String> reconciliationFileContents) {
551+
this.reconciliationFileContents = reconciliationFileContents;
552+
return self();
553+
}
554+
523555
public AiAnalysisRequestImpl build() {
524556
return new AiAnalysisRequestImpl(this);
525557
}

java-ecosystem/libs/analysis-engine/src/main/java/org/rostilos/codecrow/analysisengine/dto/request/ai/AiRequestPreviousIssueDTO.java

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package org.rostilos.codecrow.analysisengine.dto.request.ai;
22

3+
import org.rostilos.codecrow.core.model.branch.BranchIssue;
34
import org.rostilos.codecrow.core.model.codeanalysis.CodeAnalysisIssue;
45
import org.rostilos.codecrow.core.model.codeanalysis.IssueCategory;
56

67
public record AiRequestPreviousIssueDTO(
78
String id,
89
String type, // security|quality|performance|style
910
String severity, // critical|high|medium|low|info
11+
String title,
1012
String reason,
1113
String suggestedFixDescription,
1214
String suggestedFixDiff,
@@ -20,7 +22,9 @@ public record AiRequestPreviousIssueDTO(
2022
Integer prVersion, // Which PR iteration this issue was found in
2123
String resolvedDescription, // Description of how the issue was resolved
2224
String resolvedByCommit, // Commit hash that resolved the issue
23-
Long resolvedInAnalysisId // Analysis ID where this was resolved (null if still open)
25+
Long resolvedInAnalysisId, // Analysis ID where this was resolved (null if still open)
26+
// Content-based anchoring
27+
String codeSnippet // Verbatim source line for line anchoring — Python passes back, Java re-resolves
2428
) {
2529
public static AiRequestPreviousIssueDTO fromEntity(CodeAnalysisIssue issue) {
2630
String categoryStr = issue.getIssueCategory() != null
@@ -36,6 +40,7 @@ public static AiRequestPreviousIssueDTO fromEntity(CodeAnalysisIssue issue) {
3640
String.valueOf(issue.getId()),
3741
categoryStr,
3842
issue.getSeverity() != null ? issue.getSeverity().name() : null,
43+
issue.getTitle(),
3944
issue.getReason(),
4045
issue.getSuggestedFixDescription(),
4146
issue.getSuggestedFixDiff(),
@@ -48,7 +53,58 @@ public static AiRequestPreviousIssueDTO fromEntity(CodeAnalysisIssue issue) {
4853
prVersion,
4954
issue.getResolvedDescription(),
5055
issue.getResolvedCommitHash(),
51-
issue.getResolvedAnalysisId()
56+
issue.getResolvedAnalysisId(),
57+
issue.getCodeSnippet()
58+
);
59+
}
60+
61+
/**
62+
* Factory method that reads all data from a BranchIssue's own fields.
63+
* Used for AI reconciliation of branch-level issues.
64+
* The BranchIssue is a fully independent entity — no CodeAnalysisIssue dereference needed.
65+
*
66+
* <p><b>ID handling:</b> The {@code id} field is set to the origin
67+
* {@link CodeAnalysisIssue} ID when available, because
68+
* {@code processReconciledIssue()} looks up the BranchIssue via
69+
* {@code findByBranchIdAndOriginIssueId(branchId, id)}. If there is no
70+
* origin issue (e.g. the BranchIssue was created directly), we fall back to
71+
* the BranchIssue's own PK.
72+
*/
73+
public static AiRequestPreviousIssueDTO fromBranchIssue(BranchIssue bi) {
74+
String categoryStr = bi.getIssueCategory() != null
75+
? bi.getIssueCategory().name()
76+
: IssueCategory.CODE_QUALITY.name();
77+
78+
// Use the reconciled line number if available
79+
Integer lineNumber = bi.getCurrentLineNumber() != null
80+
? bi.getCurrentLineNumber() : bi.getLineNumber();
81+
82+
// Use origin issue ID so processReconciledIssue() can look up by
83+
// findByBranchIdAndOriginIssueId. Hibernate allows getId() on a
84+
// lazy proxy without triggering full initialization.
85+
String issueId = bi.getOriginIssue() != null
86+
? String.valueOf(bi.getOriginIssue().getId())
87+
: String.valueOf(bi.getId());
88+
89+
return new AiRequestPreviousIssueDTO(
90+
issueId,
91+
categoryStr,
92+
bi.getSeverity() != null ? bi.getSeverity().name() : null,
93+
bi.getTitle(),
94+
bi.getReason(),
95+
bi.getSuggestedFixDescription(),
96+
bi.getSuggestedFixDiff(),
97+
bi.getFilePath(),
98+
lineNumber,
99+
bi.getOriginBranchName(),
100+
bi.getOriginPrNumber() != null ? String.valueOf(bi.getOriginPrNumber()) : null,
101+
bi.isResolved() ? "resolved" : "open",
102+
categoryStr,
103+
null, // prVersion — not applicable for branch issues
104+
bi.getResolvedDescription(),
105+
bi.getResolvedInCommitHash(),
106+
bi.getOriginAnalysisId(), // resolvedInAnalysisId → use origin for provenance
107+
bi.getCodeSnippet()
52108
);
53109
}
54110
}

0 commit comments

Comments
 (0)