Commit f175240eb2ef
dots/pi/agent/extensions/github/actions/checks.ts
@@ -76,6 +76,7 @@ export async function handleChecks(
/**
* Get failed check logs
+ * Accepts either runId or PR number
*/
export async function handleChecksLog(
pi: ExtensionAPI,
@@ -84,17 +85,61 @@ export async function handleChecksLog(
onUpdate: any,
ctx: ExtensionContext,
): Promise<any> {
- if (!params.runId) {
+ let runId = params.runId;
+
+ // If no runId but a PR number is provided, get the first failed run
+ if (!runId && params.number) {
+ onUpdate?.({ content: [{ type: "text", text: `Finding failed runs for PR #${params.number}...` }] });
+
+ // Get checks for the PR
+ const checksResult = await execGh(pi, ctx,
+ ["pr", "view", String(params.number), "--json", "statusCheckRollup"],
+ { signal, timeout: 30000 },
+ );
+
+ if (checksResult.code !== 0) {
+ return {
+ content: [{ type: "text", text: getErrorMessage(checksResult.stderr, "Get PR checks") }],
+ details: { action: "checks-log", error: checksResult.stderr, prNumber: params.number } as GhDetails,
+ isError: true,
+ };
+ }
+
+ const checks = parseChecks(checksResult.stdout);
+
+ // Find first failed check with a workflow run ID
+ const failedCheck = checks.find((c) =>
+ c.conclusion === "FAILURE" && c.detailsUrl && c.detailsUrl.includes("/runs/")
+ );
+
+ if (failedCheck && failedCheck.detailsUrl) {
+ // Extract run ID from URL (e.g., https://github.com/owner/repo/actions/runs/123456)
+ const match = failedCheck.detailsUrl.match(/\/runs\/(\d+)/);
+ if (match) {
+ runId = parseInt(match[1], 10);
+ }
+ }
+
+ if (!runId) {
+ return {
+ content: [{ type: "text", text: `No failed workflow runs found for PR #${params.number}` }],
+ details: { action: "checks-log", error: "no_failed_runs", prNumber: params.number } as GhDetails,
+ isError: true,
+ };
+ }
+ }
+
+ if (!runId) {
return {
- content: [{ type: "text", text: "Error: 'runId' parameter is required for checks-log action" }],
+ content: [{ type: "text", text: "Error: Either 'runId' or 'number' (PR number) parameter is required for checks-log action" }],
details: { action: "checks-log", error: "missing_run_id" } as GhDetails,
isError: true,
};
}
- onUpdate?.({ content: [{ type: "text", text: `Fetching logs for run ${params.runId}...` }] });
+ onUpdate?.({ content: [{ type: "text", text: `Fetching logs for run ${runId}...` }] });
- const result = await execGh(pi, ctx, ["run", "view", String(params.runId), "--log-failed"], {
+ const result = await execGh(pi, ctx, ["run", "view", String(runId), "--log-failed"], {
signal,
timeout: 60000,
});
@@ -103,13 +148,13 @@ export async function handleChecksLog(
// If --log-failed has no output, try regular log
if (result.stderr.includes("no failed jobs")) {
return {
- content: [{ type: "text", text: `No failed jobs in run ${params.runId}` }],
- details: { action: "checks-log", output: "No failed jobs", runId: params.runId } as GhDetails,
+ content: [{ type: "text", text: `No failed jobs in run ${runId}` }],
+ details: { action: "checks-log", output: "No failed jobs", runId, prNumber: params.number } as GhDetails,
};
}
return {
content: [{ type: "text", text: getErrorMessage(result.stderr, "Get run logs") }],
- details: { action: "checks-log", error: result.stderr, runId: params.runId } as GhDetails,
+ details: { action: "checks-log", error: result.stderr, runId, prNumber: params.number } as GhDetails,
isError: true,
};
}
@@ -123,7 +168,7 @@ export async function handleChecksLog(
return {
content: [{ type: "text", text: output }],
- details: { action: "checks-log", output: `Run ${params.runId} logs (${logs.length} chars)`, runId: params.runId } as GhDetails,
+ details: { action: "checks-log", output: `Run ${runId} logs (${logs.length} chars)`, runId, prNumber: params.number } as GhDetails,
};
}
dots/pi/agent/extensions/github/index.ts
@@ -157,6 +157,7 @@ export default function (pi: ExtensionAPI) {
"Use pr-review-comments to submit a review (approve/request-changes/comment) with multiple inline comments at once. " +
"Use pr-reviews-list/pr-review-edit to list and edit top-level review bodies. " +
"Use pr-review-comments-list/pr-review-comment-edit/pr-review-comment-delete to manage inline review comments. " +
+ "Use checks-log with either runId or number (PR number) to get failed check logs - if PR number is provided, the first failed run will be used. " +
"Write operations (create, merge, review, comment, close, restart, edit, delete) require user approval.",
parameters: Type.Object({