@wickdninja/sweny-engine 0.1.0
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/README.md +75 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/recipes/triage/index.d.ts +7 -0
- package/dist/recipes/triage/index.d.ts.map +1 -0
- package/dist/recipes/triage/index.js +30 -0
- package/dist/recipes/triage/index.js.map +1 -0
- package/dist/recipes/triage/prompts.d.ts +6 -0
- package/dist/recipes/triage/prompts.d.ts.map +1 -0
- package/dist/recipes/triage/prompts.js +279 -0
- package/dist/recipes/triage/prompts.js.map +1 -0
- package/dist/recipes/triage/results.d.ts +14 -0
- package/dist/recipes/triage/results.d.ts.map +1 -0
- package/dist/recipes/triage/results.js +14 -0
- package/dist/recipes/triage/results.js.map +1 -0
- package/dist/recipes/triage/service-map.d.ts +15 -0
- package/dist/recipes/triage/service-map.d.ts.map +1 -0
- package/dist/recipes/triage/service-map.js +56 -0
- package/dist/recipes/triage/service-map.js.map +1 -0
- package/dist/recipes/triage/steps/build-context.d.ts +5 -0
- package/dist/recipes/triage/steps/build-context.d.ts.map +1 -0
- package/dist/recipes/triage/steps/build-context.js +85 -0
- package/dist/recipes/triage/steps/build-context.js.map +1 -0
- package/dist/recipes/triage/steps/create-issue.d.ts +5 -0
- package/dist/recipes/triage/steps/create-issue.d.ts.map +1 -0
- package/dist/recipes/triage/steps/create-issue.js +85 -0
- package/dist/recipes/triage/steps/create-issue.js.map +1 -0
- package/dist/recipes/triage/steps/create-pr.d.ts +5 -0
- package/dist/recipes/triage/steps/create-pr.d.ts.map +1 -0
- package/dist/recipes/triage/steps/create-pr.js +97 -0
- package/dist/recipes/triage/steps/create-pr.js.map +1 -0
- package/dist/recipes/triage/steps/cross-repo-check.d.ts +5 -0
- package/dist/recipes/triage/steps/cross-repo-check.d.ts.map +1 -0
- package/dist/recipes/triage/steps/cross-repo-check.js +44 -0
- package/dist/recipes/triage/steps/cross-repo-check.js.map +1 -0
- package/dist/recipes/triage/steps/implement-fix.d.ts +5 -0
- package/dist/recipes/triage/steps/implement-fix.d.ts.map +1 -0
- package/dist/recipes/triage/steps/implement-fix.js +100 -0
- package/dist/recipes/triage/steps/implement-fix.js.map +1 -0
- package/dist/recipes/triage/steps/investigate.d.ts +5 -0
- package/dist/recipes/triage/steps/investigate.d.ts.map +1 -0
- package/dist/recipes/triage/steps/investigate.js +74 -0
- package/dist/recipes/triage/steps/investigate.js.map +1 -0
- package/dist/recipes/triage/steps/notify.d.ts +5 -0
- package/dist/recipes/triage/steps/notify.d.ts.map +1 -0
- package/dist/recipes/triage/steps/notify.js +66 -0
- package/dist/recipes/triage/steps/notify.js.map +1 -0
- package/dist/recipes/triage/steps/novelty-gate.d.ts +5 -0
- package/dist/recipes/triage/steps/novelty-gate.d.ts.map +1 -0
- package/dist/recipes/triage/steps/novelty-gate.js +60 -0
- package/dist/recipes/triage/steps/novelty-gate.js.map +1 -0
- package/dist/recipes/triage/steps/verify-access.d.ts +5 -0
- package/dist/recipes/triage/steps/verify-access.d.ts.map +1 -0
- package/dist/recipes/triage/steps/verify-access.js +11 -0
- package/dist/recipes/triage/steps/verify-access.js.map +1 -0
- package/dist/recipes/triage/test-helpers.d.ts +17 -0
- package/dist/recipes/triage/test-helpers.d.ts.map +1 -0
- package/dist/recipes/triage/test-helpers.js +41 -0
- package/dist/recipes/triage/test-helpers.js.map +1 -0
- package/dist/recipes/triage/types.d.ts +79 -0
- package/dist/recipes/triage/types.d.ts.map +1 -0
- package/dist/recipes/triage/types.js +2 -0
- package/dist/recipes/triage/types.js.map +1 -0
- package/dist/registry.d.ts +4 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +19 -0
- package/dist/registry.js.map +1 -0
- package/dist/runner.d.ts +13 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +98 -0
- package/dist/runner.js.map +1 -0
- package/dist/types.d.ts +77 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-context.js","sourceRoot":"","sources":["../../../../src/recipes/triage/steps/build-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { StepResult, WorkflowContext } from "../../../types.js";
|
|
2
|
+
import type { TriageConfig } from "../types.js";
|
|
3
|
+
/** Extract issue title from best-candidate.md, then get-or-create an issue in the tracker. */
|
|
4
|
+
export declare function createIssue(ctx: WorkflowContext<TriageConfig>): Promise<StepResult>;
|
|
5
|
+
//# sourceMappingURL=create-issue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-issue.d.ts","sourceRoot":"","sources":["../../../../src/recipes/triage/steps/create-issue.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,8FAA8F;AAC9F,wBAAsB,WAAW,CAAC,GAAG,EAAE,eAAe,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAuFzF"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
/** Extract issue title from best-candidate.md, then get-or-create an issue in the tracker. */
|
|
3
|
+
export async function createIssue(ctx) {
|
|
4
|
+
const config = ctx.config;
|
|
5
|
+
const issueTracker = ctx.providers.get("issueTracker");
|
|
6
|
+
// -------------------------------------------------------------------------
|
|
7
|
+
// 1. Extract issue title from best-candidate.md
|
|
8
|
+
// -------------------------------------------------------------------------
|
|
9
|
+
let issueTitle = "SWEny Triage: Automated bug fix";
|
|
10
|
+
if (!config.issueOverride) {
|
|
11
|
+
const bestCandidatePath = ".github/triage-analysis/best-candidate.md";
|
|
12
|
+
if (fs.existsSync(bestCandidatePath)) {
|
|
13
|
+
const content = fs.readFileSync(bestCandidatePath, "utf-8");
|
|
14
|
+
const headingMatch = content.match(/^#\s+(.+)$/m);
|
|
15
|
+
if (headingMatch) {
|
|
16
|
+
issueTitle = headingMatch[1]
|
|
17
|
+
.replace(/`/g, "")
|
|
18
|
+
.replace(/^(Best\s+)?(Fix\s+)?(Candidate)(\s+Fix)?[:\s]*/i, "")
|
|
19
|
+
.trim()
|
|
20
|
+
.slice(0, 100);
|
|
21
|
+
}
|
|
22
|
+
if (!issueTitle) {
|
|
23
|
+
issueTitle = "SWEny Triage: Automated bug fix";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
ctx.logger.info(`Extracted title: ${issueTitle}`);
|
|
27
|
+
}
|
|
28
|
+
// -------------------------------------------------------------------------
|
|
29
|
+
// 2. Get or create issue
|
|
30
|
+
// -------------------------------------------------------------------------
|
|
31
|
+
let issue;
|
|
32
|
+
if (config.issueOverride) {
|
|
33
|
+
// User provided a specific issue
|
|
34
|
+
ctx.logger.info(`User provided issue: ${config.issueOverride}`);
|
|
35
|
+
issue = await issueTracker.getIssue(config.issueOverride);
|
|
36
|
+
ctx.logger.info(`Working on issue: ${issue.identifier} - ${issue.url}`);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// Search for existing issue or create new one
|
|
40
|
+
ctx.logger.info(`Searching for existing issues matching: ${issueTitle}`);
|
|
41
|
+
const searchResults = await issueTracker.searchIssues({
|
|
42
|
+
projectId: config.projectId,
|
|
43
|
+
query: issueTitle,
|
|
44
|
+
labels: [config.bugLabelId],
|
|
45
|
+
});
|
|
46
|
+
if (searchResults.length > 0) {
|
|
47
|
+
issue = searchResults[0];
|
|
48
|
+
const date = new Date().toISOString().split("T")[0];
|
|
49
|
+
await issueTracker.addComment(issue.id, `+1 detected on ${date}`);
|
|
50
|
+
ctx.logger.info(`Found existing issue: ${issue.identifier} - ${issue.url}`);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
ctx.logger.info("No existing issue found, creating new one...");
|
|
54
|
+
let description = "";
|
|
55
|
+
const bestCandidatePath = ".github/triage-analysis/best-candidate.md";
|
|
56
|
+
if (fs.existsSync(bestCandidatePath)) {
|
|
57
|
+
description = fs.readFileSync(bestCandidatePath, "utf-8").slice(0, 10000);
|
|
58
|
+
}
|
|
59
|
+
const labelIds = [config.bugLabelId];
|
|
60
|
+
if (config.triageLabelId) {
|
|
61
|
+
labelIds.push(config.triageLabelId);
|
|
62
|
+
}
|
|
63
|
+
issue = await issueTracker.createIssue({
|
|
64
|
+
title: issueTitle,
|
|
65
|
+
projectId: config.projectId,
|
|
66
|
+
labels: labelIds,
|
|
67
|
+
priority: 2,
|
|
68
|
+
stateId: config.stateBacklog,
|
|
69
|
+
description,
|
|
70
|
+
});
|
|
71
|
+
ctx.logger.info(`Created new issue: ${issue.identifier} - ${issue.url}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
status: "success",
|
|
76
|
+
data: {
|
|
77
|
+
issueId: issue.id,
|
|
78
|
+
issueIdentifier: issue.identifier,
|
|
79
|
+
issueTitle: issue.title || issueTitle,
|
|
80
|
+
issueUrl: issue.url,
|
|
81
|
+
issueBranchName: issue.branchName,
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=create-issue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-issue.js","sourceRoot":"","sources":["../../../../src/recipes/triage/steps/create-issue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { StepResult, WorkflowContext } from "../../../types.js";
|
|
2
|
+
import type { TriageConfig } from "../types.js";
|
|
3
|
+
/** Generate PR description with Claude, create PR, link to issue, update issue state. */
|
|
4
|
+
export declare function createPr(ctx: WorkflowContext<TriageConfig>): Promise<StepResult>;
|
|
5
|
+
//# sourceMappingURL=create-pr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-pr.d.ts","sourceRoot":"","sources":["../../../../src/recipes/triage/steps/create-pr.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD,yFAAyF;AACzF,wBAAsB,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAgGtF"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import { canLinkPr } from "@swenyai/providers/issue-tracking";
|
|
3
|
+
import { getStepData } from "../results.js";
|
|
4
|
+
import { buildPrDescriptionPrompt } from "../prompts.js";
|
|
5
|
+
/** Generate PR description with Claude, create PR, link to issue, update issue state. */
|
|
6
|
+
export async function createPr(ctx) {
|
|
7
|
+
const config = ctx.config;
|
|
8
|
+
const sourceControl = ctx.providers.get("sourceControl");
|
|
9
|
+
const issueTracker = ctx.providers.get("issueTracker");
|
|
10
|
+
const codingAgent = ctx.providers.get("codingAgent");
|
|
11
|
+
const issueData = getStepData(ctx, "create-issue");
|
|
12
|
+
const implementData = getStepData(ctx, "implement-fix");
|
|
13
|
+
// If implement-fix was skipped, we can't create a PR
|
|
14
|
+
const implementResult = ctx.results.get("implement-fix");
|
|
15
|
+
if (!implementResult || implementResult.status !== "success") {
|
|
16
|
+
return {
|
|
17
|
+
status: "skipped",
|
|
18
|
+
reason: implementResult?.reason ?? "No implementation to create PR for",
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const issueId = issueData?.issueId ?? "";
|
|
22
|
+
const issueIdentifier = issueData?.issueIdentifier ?? "";
|
|
23
|
+
const issueTitle = issueData?.issueTitle ?? "";
|
|
24
|
+
const issueUrl = issueData?.issueUrl ?? "";
|
|
25
|
+
const branchName = implementData?.branchName ?? "";
|
|
26
|
+
// -------------------------------------------------------------------------
|
|
27
|
+
// 1. Generate PR description with Claude
|
|
28
|
+
// -------------------------------------------------------------------------
|
|
29
|
+
const prDescPrompt = buildPrDescriptionPrompt(issueIdentifier, issueUrl);
|
|
30
|
+
await codingAgent.run({
|
|
31
|
+
prompt: prDescPrompt,
|
|
32
|
+
maxTurns: 10,
|
|
33
|
+
env: { ...config.agentEnv },
|
|
34
|
+
});
|
|
35
|
+
// -------------------------------------------------------------------------
|
|
36
|
+
// 2. Create Pull Request
|
|
37
|
+
// -------------------------------------------------------------------------
|
|
38
|
+
let prBody = "";
|
|
39
|
+
const prDescPath = ".github/triage-analysis/pr-description.md";
|
|
40
|
+
if (fs.existsSync(prDescPath)) {
|
|
41
|
+
prBody = fs.readFileSync(prDescPath, "utf-8");
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
prBody = `## Automated Fix from SWEny Triage
|
|
45
|
+
|
|
46
|
+
This PR contains an automated fix for an issue identified in production logs.
|
|
47
|
+
|
|
48
|
+
**Linear Issue**: [${issueIdentifier}](${issueUrl})
|
|
49
|
+
|
|
50
|
+
> Generated by SWEny Triage`;
|
|
51
|
+
}
|
|
52
|
+
const prTitle = `fix(${issueIdentifier}): ${issueTitle.toLowerCase()}`;
|
|
53
|
+
const pr = await sourceControl.createPullRequest({
|
|
54
|
+
title: prTitle,
|
|
55
|
+
body: prBody,
|
|
56
|
+
head: branchName,
|
|
57
|
+
base: "main",
|
|
58
|
+
labels: ["agent", "triage", "needs-review"],
|
|
59
|
+
});
|
|
60
|
+
ctx.logger.info(`Created PR #${pr.number}: ${pr.url}`);
|
|
61
|
+
// -------------------------------------------------------------------------
|
|
62
|
+
// 3. Link PR to issue
|
|
63
|
+
// -------------------------------------------------------------------------
|
|
64
|
+
if (issueId && canLinkPr(issueTracker)) {
|
|
65
|
+
try {
|
|
66
|
+
await issueTracker.linkPr(issueId, pr.url, pr.number);
|
|
67
|
+
ctx.logger.info(`PR #${pr.number} linked to ${issueIdentifier}`);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
ctx.logger.warn(`Failed to link PR to issue: ${err}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// -------------------------------------------------------------------------
|
|
74
|
+
// 4. Update issue state to Peer Review
|
|
75
|
+
// -------------------------------------------------------------------------
|
|
76
|
+
if (issueId) {
|
|
77
|
+
try {
|
|
78
|
+
await issueTracker.updateIssue(issueId, {
|
|
79
|
+
stateId: config.statePeerReview,
|
|
80
|
+
});
|
|
81
|
+
ctx.logger.info(`Updated ${issueIdentifier} to Peer Review`);
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
ctx.logger.warn(`Failed to update issue state: ${err}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
status: "success",
|
|
89
|
+
data: {
|
|
90
|
+
issueIdentifier,
|
|
91
|
+
issueUrl,
|
|
92
|
+
prUrl: pr.url,
|
|
93
|
+
prNumber: pr.number,
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=create-pr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-pr.js","sourceRoot":"","sources":["../../../../src/recipes/triage/steps/create-pr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { StepResult, WorkflowContext } from "../../../types.js";
|
|
2
|
+
import type { TriageConfig } from "../types.js";
|
|
3
|
+
/** If the bug belongs to a different repo, dispatch the workflow there and skip remaining act steps. */
|
|
4
|
+
export declare function crossRepoCheck(ctx: WorkflowContext<TriageConfig>): Promise<StepResult>;
|
|
5
|
+
//# sourceMappingURL=cross-repo-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cross-repo-check.d.ts","sourceRoot":"","sources":["../../../../src/recipes/triage/steps/cross-repo-check.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,wGAAwG;AACxG,wBAAsB,cAAc,CAAC,GAAG,EAAE,eAAe,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CA8C5F"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { getStepData } from "../results.js";
|
|
2
|
+
/** If the bug belongs to a different repo, dispatch the workflow there and skip remaining act steps. */
|
|
3
|
+
export async function crossRepoCheck(ctx) {
|
|
4
|
+
const config = ctx.config;
|
|
5
|
+
const sourceControl = ctx.providers.get("sourceControl");
|
|
6
|
+
const issueTracker = ctx.providers.get("issueTracker");
|
|
7
|
+
const investigation = getStepData(ctx, "investigate");
|
|
8
|
+
const issueData = getStepData(ctx, "create-issue");
|
|
9
|
+
const targetRepo = investigation?.targetRepo;
|
|
10
|
+
const currentRepo = config.repository;
|
|
11
|
+
if (!targetRepo || targetRepo === currentRepo) {
|
|
12
|
+
ctx.logger.info(`Bug belongs to this repo (${currentRepo}) — implementing locally`);
|
|
13
|
+
return { status: "success", data: { dispatched: false } };
|
|
14
|
+
}
|
|
15
|
+
// Cross-repo dispatch
|
|
16
|
+
ctx.logger.info(`Bug belongs to ${targetRepo} (current: ${currentRepo}) — dispatching cross-repo`);
|
|
17
|
+
try {
|
|
18
|
+
await sourceControl.dispatchWorkflow({
|
|
19
|
+
targetRepo,
|
|
20
|
+
workflow: "SWEny Triage",
|
|
21
|
+
inputs: {
|
|
22
|
+
linear_issue: issueData?.issueIdentifier ?? "",
|
|
23
|
+
dispatched_from: currentRepo,
|
|
24
|
+
novelty_mode: "false",
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
// Add comment noting the cross-repo handoff
|
|
28
|
+
if (issueData?.issueId) {
|
|
29
|
+
await issueTracker.updateIssue(issueData.issueId, {
|
|
30
|
+
comment: `Cross-repo dispatch: Discovered in \`${currentRepo}\`, dispatched to \`${targetRepo}\` for implementation.`,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
ctx.logger.warn(`Cross-repo dispatch failed: ${err}`);
|
|
36
|
+
}
|
|
37
|
+
// Skip remaining act steps — implementation happens in the target repo
|
|
38
|
+
ctx.skipPhase("act", `Cross-repo dispatch to ${targetRepo}`);
|
|
39
|
+
return {
|
|
40
|
+
status: "success",
|
|
41
|
+
data: { dispatched: true, targetRepo },
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=cross-repo-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cross-repo-check.js","sourceRoot":"","sources":["../../../../src/recipes/triage/steps/cross-repo-check.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,wGAAwG;AACxG,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAkC;IACrE,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAC1B,MAAM,aAAa,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAwB,eAAe,CAAC,CAAC;IAChF,MAAM,YAAY,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAwB,cAAc,CAAC,CAAC;IAC9E,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAEnD,MAAM,UAAU,GAAG,aAAa,EAAE,UAAU,CAAC;IAC7C,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;IAEtC,IAAI,CAAC,UAAU,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;QAC9C,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,6BAA6B,WAAW,0BAA0B,CAAC,CAAC;QACpF,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,CAAC;IAC5D,CAAC;IAED,sBAAsB;IACtB,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,UAAU,cAAc,WAAW,4BAA4B,CAAC,CAAC;IAEnG,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,gBAAgB,CAAC;YACnC,UAAU;YACV,QAAQ,EAAE,cAAc;YACxB,MAAM,EAAE;gBACN,YAAY,EAAE,SAAS,EAAE,eAAe,IAAI,EAAE;gBAC9C,eAAe,EAAE,WAAW;gBAC5B,YAAY,EAAE,OAAO;aACtB;SACF,CAAC,CAAC;QAEH,4CAA4C;QAC5C,IAAI,SAAS,EAAE,OAAO,EAAE,CAAC;YACvB,MAAM,YAAY,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,EAAE;gBAChD,OAAO,EAAE,wCAAwC,WAAW,uBAAuB,UAAU,wBAAwB;aACtH,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,uEAAuE;IACvE,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,0BAA0B,UAAU,EAAE,CAAC,CAAC;IAE7D,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE;KACvC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { StepResult, WorkflowContext } from "../../../types.js";
|
|
2
|
+
import type { TriageConfig } from "../types.js";
|
|
3
|
+
/** Create branch, run Claude to implement fix, check for changes, and push. */
|
|
4
|
+
export declare function implementFix(ctx: WorkflowContext<TriageConfig>): Promise<StepResult>;
|
|
5
|
+
//# sourceMappingURL=implement-fix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"implement-fix.d.ts","sourceRoot":"","sources":["../../../../src/recipes/triage/steps/implement-fix.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD,+EAA+E;AAC/E,wBAAsB,YAAY,CAAC,GAAG,EAAE,eAAe,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CA2G1F"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import { getStepData } from "../results.js";
|
|
3
|
+
import { buildImplementPrompt } from "../prompts.js";
|
|
4
|
+
/** Create branch, run Claude to implement fix, check for changes, and push. */
|
|
5
|
+
export async function implementFix(ctx) {
|
|
6
|
+
const config = ctx.config;
|
|
7
|
+
const sourceControl = ctx.providers.get("sourceControl");
|
|
8
|
+
const codingAgent = ctx.providers.get("codingAgent");
|
|
9
|
+
const issueData = getStepData(ctx, "create-issue");
|
|
10
|
+
const issueIdentifier = issueData?.issueIdentifier ?? "";
|
|
11
|
+
const issueBranchName = issueData?.issueBranchName;
|
|
12
|
+
// -------------------------------------------------------------------------
|
|
13
|
+
// 1. Check for existing PRs (duplicate check)
|
|
14
|
+
// -------------------------------------------------------------------------
|
|
15
|
+
const skipMergedCheck = !!config.issueOverride;
|
|
16
|
+
let existingPr = await sourceControl.findExistingPr(issueIdentifier);
|
|
17
|
+
if (existingPr && skipMergedCheck && existingPr.state !== "open") {
|
|
18
|
+
existingPr = null;
|
|
19
|
+
}
|
|
20
|
+
if (existingPr) {
|
|
21
|
+
if (config.issueOverride && existingPr.state !== "open") {
|
|
22
|
+
ctx.logger.info(`Found ${existingPr.state} PR: ${existingPr.url} — issue override provided, implementing anyway`);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
ctx.logger.info(`Found existing PR: ${existingPr.url} (state: ${existingPr.state}) — skipping`);
|
|
26
|
+
return {
|
|
27
|
+
status: "skipped",
|
|
28
|
+
reason: `Existing PR found: ${existingPr.url}`,
|
|
29
|
+
data: { existingPrUrl: existingPr.url },
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// -------------------------------------------------------------------------
|
|
34
|
+
// 2. Create branch and configure git
|
|
35
|
+
// -------------------------------------------------------------------------
|
|
36
|
+
await sourceControl.configureBotIdentity();
|
|
37
|
+
let branchName;
|
|
38
|
+
if (issueBranchName) {
|
|
39
|
+
branchName = issueBranchName.replace(/^[^/]*\//, "");
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
branchName = `${issueIdentifier.toLowerCase()}-triage-fix`;
|
|
43
|
+
}
|
|
44
|
+
await sourceControl.createBranch(branchName);
|
|
45
|
+
await sourceControl.resetPaths([".github/workflows/"]);
|
|
46
|
+
ctx.logger.info(`Created branch: ${branchName}`);
|
|
47
|
+
// -------------------------------------------------------------------------
|
|
48
|
+
// 3. Install Claude and implement fix
|
|
49
|
+
// -------------------------------------------------------------------------
|
|
50
|
+
await codingAgent.install();
|
|
51
|
+
const implementPrompt = buildImplementPrompt(issueIdentifier);
|
|
52
|
+
await codingAgent.run({
|
|
53
|
+
prompt: implementPrompt,
|
|
54
|
+
maxTurns: config.maxImplementTurns,
|
|
55
|
+
env: { ...config.agentEnv },
|
|
56
|
+
});
|
|
57
|
+
// -------------------------------------------------------------------------
|
|
58
|
+
// 4. Check for code changes
|
|
59
|
+
// -------------------------------------------------------------------------
|
|
60
|
+
// Check if fix was declined
|
|
61
|
+
const fixDeclinedPath = ".github/triage-analysis/fix-declined.md";
|
|
62
|
+
if (fs.existsSync(fixDeclinedPath)) {
|
|
63
|
+
const reason = fs.readFileSync(fixDeclinedPath, "utf-8").trim();
|
|
64
|
+
ctx.logger.info(`Fix was declined by Claude: ${reason.slice(0, 200)}`);
|
|
65
|
+
return {
|
|
66
|
+
status: "skipped",
|
|
67
|
+
reason: `Fix declined: ${reason.slice(0, 200)}`,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
let hasCodeChanges = await sourceControl.hasNewCommits();
|
|
71
|
+
if (!hasCodeChanges) {
|
|
72
|
+
ctx.logger.info("No commits created by Claude");
|
|
73
|
+
const hasUncommitted = await sourceControl.hasChanges();
|
|
74
|
+
if (hasUncommitted) {
|
|
75
|
+
ctx.logger.info("Found uncommitted code changes, creating fallback commit");
|
|
76
|
+
await sourceControl.stageAndCommit(`fix: automated fix from log analysis\n\nPartial implementation by Claude (reached max turns before completion)\n\nIdentified by SWEny Triage\nLinear: ${issueIdentifier}`);
|
|
77
|
+
hasCodeChanges = true;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
ctx.logger.info("No code changes to commit");
|
|
81
|
+
return {
|
|
82
|
+
status: "skipped",
|
|
83
|
+
reason: "No code changes produced",
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
const changedFiles = await sourceControl.getChangedFiles();
|
|
89
|
+
ctx.logger.info(`Claude created commits with changes to: ${changedFiles.join(", ")}`);
|
|
90
|
+
}
|
|
91
|
+
// -------------------------------------------------------------------------
|
|
92
|
+
// 5. Push branch
|
|
93
|
+
// -------------------------------------------------------------------------
|
|
94
|
+
await sourceControl.pushBranch(branchName);
|
|
95
|
+
return {
|
|
96
|
+
status: "success",
|
|
97
|
+
data: { branchName, hasCodeChanges },
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=implement-fix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"implement-fix.js","sourceRoot":"","sources":["../../../../src/recipes/triage/steps/implement-fix.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { StepResult, WorkflowContext } from "../../../types.js";
|
|
2
|
+
import type { TriageConfig } from "../types.js";
|
|
3
|
+
/** Run Claude coding agent to investigate production issues and parse results. */
|
|
4
|
+
export declare function investigate(ctx: WorkflowContext<TriageConfig>): Promise<StepResult>;
|
|
5
|
+
//# sourceMappingURL=investigate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"investigate.d.ts","sourceRoot":"","sources":["../../../../src/recipes/triage/steps/investigate.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,aAAa,CAAC;AAMrE,kFAAkF;AAClF,wBAAsB,WAAW,CAAC,GAAG,EAAE,eAAe,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAkCzF"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { getStepData } from "../results.js";
|
|
4
|
+
import { buildInvestigationPrompt } from "../prompts.js";
|
|
5
|
+
const ANALYSIS_DIR = ".github/triage-analysis";
|
|
6
|
+
/** Run Claude coding agent to investigate production issues and parse results. */
|
|
7
|
+
export async function investigate(ctx) {
|
|
8
|
+
const config = ctx.config;
|
|
9
|
+
const observability = ctx.providers.get("observability");
|
|
10
|
+
const codingAgent = ctx.providers.get("codingAgent");
|
|
11
|
+
fs.mkdirSync(ANALYSIS_DIR, { recursive: true });
|
|
12
|
+
// Install coding agent CLI
|
|
13
|
+
await codingAgent.install();
|
|
14
|
+
// Get known issues context from prior step
|
|
15
|
+
const knownIssuesContent = getStepData(ctx, "build-context")?.knownIssuesContent ?? "";
|
|
16
|
+
// Write known issues file for reference
|
|
17
|
+
const knownIssuesPath = path.join(ANALYSIS_DIR, "known-issues-context.md");
|
|
18
|
+
fs.writeFileSync(knownIssuesPath, knownIssuesContent);
|
|
19
|
+
// Build investigation prompt
|
|
20
|
+
const prompt = buildInvestigationPrompt(config, observability, knownIssuesContent);
|
|
21
|
+
// Run coding agent investigation
|
|
22
|
+
await codingAgent.run({
|
|
23
|
+
prompt,
|
|
24
|
+
maxTurns: config.maxInvestigateTurns,
|
|
25
|
+
env: { ...config.agentEnv },
|
|
26
|
+
});
|
|
27
|
+
// Parse results
|
|
28
|
+
const result = parseInvestigationResults(ANALYSIS_DIR);
|
|
29
|
+
return {
|
|
30
|
+
status: "success",
|
|
31
|
+
data: result,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function parseInvestigationResults(analysisDir) {
|
|
35
|
+
const issuesReportPath = path.join(analysisDir, "issues-report.md");
|
|
36
|
+
const bestCandidatePath = path.join(analysisDir, "best-candidate.md");
|
|
37
|
+
const issuesFound = fs.existsSync(issuesReportPath);
|
|
38
|
+
const bestCandidate = fs.existsSync(bestCandidatePath);
|
|
39
|
+
let recommendation = "skip";
|
|
40
|
+
let existingIssue = "";
|
|
41
|
+
let targetRepo = "";
|
|
42
|
+
if (bestCandidate) {
|
|
43
|
+
const content = fs.readFileSync(bestCandidatePath, "utf-8");
|
|
44
|
+
// Extract RECOMMENDATION
|
|
45
|
+
const recMatch = content.match(/^RECOMMENDATION:\s*(.+)$/im);
|
|
46
|
+
if (recMatch) {
|
|
47
|
+
recommendation = recMatch[1].trim();
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
// Default to "implement" if best candidate exists but no explicit recommendation
|
|
51
|
+
recommendation = "implement";
|
|
52
|
+
}
|
|
53
|
+
// Extract existing issue reference from "+1 existing" recommendation
|
|
54
|
+
const existingMatch = recommendation.match(/\+1 existing\s+([A-Z]+-\d+)/i);
|
|
55
|
+
if (existingMatch) {
|
|
56
|
+
existingIssue = existingMatch[1];
|
|
57
|
+
}
|
|
58
|
+
// Extract TARGET_REPO
|
|
59
|
+
const repoMatch = content.match(/^TARGET_REPO:\s*(.+)$/im);
|
|
60
|
+
if (repoMatch) {
|
|
61
|
+
targetRepo = repoMatch[1].trim();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const shouldImplement = recommendation.toLowerCase().startsWith("implement");
|
|
65
|
+
return {
|
|
66
|
+
issuesFound,
|
|
67
|
+
bestCandidate,
|
|
68
|
+
recommendation,
|
|
69
|
+
existingIssue,
|
|
70
|
+
targetRepo,
|
|
71
|
+
shouldImplement,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=investigate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"investigate.js","sourceRoot":"","sources":["../../../../src/recipes/triage/steps/investigate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAK7B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAEzD,MAAM,YAAY,GAAG,yBAAyB,CAAC;AAE/C,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAkC;IAClE,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAC1B,MAAM,aAAa,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAwB,eAAe,CAAC,CAAC;IAChF,MAAM,WAAW,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAc,aAAa,CAAC,CAAC;IAElE,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhD,2BAA2B;IAC3B,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;IAE5B,2CAA2C;IAC3C,MAAM,kBAAkB,GAAG,WAAW,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,kBAAkB,IAAI,EAAE,CAAC;IAEvF,wCAAwC;IACxC,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,yBAAyB,CAAC,CAAC;IAC3E,EAAE,CAAC,aAAa,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC;IAEtD,6BAA6B;IAC7B,MAAM,MAAM,GAAG,wBAAwB,CAAC,MAAM,EAAE,aAAa,EAAE,kBAAkB,CAAC,CAAC;IAEnF,iCAAiC;IACjC,MAAM,WAAW,CAAC,GAAG,CAAC;QACpB,MAAM;QACN,QAAQ,EAAE,MAAM,CAAC,mBAAmB;QACpC,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE;KAC5B,CAAC,CAAC;IAEH,gBAAgB;IAChB,MAAM,MAAM,GAAG,yBAAyB,CAAC,YAAY,CAAC,CAAC;IAEvD,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,IAAI,EAAE,MAA4C;KACnD,CAAC;AACJ,CAAC;AAED,SAAS,yBAAyB,CAAC,WAAmB;IACpD,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;IACpE,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;IAEtE,MAAM,WAAW,GAAG,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;IACpD,MAAM,aAAa,GAAG,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAEvD,IAAI,cAAc,GAAG,MAAM,CAAC;IAC5B,IAAI,aAAa,GAAG,EAAE,CAAC;IACvB,IAAI,UAAU,GAAG,EAAE,CAAC;IAEpB,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;QAE5D,yBAAyB;QACzB,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAC7D,IAAI,QAAQ,EAAE,CAAC;YACb,cAAc,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,iFAAiF;YACjF,cAAc,GAAG,WAAW,CAAC;QAC/B,CAAC;QAED,qEAAqE;QACrE,MAAM,aAAa,GAAG,cAAc,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC3E,IAAI,aAAa,EAAE,CAAC;YAClB,aAAa,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC;QAED,sBAAsB;QACtB,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC3D,IAAI,SAAS,EAAE,CAAC;YACd,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACnC,CAAC;IACH,CAAC;IAED,MAAM,eAAe,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IAE7E,OAAO;QACL,WAAW;QACX,aAAa;QACb,cAAc;QACd,aAAa;QACb,UAAU;QACV,eAAe;KAChB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { StepResult, WorkflowContext } from "../../../types.js";
|
|
2
|
+
import type { TriageConfig } from "../types.js";
|
|
3
|
+
/** Build summary and send notification with investigation results. */
|
|
4
|
+
export declare function sendNotification(ctx: WorkflowContext<TriageConfig>): Promise<StepResult>;
|
|
5
|
+
//# sourceMappingURL=notify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../../../../src/recipes/triage/steps/notify.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,sEAAsE;AACtE,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,eAAe,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAkE9F"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import { getStepData } from "../results.js";
|
|
3
|
+
/** Build summary and send notification with investigation results. */
|
|
4
|
+
export async function sendNotification(ctx) {
|
|
5
|
+
const config = ctx.config;
|
|
6
|
+
const notification = ctx.providers.get("notification");
|
|
7
|
+
const investigation = getStepData(ctx, "investigate");
|
|
8
|
+
const prData = getStepData(ctx, "create-pr");
|
|
9
|
+
const issueData = getStepData(ctx, "create-issue");
|
|
10
|
+
const crossRepoData = getStepData(ctx, "cross-repo-check");
|
|
11
|
+
const implementResult = ctx.results.get("implement-fix");
|
|
12
|
+
const lines = [];
|
|
13
|
+
lines.push(`**Run Date**: ${new Date().toISOString()}`);
|
|
14
|
+
lines.push(`**Service Filter**: \`${config.serviceFilter}\``);
|
|
15
|
+
lines.push(`**Time Range**: \`${config.timeRange}\``);
|
|
16
|
+
lines.push(`**Dry Run**: ${config.dryRun}`);
|
|
17
|
+
lines.push(`**Recommendation**: ${investigation?.recommendation ?? "unknown"}`);
|
|
18
|
+
lines.push("");
|
|
19
|
+
// Issue reference
|
|
20
|
+
const issueIdentifier = prData?.issueIdentifier ?? issueData?.issueIdentifier;
|
|
21
|
+
const issueUrl = prData?.issueUrl ?? issueData?.issueUrl;
|
|
22
|
+
if (issueIdentifier) {
|
|
23
|
+
lines.push(`**Issue**: [${issueIdentifier}](${issueUrl})`);
|
|
24
|
+
lines.push("");
|
|
25
|
+
}
|
|
26
|
+
// Status message
|
|
27
|
+
if (crossRepoData?.dispatched) {
|
|
28
|
+
lines.push(`> **Cross-repo dispatch**: Bug belongs to \`${crossRepoData.targetRepo}\` — dispatched for implementation`);
|
|
29
|
+
}
|
|
30
|
+
else if (investigation?.recommendation?.toLowerCase().includes("skip")) {
|
|
31
|
+
lines.push("> **Skipped**: No novel issues found");
|
|
32
|
+
}
|
|
33
|
+
else if (investigation?.recommendation?.toLowerCase().includes("+1 existing")) {
|
|
34
|
+
lines.push("> **+1 Existing**: Added occurrence to existing issue");
|
|
35
|
+
}
|
|
36
|
+
else if (implementResult?.status === "skipped" && implementResult.reason) {
|
|
37
|
+
lines.push(`> **Skipped**: ${implementResult.reason}`);
|
|
38
|
+
}
|
|
39
|
+
else if (prData?.prUrl) {
|
|
40
|
+
lines.push(`> **Success**: New PR created - ${prData.prUrl}`);
|
|
41
|
+
}
|
|
42
|
+
else if (config.dryRun) {
|
|
43
|
+
lines.push("> **Dry Run**: Analysis only");
|
|
44
|
+
}
|
|
45
|
+
// Append investigation log if it exists
|
|
46
|
+
const investigationLog = ".github/triage-analysis/investigation-log.md";
|
|
47
|
+
if (fs.existsSync(investigationLog)) {
|
|
48
|
+
lines.push("");
|
|
49
|
+
lines.push("### Investigation Log");
|
|
50
|
+
lines.push(fs.readFileSync(investigationLog, "utf-8"));
|
|
51
|
+
}
|
|
52
|
+
// Append issues report if it exists
|
|
53
|
+
const issuesReport = ".github/triage-analysis/issues-report.md";
|
|
54
|
+
if (fs.existsSync(issuesReport)) {
|
|
55
|
+
lines.push("");
|
|
56
|
+
lines.push("### Issues Found");
|
|
57
|
+
lines.push(fs.readFileSync(issuesReport, "utf-8"));
|
|
58
|
+
}
|
|
59
|
+
await notification.send({
|
|
60
|
+
title: "SWEny Triage Summary",
|
|
61
|
+
body: lines.join("\n"),
|
|
62
|
+
format: "markdown",
|
|
63
|
+
});
|
|
64
|
+
return { status: "success" };
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=notify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notify.js","sourceRoot":"","sources":["../../../../src/recipes/triage/steps/notify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAIzB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,GAAkC;IACvE,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAC1B,MAAM,YAAY,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAuB,cAAc,CAAC,CAAC;IAC7E,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IACnD,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;IAC3D,MAAM,eAAe,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAEzD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,iBAAiB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IACxD,KAAK,CAAC,IAAI,CAAC,yBAAyB,MAAM,CAAC,aAAa,IAAI,CAAC,CAAC;IAC9D,KAAK,CAAC,IAAI,CAAC,qBAAqB,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;IACtD,KAAK,CAAC,IAAI,CAAC,gBAAgB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5C,KAAK,CAAC,IAAI,CAAC,uBAAuB,aAAa,EAAE,cAAc,IAAI,SAAS,EAAE,CAAC,CAAC;IAChF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,kBAAkB;IAClB,MAAM,eAAe,GAAG,MAAM,EAAE,eAAe,IAAI,SAAS,EAAE,eAAe,CAAC;IAC9E,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,SAAS,EAAE,QAAQ,CAAC;IACzD,IAAI,eAAe,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,eAAe,eAAe,KAAK,QAAQ,GAAG,CAAC,CAAC;QAC3D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,iBAAiB;IACjB,IAAI,aAAa,EAAE,UAAU,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CACR,+CAA+C,aAAa,CAAC,UAAU,oCAAoC,CAC5G,CAAC;IACJ,CAAC;SAAM,IAAI,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACzE,KAAK,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;IACrD,CAAC;SAAM,IAAI,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QAChF,KAAK,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;IACtE,CAAC;SAAM,IAAI,eAAe,EAAE,MAAM,KAAK,SAAS,IAAI,eAAe,CAAC,MAAM,EAAE,CAAC;QAC3E,KAAK,CAAC,IAAI,CAAC,kBAAkB,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC;IACzD,CAAC;SAAM,IAAI,MAAM,EAAE,KAAK,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,mCAAmC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IAChE,CAAC;SAAM,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC7C,CAAC;IAED,wCAAwC;IACxC,MAAM,gBAAgB,GAAG,8CAA8C,CAAC;IACxE,IAAI,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,oCAAoC;IACpC,MAAM,YAAY,GAAG,0CAA0C,CAAC;IAChE,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,YAAY,CAAC,IAAI,CAAC;QACtB,KAAK,EAAE,sBAAsB;QAC7B,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QACtB,MAAM,EAAE,UAAU;KACnB,CAAC,CAAC;IAEH,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { StepResult, WorkflowContext } from "../../../types.js";
|
|
2
|
+
import type { TriageConfig } from "../types.js";
|
|
3
|
+
/** Check investigation recommendation and decide whether to proceed with implementation. */
|
|
4
|
+
export declare function noveltyGate(ctx: WorkflowContext<TriageConfig>): Promise<StepResult>;
|
|
5
|
+
//# sourceMappingURL=novelty-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"novelty-gate.d.ts","sourceRoot":"","sources":["../../../../src/recipes/triage/steps/novelty-gate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,4FAA4F;AAC5F,wBAAsB,WAAW,CAAC,GAAG,EAAE,eAAe,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CA+DzF"}
|