Agent generated files.

This commit is contained in:
Christian Gunderman
2026-04-22 17:28:53 -07:00
parent 1ab09fb428
commit 9109505145
17 changed files with 1402 additions and 4 deletions
@@ -0,0 +1,56 @@
/**
* @license
* Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { execSync } from 'node:child_process';
try {
const query = `
query($owner: String!, $repo: String!) {
repository(owner: $owner, name: $repo) {
pullRequests(first: 100, states: OPEN) {
nodes {
number
authorAssociation
reviewDecision
commits(last: 1) {
nodes {
commit {
statusCheckRollup {
state
}
}
}
}
}
}
}
}
`;
const output = execSync(`gh api graphql -F owner=google-gemini -F repo=gemini-cli -f query='${query}'`, { encoding: 'utf-8' });
const data = JSON.parse(output).data.repository;
const prs = data.pullRequests.nodes;
const communityPrs = prs.filter(p => !['MEMBER', 'OWNER', 'COLLABORATOR'].includes(p.authorAssociation));
const waitingForReview = communityPrs.filter(p => p.reviewDecision === 'REVIEW_REQUIRED' && p.commits.nodes[0]?.commit?.statusCheckRollup?.state === 'SUCCESS');
console.log(`Total Community PRs: ${communityPrs.length}`);
console.log(`Community PRs with SUCCESS CI waiting for Review: ${waitingForReview.length}`);
} catch (err) {
console.error('Error analyzing community PRs:', err);
process.exit(1);
}
@@ -0,0 +1,36 @@
/**
* @license
* Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { execSync } from 'node:child_process';
try {
const output = execSync(`gh issue list --state open --json number,labels,assignees,comments --limit 1000`, { encoding: 'utf-8' });
const issues = JSON.parse(output);
const untriaged = issues.filter(i => i.labels.some(l => l.name === 'status/need-triage')).length;
const unassigned = issues.filter(i => i.assignees.length === 0).length;
const noComments = issues.filter(i => i.comments.length === 0).length;
console.log(`Total Open Issues: ${issues.length}`);
console.log(`Untriaged Issues: ${untriaged}`);
console.log(`Unassigned Issues: ${unassigned}`);
console.log(`Issues with 0 Comments: ${noComments}`);
} catch (err) {
console.error('Error analyzing issues:', err);
process.exit(1);
}
@@ -0,0 +1,49 @@
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { execSync } from 'node:child_process';
async function run() {
try {
const output = execSync(`gh issue list --state open --label "status/need-triage" --json number,title,author,comments,createdAt --limit 1000`, { encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 });
const issues = JSON.parse(output);
const userCounts = {};
const ageStats = {
lessThanWeek: 0,
oneToFourWeeks: 0,
olderThanMonth: 0
};
const now = new Date();
for (const issue of issues) {
const login = issue.author.login;
userCounts[login] = (userCounts[login] || 0) + 1;
const createdAt = new Date(issue.createdAt);
const daysOld = (now.getTime() - createdAt.getTime()) / (1000 * 60 * 60 * 24);
if (daysOld < 7) ageStats.lessThanWeek++;
else if (daysOld < 30) ageStats.oneToFourWeeks++;
else ageStats.olderThanMonth++;
}
const topUsers = Object.entries(userCounts)
.sort((a, b) => b[1] - a[1])
.slice(0, 10);
console.log(`Total Untriaged Issues: ${issues.length}`);
console.log('Age Stats:', ageStats);
console.log('Top Reporters for Untriaged Issues:', topUsers);
} catch (err) {
console.error('Error analyzing untriaged issues:', err);
process.exit(1);
}
}
run();
@@ -0,0 +1,83 @@
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { execSync } from 'node:child_process';
async function run() {
try {
const query = `
query($owner: String!, $repo: String!) {
repository(owner: $owner, name: $repo) {
pullRequests(first: 100, states: OPEN) {
nodes {
number
author { login }
authorAssociation
mergeable
reviewDecision
commits(last: 1) {
nodes {
commit {
statusCheckRollup {
state
}
}
}
}
}
}
}
}
`;
const output = execSync(`gh api graphql -F owner=google-gemini -F repo=gemini-cli -f query='${query}'`, { encoding: 'utf-8' });
const data = JSON.parse(output).data.repository;
const prs = data.pullRequests.nodes;
const communityPrs = prs.filter(p => !['MEMBER', 'OWNER', 'COLLABORATOR'].includes(p.authorAssociation));
const stats = {
conflicting: 0,
mergeable: 0,
unknown: 0,
reviewRequired: 0,
approved: 0,
changesRequested: 0,
ciSuccess: 0,
ciFailure: 0,
ciPending: 0,
readyForReview: 0
};
for (const p of communityPrs) {
const isMergeable = p.mergeable === 'MERGEABLE';
const ciState = p.commits?.nodes[0]?.commit?.statusCheckRollup?.state;
const isCiSuccess = ciState === 'SUCCESS';
if (p.mergeable === 'CONFLICTING') stats.conflicting++;
else if (isMergeable) stats.mergeable++;
else stats.unknown++;
if (p.reviewDecision === 'REVIEW_REQUIRED') stats.reviewRequired++;
else if (p.reviewDecision === 'APPROVED') stats.approved++;
else if (p.reviewDecision === 'CHANGES_REQUESTED') stats.changesRequested++;
if (isCiSuccess) stats.ciSuccess++;
else if (ciState === 'FAILURE') stats.ciFailure++;
else stats.ciPending++;
if (isMergeable && isCiSuccess && p.reviewDecision === 'REVIEW_REQUIRED') {
stats.readyForReview++;
}
}
console.log('Stats for Community PRs:', stats);
} catch (err) {
console.error('Error checking merge conflicts:', err);
process.exit(1);
}
}
run();
@@ -0,0 +1,116 @@
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { execSync } from 'node:child_process';
import { createObjectCsvWriter } from 'csv-writer';
async function run() {
try {
// 1. Community PRs
const prQuery = `
query($owner: String!, $repo: String!) {
repository(owner: $owner, name: $repo) {
pullRequests(first: 100, states: OPEN) {
nodes {
number
author { login }
authorAssociation
mergeable
reviewDecision
commits(last: 1) {
nodes {
commit {
statusCheckRollup {
state
}
}
}
}
}
}
}
}
`;
const prOutput = execSync(`gh api graphql -F owner=google-gemini -F repo=gemini-cli -f query='${prQuery}'`, { encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 });
const prs = JSON.parse(prOutput).data.repository.pullRequests.nodes;
const communityPrs = prs.filter(p => !['MEMBER', 'OWNER', 'COLLABORATOR'].includes(p.authorAssociation));
const stalePrs = communityPrs.filter(p => p.mergeable === 'CONFLICTING').map(p => ({
number: p.number,
author: p.author?.login,
reason: 'Merge Conflict'
}));
const readyPrs = communityPrs.filter(p => p.mergeable === 'MERGEABLE' && p.commits?.nodes[0]?.commit?.statusCheckRollup?.state === 'SUCCESS' && p.reviewDecision === 'REVIEW_REQUIRED').map(p => ({
number: p.number,
author: p.author?.login,
reason: 'Mergeable + CI Success + Needs Review'
}));
const staleWriter = createObjectCsvWriter({
path: 'author_stale_prs.csv',
header: [
{id: 'number', title: 'number'},
{id: 'author', title: 'author'},
{id: 'reason', title: 'reason'}
]
});
await staleWriter.writeRecords(stalePrs);
const readyWriter = createObjectCsvWriter({
path: 'ready_for_review_prs.csv',
header: [
{id: 'number', title: 'number'},
{id: 'author', title: 'author'},
{id: 'reason', title: 'reason'}
]
});
await readyWriter.writeRecords(readyPrs);
// 2. Untriaged Issues
const issueQuery = `
query($owner: String!, $repo: String!) {
repository(owner: $owner, name: $repo) {
issues(first: 100, states: OPEN, labels: ["status/need-triage"]) {
nodes {
number
title
body
author { login }
}
}
}
}
`;
const issueOutput = execSync(`gh api graphql -F owner=google-gemini -F repo=gemini-cli -f query='${issueQuery}'`, { encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 });
const issues = JSON.parse(issueOutput).data.repository.issues.nodes;
const highQualityIssues = issues.filter(i => (i.body?.length || 0) > 200 && (i.title?.length || 0) > 20).map(i => ({
number: i.number,
author: i.author?.login,
reason: 'High quality content (>200 chars body, >20 chars title)'
}));
const issueWriter = createObjectCsvWriter({
path: 'untriaged_high_quality.csv',
header: [
{id: 'number', title: 'number'},
{id: 'author', title: 'author'},
{id: 'reason', title: 'reason'}
]
});
await issueWriter.writeRecords(highQualityIssues);
console.log('Generated author_stale_prs.csv, ready_for_review_prs.csv, and untriaged_high_quality.csv');
} catch (err) {
console.error('Error generating CSVs:', err);
process.exit(1);
}
}
run();