@hardlydifficult/pr-analyzer 1.0.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/dist/actions.d.ts +38 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +77 -0
- package/dist/actions.js.map +1 -0
- package/dist/analysis.d.ts +22 -0
- package/dist/analysis.d.ts.map +1 -0
- package/dist/analysis.js +244 -0
- package/dist/analysis.js.map +1 -0
- package/dist/classification.d.ts +20 -0
- package/dist/classification.d.ts.map +1 -0
- package/dist/classification.js +54 -0
- package/dist/classification.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +98 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/workflow.d.ts +13 -0
- package/dist/workflow.d.ts.map +1 -0
- package/dist/workflow.js +18 -0
- package/dist/workflow.js.map +1 -0
- package/package.json +25 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PR Action Resolution
|
|
3
|
+
*
|
|
4
|
+
* Determines which actions are available for a PR based on its status.
|
|
5
|
+
* This is the single source of truth for core action definitions — clients
|
|
6
|
+
* (web, Discord, voice) render from these descriptors.
|
|
7
|
+
*
|
|
8
|
+
* Consumers can provide extra actions via ActionDefinition[].
|
|
9
|
+
*/
|
|
10
|
+
import type { ActionDefinition, ScannedPR } from "./types.js";
|
|
11
|
+
/**
|
|
12
|
+
* Core action types built into the package.
|
|
13
|
+
* Consumers can define additional action types via ActionDefinition.
|
|
14
|
+
*/
|
|
15
|
+
export type CorePRActionType = "merge" | "mark_ready" | "enable_auto_merge";
|
|
16
|
+
/**
|
|
17
|
+
* Describes an available action for a PR.
|
|
18
|
+
* `type` is `string` to allow custom action types from consumers.
|
|
19
|
+
*/
|
|
20
|
+
export interface PRActionDescriptor {
|
|
21
|
+
readonly type: string;
|
|
22
|
+
readonly label: string;
|
|
23
|
+
readonly description: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Core action registry — maps each core action type to its metadata.
|
|
27
|
+
*/
|
|
28
|
+
export declare const PR_ACTIONS: Record<CorePRActionType, Omit<PRActionDescriptor, "type">>;
|
|
29
|
+
/**
|
|
30
|
+
* Determine which actions are available for a given PR.
|
|
31
|
+
*
|
|
32
|
+
* @param pr - The scanned PR object
|
|
33
|
+
* @param extraActions - Additional actions provided by consumers
|
|
34
|
+
* @param context - Key-value context for evaluating extra action conditions
|
|
35
|
+
* @returns Array of available action descriptors
|
|
36
|
+
*/
|
|
37
|
+
export declare function getAvailableActions(pr: ScannedPR, extraActions?: readonly ActionDefinition[], context?: Record<string, boolean>): PRActionDescriptor[];
|
|
38
|
+
//# sourceMappingURL=actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE9D;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,YAAY,GAAG,mBAAmB,CAAC;AAE5E;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,CAC7B,gBAAgB,EAChB,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAWjC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,SAAS,EACb,YAAY,CAAC,EAAE,SAAS,gBAAgB,EAAE,EAC1C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,kBAAkB,EAAE,CA2CtB"}
|
package/dist/actions.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PR Action Resolution
|
|
4
|
+
*
|
|
5
|
+
* Determines which actions are available for a PR based on its status.
|
|
6
|
+
* This is the single source of truth for core action definitions — clients
|
|
7
|
+
* (web, Discord, voice) render from these descriptors.
|
|
8
|
+
*
|
|
9
|
+
* Consumers can provide extra actions via ActionDefinition[].
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.PR_ACTIONS = void 0;
|
|
13
|
+
exports.getAvailableActions = getAvailableActions;
|
|
14
|
+
/**
|
|
15
|
+
* Core action registry — maps each core action type to its metadata.
|
|
16
|
+
*/
|
|
17
|
+
exports.PR_ACTIONS = {
|
|
18
|
+
merge: { label: "Merge", description: "Squash and merge this PR" },
|
|
19
|
+
mark_ready: {
|
|
20
|
+
label: "Mark Ready",
|
|
21
|
+
description: "Mark this draft PR as ready for review",
|
|
22
|
+
},
|
|
23
|
+
enable_auto_merge: {
|
|
24
|
+
label: "Enable Auto-Merge",
|
|
25
|
+
description: "Enable GitHub auto-merge when checks pass",
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Determine which actions are available for a given PR.
|
|
30
|
+
*
|
|
31
|
+
* @param pr - The scanned PR object
|
|
32
|
+
* @param extraActions - Additional actions provided by consumers
|
|
33
|
+
* @param context - Key-value context for evaluating extra action conditions
|
|
34
|
+
* @returns Array of available action descriptors
|
|
35
|
+
*/
|
|
36
|
+
function getAvailableActions(pr, extraActions, context) {
|
|
37
|
+
const actions = [];
|
|
38
|
+
const { status } = pr;
|
|
39
|
+
// Core actions based on status
|
|
40
|
+
switch (status) {
|
|
41
|
+
case "ready_to_merge":
|
|
42
|
+
case "approved":
|
|
43
|
+
actions.push({ type: "merge", ...exports.PR_ACTIONS.merge });
|
|
44
|
+
break;
|
|
45
|
+
case "draft":
|
|
46
|
+
if (pr.ciStatus.allPassed && !pr.hasConflicts) {
|
|
47
|
+
actions.push({ type: "mark_ready", ...exports.PR_ACTIONS.mark_ready });
|
|
48
|
+
}
|
|
49
|
+
break;
|
|
50
|
+
case "ci_running":
|
|
51
|
+
case "needs_review":
|
|
52
|
+
if (!pr.pr.draft && !pr.hasConflicts && pr.pr.merged_at === null) {
|
|
53
|
+
actions.push({
|
|
54
|
+
type: "enable_auto_merge",
|
|
55
|
+
...exports.PR_ACTIONS.enable_auto_merge,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
break;
|
|
59
|
+
default:
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
// Evaluate extra actions from consumers
|
|
63
|
+
if (extraActions) {
|
|
64
|
+
const ctx = context ?? {};
|
|
65
|
+
for (const action of extraActions) {
|
|
66
|
+
if (action.when(pr, ctx)) {
|
|
67
|
+
actions.push({
|
|
68
|
+
type: action.type,
|
|
69
|
+
label: action.label,
|
|
70
|
+
description: action.description,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return actions;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AA8CH,kDA+CC;AAzED;;GAEG;AACU,QAAA,UAAU,GAGnB;IACF,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,0BAA0B,EAAE;IAClE,UAAU,EAAE;QACV,KAAK,EAAE,YAAY;QACnB,WAAW,EAAE,wCAAwC;KACtD;IACD,iBAAiB,EAAE;QACjB,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EAAE,2CAA2C;KACzD;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,SAAgB,mBAAmB,CACjC,EAAa,EACb,YAA0C,EAC1C,OAAiC;IAEjC,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IAEtB,+BAA+B;IAC/B,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,gBAAgB,CAAC;QACtB,KAAK,UAAU;YACb,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,kBAAU,CAAC,KAAK,EAAE,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,OAAO;YACV,IAAI,EAAE,CAAC,QAAQ,CAAC,SAAS,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC;gBAC9C,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,kBAAU,CAAC,UAAU,EAAE,CAAC,CAAC;YACjE,CAAC;YACD,MAAM;QACR,KAAK,YAAY,CAAC;QAClB,KAAK,cAAc;YACjB,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;gBACjE,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,mBAAmB;oBACzB,GAAG,kBAAU,CAAC,iBAAiB;iBAChC,CAAC,CAAC;YACL,CAAC;YACD,MAAM;QACR;YACE,MAAM;IACV,CAAC;IAED,wCAAwC;IACxC,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,GAAG,GAAG,OAAO,IAAI,EAAE,CAAC;QAC1B,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;YAClC,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;gBACzB,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,WAAW,EAAE,MAAM,CAAC,WAAW;iBAChC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PR Analysis
|
|
3
|
+
*
|
|
4
|
+
* Analyzes a single PR to determine its status:
|
|
5
|
+
* 1. Fetch CI checks, comments, reviews, and repo info
|
|
6
|
+
* 2. Analyze CI status (running, failed, passed)
|
|
7
|
+
* 3. Check if waiting on a bot response
|
|
8
|
+
* 4. Determine overall PR status based on all factors
|
|
9
|
+
*
|
|
10
|
+
* Custom status logic can be injected via AnalyzerHooks.resolveStatus.
|
|
11
|
+
*/
|
|
12
|
+
import type { GitHubClient, PullRequest } from "@hardlydifficult/github";
|
|
13
|
+
import type { AnalyzerHooks, DiscoveredPR, Logger, ScannedPR } from "./types.js";
|
|
14
|
+
/**
|
|
15
|
+
* Analyze a PR and determine its status
|
|
16
|
+
*/
|
|
17
|
+
export declare function analyzePR(client: GitHubClient, owner: string, repo: string, pr: PullRequest, botMention: string, hooks?: AnalyzerHooks): Promise<ScannedPR>;
|
|
18
|
+
/**
|
|
19
|
+
* Analyze all discovered PRs, logging any failures
|
|
20
|
+
*/
|
|
21
|
+
export declare function analyzeAll(prs: readonly DiscoveredPR[], client: GitHubClient, botMention: string, logger?: Logger, hooks?: AnalyzerHooks): Promise<ScannedPR[]>;
|
|
22
|
+
//# sourceMappingURL=analysis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAEV,YAAY,EACZ,WAAW,EAGZ,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EACV,aAAa,EAGb,YAAY,EACZ,MAAM,EACN,SAAS,EACV,MAAM,YAAY,CAAC;AAmBpB;;GAEG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,WAAW,EACf,UAAU,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,CAAC,CAwCpB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,SAAS,YAAY,EAAE,EAC5B,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CAkBtB"}
|
package/dist/analysis.js
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PR Analysis
|
|
4
|
+
*
|
|
5
|
+
* Analyzes a single PR to determine its status:
|
|
6
|
+
* 1. Fetch CI checks, comments, reviews, and repo info
|
|
7
|
+
* 2. Analyze CI status (running, failed, passed)
|
|
8
|
+
* 3. Check if waiting on a bot response
|
|
9
|
+
* 4. Determine overall PR status based on all factors
|
|
10
|
+
*
|
|
11
|
+
* Custom status logic can be injected via AnalyzerHooks.resolveStatus.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.analyzePR = analyzePR;
|
|
15
|
+
exports.analyzeAll = analyzeAll;
|
|
16
|
+
// Bot usernames to detect when waiting for bot response
|
|
17
|
+
const BOT_USERNAMES = new Set([
|
|
18
|
+
"cursor",
|
|
19
|
+
"cursor-bot",
|
|
20
|
+
"github-actions",
|
|
21
|
+
"github-actions[bot]",
|
|
22
|
+
"dependabot",
|
|
23
|
+
"dependabot[bot]",
|
|
24
|
+
"renovate",
|
|
25
|
+
"renovate[bot]",
|
|
26
|
+
"codecov",
|
|
27
|
+
"codecov[bot]",
|
|
28
|
+
"vercel",
|
|
29
|
+
"vercel[bot]",
|
|
30
|
+
"claude",
|
|
31
|
+
]);
|
|
32
|
+
/**
|
|
33
|
+
* Analyze a PR and determine its status
|
|
34
|
+
*/
|
|
35
|
+
async function analyzePR(client, owner, repo, pr, botMention, hooks) {
|
|
36
|
+
// Fetch all required data in parallel
|
|
37
|
+
const repoClient = client.repo(owner, repo);
|
|
38
|
+
const prClient = repoClient.pr(pr.number);
|
|
39
|
+
const [checks, comments, reviews, repoInfo] = await Promise.all([
|
|
40
|
+
prClient.getCheckRuns(),
|
|
41
|
+
prClient.getComments(),
|
|
42
|
+
prClient.getReviews(),
|
|
43
|
+
repoClient.get(),
|
|
44
|
+
]);
|
|
45
|
+
// Analyze the fetched data
|
|
46
|
+
const ciStatus = analyzeCIStatus(checks);
|
|
47
|
+
const waitingOnBot = isWaitingOnBot(comments, botMention);
|
|
48
|
+
const conflicting = hasConflicts(pr);
|
|
49
|
+
const coreStatus = determineStatus(pr, ciStatus, reviews, waitingOnBot);
|
|
50
|
+
// Allow hook to override status
|
|
51
|
+
const status = hooks?.resolveStatus?.(coreStatus, {
|
|
52
|
+
comments,
|
|
53
|
+
checks,
|
|
54
|
+
reviews,
|
|
55
|
+
ciStatus,
|
|
56
|
+
hasConflicts: conflicting,
|
|
57
|
+
waitingOnBot,
|
|
58
|
+
}) ?? coreStatus;
|
|
59
|
+
const daysSinceUpdate = calculateDaysSinceUpdate(pr.updated_at);
|
|
60
|
+
return {
|
|
61
|
+
pr,
|
|
62
|
+
repo: repoInfo,
|
|
63
|
+
status,
|
|
64
|
+
ciStatus,
|
|
65
|
+
ciSummary: ciStatus.summary,
|
|
66
|
+
hasConflicts: conflicting,
|
|
67
|
+
waitingOnBot,
|
|
68
|
+
daysSinceUpdate,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Analyze all discovered PRs, logging any failures
|
|
73
|
+
*/
|
|
74
|
+
async function analyzeAll(prs, client, botMention, logger, hooks) {
|
|
75
|
+
const results = [];
|
|
76
|
+
for (const { pr, repoOwner, repoName } of prs) {
|
|
77
|
+
try {
|
|
78
|
+
results.push(await analyzePR(client, repoOwner, repoName, pr, botMention, hooks));
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
logger?.error("Failed to analyze PR", {
|
|
82
|
+
repo: `${repoOwner}/${repoName}`,
|
|
83
|
+
pr: pr.number,
|
|
84
|
+
error: err instanceof Error ? err.message : String(err),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return results;
|
|
89
|
+
}
|
|
90
|
+
// --- Status Determination ---
|
|
91
|
+
/**
|
|
92
|
+
* Determine the core status of a PR based on GitHub data.
|
|
93
|
+
*
|
|
94
|
+
* Priority order:
|
|
95
|
+
* 1. Draft → draft
|
|
96
|
+
* 2. CI running → ci_running
|
|
97
|
+
* 3. CI failed → ci_failed
|
|
98
|
+
* 4. Has conflicts → has_conflicts
|
|
99
|
+
* 5. Waiting on bot → waiting_on_bot
|
|
100
|
+
* 6. Changes requested → changes_requested
|
|
101
|
+
* 7. CI passed → ready_to_merge
|
|
102
|
+
* 8. Approved → approved
|
|
103
|
+
* 9. Default → needs_review
|
|
104
|
+
*/
|
|
105
|
+
function determineStatus(pr, ci, reviews, waitingOnBot) {
|
|
106
|
+
if (pr.draft) {
|
|
107
|
+
return "draft";
|
|
108
|
+
}
|
|
109
|
+
if (ci.isRunning) {
|
|
110
|
+
return "ci_running";
|
|
111
|
+
}
|
|
112
|
+
if (ci.hasFailed) {
|
|
113
|
+
return "ci_failed";
|
|
114
|
+
}
|
|
115
|
+
if (hasConflicts(pr)) {
|
|
116
|
+
return "has_conflicts";
|
|
117
|
+
}
|
|
118
|
+
if (waitingOnBot) {
|
|
119
|
+
return "waiting_on_bot";
|
|
120
|
+
}
|
|
121
|
+
const reviewStatus = analyzeReviews(reviews);
|
|
122
|
+
if (reviewStatus.hasChangesRequested) {
|
|
123
|
+
return "changes_requested";
|
|
124
|
+
}
|
|
125
|
+
if (ci.allPassed) {
|
|
126
|
+
return "ready_to_merge";
|
|
127
|
+
}
|
|
128
|
+
if (reviewStatus.hasApproval) {
|
|
129
|
+
return "approved";
|
|
130
|
+
}
|
|
131
|
+
return "needs_review";
|
|
132
|
+
}
|
|
133
|
+
// --- CI Analysis ---
|
|
134
|
+
function analyzeCIStatus(checks) {
|
|
135
|
+
if (checks.length === 0) {
|
|
136
|
+
return {
|
|
137
|
+
isRunning: false,
|
|
138
|
+
hasFailed: false,
|
|
139
|
+
allPassed: true,
|
|
140
|
+
summary: "No CI checks",
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
const running = checks.filter(isCheckRunning);
|
|
144
|
+
const failed = checks.filter(isCheckFailed);
|
|
145
|
+
const passed = checks.filter(isCheckPassed);
|
|
146
|
+
// Validate that all checks are categorized
|
|
147
|
+
const categorized = running.length + failed.length + passed.length;
|
|
148
|
+
if (categorized !== checks.length) {
|
|
149
|
+
const uncategorized = checks.filter((c) => !isCheckRunning(c) && !isCheckFailed(c) && !isCheckPassed(c));
|
|
150
|
+
running.push(...uncategorized);
|
|
151
|
+
}
|
|
152
|
+
const isRunning = running.length > 0;
|
|
153
|
+
const hasFailed = failed.length > 0;
|
|
154
|
+
const allPassed = !isRunning && !hasFailed && passed.length === checks.length;
|
|
155
|
+
return {
|
|
156
|
+
isRunning,
|
|
157
|
+
hasFailed,
|
|
158
|
+
allPassed,
|
|
159
|
+
summary: formatCISummary(running, failed, passed, checks.length),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function isCheckRunning(check) {
|
|
163
|
+
if (check.status === "in_progress" || check.status === "queued") {
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
return check.conclusion === null;
|
|
167
|
+
}
|
|
168
|
+
function isCheckFailed(check) {
|
|
169
|
+
return (check.status === "completed" &&
|
|
170
|
+
(check.conclusion === "failure" ||
|
|
171
|
+
check.conclusion === "timed_out" ||
|
|
172
|
+
check.conclusion === "cancelled" ||
|
|
173
|
+
check.conclusion === "action_required"));
|
|
174
|
+
}
|
|
175
|
+
function isCheckPassed(check) {
|
|
176
|
+
return (check.status === "completed" &&
|
|
177
|
+
(check.conclusion === "success" ||
|
|
178
|
+
check.conclusion === "skipped" ||
|
|
179
|
+
check.conclusion === "neutral"));
|
|
180
|
+
}
|
|
181
|
+
function formatCISummary(running, failed, passed, total) {
|
|
182
|
+
if (running.length > 0 && passed.length > 0) {
|
|
183
|
+
return `CI running: ${String(running.length)} in progress, ${String(passed.length)} passed`;
|
|
184
|
+
}
|
|
185
|
+
if (running.length > 0) {
|
|
186
|
+
return `CI running: ${String(running.length)} in progress`;
|
|
187
|
+
}
|
|
188
|
+
if (failed.length > 0 && passed.length > 0) {
|
|
189
|
+
return `CI failed: ${String(failed.length)} failed, ${String(passed.length)} passed`;
|
|
190
|
+
}
|
|
191
|
+
if (failed.length > 0) {
|
|
192
|
+
return `CI failed: ${failed.map((c) => c.name).join(", ")}`;
|
|
193
|
+
}
|
|
194
|
+
if (passed.length === total) {
|
|
195
|
+
return `CI passed: ${String(passed.length)} checks`;
|
|
196
|
+
}
|
|
197
|
+
return `CI: ${String(total)} checks`;
|
|
198
|
+
}
|
|
199
|
+
// --- Review Analysis ---
|
|
200
|
+
function analyzeReviews(reviews) {
|
|
201
|
+
const latestByUser = new Map();
|
|
202
|
+
for (const review of reviews) {
|
|
203
|
+
const existing = latestByUser.get(review.user.login);
|
|
204
|
+
if (existing === undefined ||
|
|
205
|
+
new Date(review.submitted_at) > new Date(existing.submitted_at)) {
|
|
206
|
+
latestByUser.set(review.user.login, review);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const latestReviews = Array.from(latestByUser.values());
|
|
210
|
+
return {
|
|
211
|
+
hasChangesRequested: latestReviews.some((r) => r.state === "CHANGES_REQUESTED"),
|
|
212
|
+
hasApproval: latestReviews.some((r) => r.state === "APPROVED"),
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
// --- Bot Detection ---
|
|
216
|
+
function isWaitingOnBot(comments, botMention) {
|
|
217
|
+
if (comments.length === 0) {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
const botMentionLower = botMention.toLowerCase();
|
|
221
|
+
const mentionComments = comments.filter((c) => c.body.toLowerCase().includes(botMentionLower));
|
|
222
|
+
if (mentionComments.length === 0) {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
const lastMention = mentionComments[mentionComments.length - 1];
|
|
226
|
+
const botComments = comments.filter((c) => isBot(c.user.login));
|
|
227
|
+
if (botComments.length === 0) {
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
const lastBotComment = botComments[botComments.length - 1];
|
|
231
|
+
return new Date(lastBotComment.created_at) < new Date(lastMention.created_at);
|
|
232
|
+
}
|
|
233
|
+
function isBot(username) {
|
|
234
|
+
const lower = username.toLowerCase();
|
|
235
|
+
return (BOT_USERNAMES.has(lower) || lower.endsWith("[bot]") || lower.includes("bot"));
|
|
236
|
+
}
|
|
237
|
+
// --- Utility ---
|
|
238
|
+
function hasConflicts(pr) {
|
|
239
|
+
return pr.mergeable === false || pr.mergeable_state === "conflicting";
|
|
240
|
+
}
|
|
241
|
+
function calculateDaysSinceUpdate(updatedAt) {
|
|
242
|
+
return Math.floor((Date.now() - new Date(updatedAt).getTime()) / (1000 * 60 * 60 * 24));
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=analysis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PR Classification
|
|
3
|
+
*
|
|
4
|
+
* Classifies PRs into action buckets:
|
|
5
|
+
* - readyForHuman: PRs that need human attention (review, approve, merge)
|
|
6
|
+
* - needsBotBump: PRs waiting on a bot response
|
|
7
|
+
* - inProgress: PRs with active work (CI running)
|
|
8
|
+
* - blocked: PRs waiting but no active work (draft, CI failed, conflicts)
|
|
9
|
+
*
|
|
10
|
+
* Consumers can extend buckets via ClassificationConfig.
|
|
11
|
+
*/
|
|
12
|
+
import type { ClassificationConfig, ScannedPR, ScanResult } from "./types.js";
|
|
13
|
+
/**
|
|
14
|
+
* Classify PRs into action buckets.
|
|
15
|
+
*
|
|
16
|
+
* @param prs - The PRs to classify
|
|
17
|
+
* @param config - Optional extra statuses to include in each bucket
|
|
18
|
+
*/
|
|
19
|
+
export declare function classifyPRs(prs: readonly ScannedPR[], config?: ClassificationConfig): ScanResult;
|
|
20
|
+
//# sourceMappingURL=classification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classification.d.ts","sourceRoot":"","sources":["../src/classification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAqB9E;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,SAAS,SAAS,EAAE,EACzB,MAAM,CAAC,EAAE,oBAAoB,GAC5B,UAAU,CAmBZ"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PR Classification
|
|
4
|
+
*
|
|
5
|
+
* Classifies PRs into action buckets:
|
|
6
|
+
* - readyForHuman: PRs that need human attention (review, approve, merge)
|
|
7
|
+
* - needsBotBump: PRs waiting on a bot response
|
|
8
|
+
* - inProgress: PRs with active work (CI running)
|
|
9
|
+
* - blocked: PRs waiting but no active work (draft, CI failed, conflicts)
|
|
10
|
+
*
|
|
11
|
+
* Consumers can extend buckets via ClassificationConfig.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.classifyPRs = classifyPRs;
|
|
15
|
+
// --- Core status lists ---
|
|
16
|
+
const READY_FOR_HUMAN_STATUSES = [
|
|
17
|
+
"needs_review",
|
|
18
|
+
"changes_requested",
|
|
19
|
+
"approved",
|
|
20
|
+
"ready_to_merge",
|
|
21
|
+
];
|
|
22
|
+
const IN_PROGRESS_STATUSES = ["ci_running"];
|
|
23
|
+
const BLOCKED_STATUSES = [
|
|
24
|
+
"draft",
|
|
25
|
+
"ci_failed",
|
|
26
|
+
"has_conflicts",
|
|
27
|
+
];
|
|
28
|
+
const NEEDS_BOT_BUMP_STATUSES = ["waiting_on_bot"];
|
|
29
|
+
/**
|
|
30
|
+
* Classify PRs into action buckets.
|
|
31
|
+
*
|
|
32
|
+
* @param prs - The PRs to classify
|
|
33
|
+
* @param config - Optional extra statuses to include in each bucket
|
|
34
|
+
*/
|
|
35
|
+
function classifyPRs(prs, config) {
|
|
36
|
+
const readyForHuman = mergeStatuses(READY_FOR_HUMAN_STATUSES, config?.readyForHuman);
|
|
37
|
+
const inProgress = mergeStatuses(IN_PROGRESS_STATUSES, config?.inProgress);
|
|
38
|
+
const blocked = mergeStatuses(BLOCKED_STATUSES, config?.blocked);
|
|
39
|
+
const needsBotBump = mergeStatuses(NEEDS_BOT_BUMP_STATUSES, config?.needsBotBump);
|
|
40
|
+
return {
|
|
41
|
+
all: prs,
|
|
42
|
+
readyForHuman: prs.filter((pr) => readyForHuman.includes(pr.status)),
|
|
43
|
+
needsBotBump: prs.filter((pr) => needsBotBump.includes(pr.status)),
|
|
44
|
+
inProgress: prs.filter((pr) => inProgress.includes(pr.status)),
|
|
45
|
+
blocked: prs.filter((pr) => blocked.includes(pr.status)),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function mergeStatuses(base, extra) {
|
|
49
|
+
if (!extra || extra.length === 0) {
|
|
50
|
+
return base;
|
|
51
|
+
}
|
|
52
|
+
return [...base, ...extra];
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=classification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classification.js","sourceRoot":"","sources":["../src/classification.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AA6BH,kCAsBC;AA/CD,4BAA4B;AAE5B,MAAM,wBAAwB,GAAsB;IAClD,cAAc;IACd,mBAAmB;IACnB,UAAU;IACV,gBAAgB;CACjB,CAAC;AAEF,MAAM,oBAAoB,GAAsB,CAAC,YAAY,CAAC,CAAC;AAE/D,MAAM,gBAAgB,GAAsB;IAC1C,OAAO;IACP,WAAW;IACX,eAAe;CAChB,CAAC;AAEF,MAAM,uBAAuB,GAAsB,CAAC,gBAAgB,CAAC,CAAC;AAEtE;;;;;GAKG;AACH,SAAgB,WAAW,CACzB,GAAyB,EACzB,MAA6B;IAE7B,MAAM,aAAa,GAAG,aAAa,CACjC,wBAAwB,EACxB,MAAM,EAAE,aAAa,CACtB,CAAC;IACF,MAAM,UAAU,GAAG,aAAa,CAAC,oBAAoB,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IAC3E,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACjE,MAAM,YAAY,GAAG,aAAa,CAChC,uBAAuB,EACvB,MAAM,EAAE,YAAY,CACrB,CAAC;IAEF,OAAO;QACL,GAAG,EAAE,GAAG;QACR,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QACpE,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAClE,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAC9D,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;KACzD,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CACpB,IAAuB,EACvB,KAAyB;IAEzB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC;AAC7B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PR Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Analyzes and classifies GitHub PRs.
|
|
5
|
+
* See workflow.ts for single-PR scanning.
|
|
6
|
+
*/
|
|
7
|
+
export { scanSinglePR } from "./workflow.js";
|
|
8
|
+
export { analyzePR, analyzeAll } from "./analysis.js";
|
|
9
|
+
export { classifyPRs } from "./classification.js";
|
|
10
|
+
export { getAvailableActions, PR_ACTIONS } from "./actions.js";
|
|
11
|
+
export type { CorePRStatus, ScannedPR, ScanResult, CIStatus, DiscoveredPR, Logger, AnalysisDetails, AnalyzerHooks, ClassificationConfig, ActionDefinition, } from "./types.js";
|
|
12
|
+
export type { CorePRActionType, PRActionDescriptor } from "./actions.js";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/D,YAAY,EACV,YAAY,EACZ,SAAS,EACT,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PR Analyzer
|
|
4
|
+
*
|
|
5
|
+
* Analyzes and classifies GitHub PRs.
|
|
6
|
+
* See workflow.ts for single-PR scanning.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.PR_ACTIONS = exports.getAvailableActions = exports.classifyPRs = exports.analyzeAll = exports.analyzePR = exports.scanSinglePR = void 0;
|
|
10
|
+
var workflow_js_1 = require("./workflow.js");
|
|
11
|
+
Object.defineProperty(exports, "scanSinglePR", { enumerable: true, get: function () { return workflow_js_1.scanSinglePR; } });
|
|
12
|
+
var analysis_js_1 = require("./analysis.js");
|
|
13
|
+
Object.defineProperty(exports, "analyzePR", { enumerable: true, get: function () { return analysis_js_1.analyzePR; } });
|
|
14
|
+
Object.defineProperty(exports, "analyzeAll", { enumerable: true, get: function () { return analysis_js_1.analyzeAll; } });
|
|
15
|
+
var classification_js_1 = require("./classification.js");
|
|
16
|
+
Object.defineProperty(exports, "classifyPRs", { enumerable: true, get: function () { return classification_js_1.classifyPRs; } });
|
|
17
|
+
var actions_js_1 = require("./actions.js");
|
|
18
|
+
Object.defineProperty(exports, "getAvailableActions", { enumerable: true, get: function () { return actions_js_1.getAvailableActions; } });
|
|
19
|
+
Object.defineProperty(exports, "PR_ACTIONS", { enumerable: true, get: function () { return actions_js_1.PR_ACTIONS; } });
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,6CAA6C;AAApC,2GAAA,YAAY,OAAA;AACrB,6CAAsD;AAA7C,wGAAA,SAAS,OAAA;AAAE,yGAAA,UAAU,OAAA;AAC9B,yDAAkD;AAAzC,gHAAA,WAAW,OAAA;AACpB,2CAA+D;AAAtD,iHAAA,mBAAmB,OAAA;AAAE,wGAAA,UAAU,OAAA"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PR Analysis Types
|
|
3
|
+
*/
|
|
4
|
+
import type { CheckRun, PullRequest, PullRequestComment, PullRequestReview, Repository } from "@hardlydifficult/github";
|
|
5
|
+
/**
|
|
6
|
+
* Core PR statuses derived purely from GitHub data.
|
|
7
|
+
* Consumers can extend with custom statuses via AnalyzerHooks.
|
|
8
|
+
*/
|
|
9
|
+
export type CorePRStatus = "draft" | "ci_running" | "ci_failed" | "needs_review" | "changes_requested" | "approved" | "has_conflicts" | "ready_to_merge" | "waiting_on_bot";
|
|
10
|
+
/**
|
|
11
|
+
* A PR that has been scanned and analyzed.
|
|
12
|
+
* Status is `string` to allow custom statuses from hooks.
|
|
13
|
+
*/
|
|
14
|
+
export interface ScannedPR {
|
|
15
|
+
readonly pr: PullRequest;
|
|
16
|
+
readonly repo: Repository;
|
|
17
|
+
readonly status: string;
|
|
18
|
+
readonly ciStatus: CIStatus;
|
|
19
|
+
readonly ciSummary: string;
|
|
20
|
+
readonly hasConflicts: boolean;
|
|
21
|
+
readonly waitingOnBot: boolean;
|
|
22
|
+
readonly daysSinceUpdate: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Result of scanning all PRs, classified into buckets
|
|
26
|
+
*/
|
|
27
|
+
export interface ScanResult {
|
|
28
|
+
readonly all: readonly ScannedPR[];
|
|
29
|
+
readonly readyForHuman: readonly ScannedPR[];
|
|
30
|
+
readonly needsBotBump: readonly ScannedPR[];
|
|
31
|
+
readonly inProgress: readonly ScannedPR[];
|
|
32
|
+
readonly blocked: readonly ScannedPR[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* CI status analysis result
|
|
36
|
+
*/
|
|
37
|
+
export interface CIStatus {
|
|
38
|
+
readonly isRunning: boolean;
|
|
39
|
+
readonly hasFailed: boolean;
|
|
40
|
+
readonly allPassed: boolean;
|
|
41
|
+
readonly summary: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A discovered PR with its repository context (used internally by analysis)
|
|
45
|
+
*/
|
|
46
|
+
export interface DiscoveredPR {
|
|
47
|
+
readonly pr: PullRequest;
|
|
48
|
+
readonly repoOwner: string;
|
|
49
|
+
readonly repoName: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Logger interface for pr-analyzer consumers to implement
|
|
53
|
+
*/
|
|
54
|
+
export interface Logger {
|
|
55
|
+
info(message: string, context?: Record<string, unknown>): void;
|
|
56
|
+
error(message: string, context?: Record<string, unknown>): void;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Raw analysis data passed to hooks for custom status resolution.
|
|
60
|
+
*/
|
|
61
|
+
export interface AnalysisDetails {
|
|
62
|
+
readonly comments: readonly PullRequestComment[];
|
|
63
|
+
readonly checks: readonly CheckRun[];
|
|
64
|
+
readonly reviews: readonly PullRequestReview[];
|
|
65
|
+
readonly ciStatus: CIStatus;
|
|
66
|
+
readonly hasConflicts: boolean;
|
|
67
|
+
readonly waitingOnBot: boolean;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Hooks for customizing analysis behavior.
|
|
71
|
+
* Consumers can override status determination with custom logic.
|
|
72
|
+
*/
|
|
73
|
+
export interface AnalyzerHooks {
|
|
74
|
+
/**
|
|
75
|
+
* Called after the core status is determined.
|
|
76
|
+
* Return a custom status string to override, or undefined to keep the core status.
|
|
77
|
+
*/
|
|
78
|
+
readonly resolveStatus?: (coreStatus: CorePRStatus, details: AnalysisDetails) => string | undefined;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Configuration for extending classification buckets with custom statuses.
|
|
82
|
+
*/
|
|
83
|
+
export interface ClassificationConfig {
|
|
84
|
+
readonly readyForHuman?: readonly string[];
|
|
85
|
+
readonly inProgress?: readonly string[];
|
|
86
|
+
readonly blocked?: readonly string[];
|
|
87
|
+
readonly needsBotBump?: readonly string[];
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Definition for a custom action provided by consumers.
|
|
91
|
+
*/
|
|
92
|
+
export interface ActionDefinition {
|
|
93
|
+
readonly type: string;
|
|
94
|
+
readonly label: string;
|
|
95
|
+
readonly description: string;
|
|
96
|
+
readonly when: (pr: ScannedPR, context: Record<string, boolean>) => boolean;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PR Scanning Workflow
|
|
3
|
+
*
|
|
4
|
+
* Scans a single PR by repo and number for real-time event handling.
|
|
5
|
+
*/
|
|
6
|
+
import type { GitHubClient } from "@hardlydifficult/github";
|
|
7
|
+
import type { AnalyzerHooks, ScannedPR } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Scan a single PR by repo and number.
|
|
10
|
+
* Used for real-time event handling - much faster than a full scan.
|
|
11
|
+
*/
|
|
12
|
+
export declare function scanSinglePR(client: GitHubClient, botMention: string, owner: string, repo: string, prNumber: number, hooks?: AnalyzerHooks): Promise<ScannedPR>;
|
|
13
|
+
//# sourceMappingURL=workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../src/workflow.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAG5D,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE3D;;;GAGG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,CAAC,CAGpB"}
|
package/dist/workflow.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PR Scanning Workflow
|
|
4
|
+
*
|
|
5
|
+
* Scans a single PR by repo and number for real-time event handling.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.scanSinglePR = scanSinglePR;
|
|
9
|
+
const analysis_js_1 = require("./analysis.js");
|
|
10
|
+
/**
|
|
11
|
+
* Scan a single PR by repo and number.
|
|
12
|
+
* Used for real-time event handling - much faster than a full scan.
|
|
13
|
+
*/
|
|
14
|
+
async function scanSinglePR(client, botMention, owner, repo, prNumber, hooks) {
|
|
15
|
+
const pr = await client.repo(owner, repo).pr(prNumber).get();
|
|
16
|
+
return (0, analysis_js_1.analyzePR)(client, owner, repo, pr, botMention, hooks);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../src/workflow.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAWH,oCAUC;AAjBD,+CAA0C;AAG1C;;;GAGG;AACI,KAAK,UAAU,YAAY,CAChC,MAAoB,EACpB,UAAkB,EAClB,KAAa,EACb,IAAY,EACZ,QAAgB,EAChB,KAAqB;IAErB,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,CAAC;IAC7D,OAAO,IAAA,uBAAS,EAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;AAC/D,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hardlydifficult/pr-analyzer",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "./dist/index.js",
|
|
5
|
+
"types": "./dist/index.d.ts",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"test": "vitest run",
|
|
12
|
+
"test:watch": "vitest",
|
|
13
|
+
"test:coverage": "vitest run --coverage",
|
|
14
|
+
"lint": "tsc --noEmit",
|
|
15
|
+
"clean": "rm -rf dist"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@hardlydifficult/github": "1.0.22"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "25.2.3",
|
|
22
|
+
"typescript": "5.9.3",
|
|
23
|
+
"vitest": "4.0.18"
|
|
24
|
+
}
|
|
25
|
+
}
|