diff --git a/.github/workflows/dataflow-pr-discussion-dataset.lock.yml b/.github/workflows/dataflow-pr-discussion-dataset.lock.yml index c23a4a8fcb0..d723308c4c1 100644 --- a/.github/workflows/dataflow-pr-discussion-dataset.lock.yml +++ b/.github/workflows/dataflow-pr-discussion-dataset.lock.yml @@ -687,12 +687,12 @@ jobs: # Extract discussions and normalize structure echo "$RESULT" | jq -r ' - .data.repository.discussions.nodes + .data.repository.discussions.nodes | map({ - number, + number, title, body, - createdAt, + createdAt, updatedAt, url, category: .category.name, diff --git a/.github/workflows/deep-report.lock.yml b/.github/workflows/deep-report.lock.yml index 1b86f1c7a58..17ece588b4a 100644 --- a/.github/workflows/deep-report.lock.yml +++ b/.github/workflows/deep-report.lock.yml @@ -708,12 +708,12 @@ jobs: # Extract discussions and normalize structure echo "$RESULT" | jq -r ' - .data.repository.discussions.nodes + .data.repository.discussions.nodes | map({ - number, + number, title, body, - createdAt, + createdAt, updatedAt, url, category: .category.name, diff --git a/.github/workflows/issue-monster.lock.yml b/.github/workflows/issue-monster.lock.yml index 33e2a3bc25b..135e6d3b123 100644 --- a/.github/workflows/issue-monster.lock.yml +++ b/.github/workflows/issue-monster.lock.yml @@ -2283,8 +2283,8 @@ jobs: } // Exclude issues with open PRs from Copilot coding agent - const openCopilotPRs = issue.linkedPRs?.filter(pr => - pr.state === 'OPEN' && + const openCopilotPRs = issue.linkedPRs?.filter(pr => + pr.state === 'OPEN' && (pr.author === 'copilot-swe-agent' || pr.author?.includes('copilot')) ) || []; if (openCopilotPRs.length > 0) { diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 052f240f239..eff1812073d 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -454,11 +454,11 @@ jobs: 5. **Tavily Web Search Testing**: Use the Tavily MCP server to perform a web search for "GitHub Agentic Workflows" and verify that results are returned with at least one item 6. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-claude-__GH_AW_GITHUB_RUN_ID__.txt` with content "Smoke test passed for Claude at $(date)" (create the directory if it doesn't exist) 7. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) - 8. **Discussion Interaction Testing**: + 8. **Discussion Interaction Testing**: - Use `gh api repos/__GH_AW_GITHUB_REPOSITORY__/discussions?per_page=1` to get the latest discussion from __GH_AW_GITHUB_REPOSITORY__ - Extract the discussion number from the result (e.g., if the result is `{"number": 123, "title": "...", ...}`, extract 123) - Use the `add_comment` tool with `discussion_number: ` to add a fun, comic-book style comment stating that the smoke test agent was here - 9. **Agentic Workflows MCP Testing**: + 9. **Agentic Workflows MCP Testing**: - Call the `agentic-workflows` MCP tool using the `status` method with workflow name `smoke-claude` to query workflow status - If the tool returns an error or no results, mark this test as ❌ and note "Tool unavailable or workflow not found" but continue to the Output section - If the tool succeeds, extract key information from the response: total runs, success/failure counts, last run timestamp @@ -496,7 +496,7 @@ jobs: - Note: This will bundle all review comments from test #14 - After submitting, use the GitHub MCP tool to list review threads on the PR and note the thread IDs from review comments you created in test #14 — these will be used in test #16 - 16. **Resolve Review Thread Testing**: + 16. **Resolve Review Thread Testing**: - Use the GitHub MCP tool to list review threads on the PR and filter for threads that are **not yet resolved** (`isResolved: false`) - Prefer resolving a thread created by your own review comments from test #14 in this run - Use `thread_id: ""` from one of those unresolved threads @@ -508,7 +508,7 @@ jobs: - Verify the tool call succeeds - Note: May fail if reviewer is already assigned or doesn't have access - 18. **Push to PR Branch Testing**: + 18. **Push to PR Branch Testing**: - Create a test file at `smoke-test-files/smoke-claude-push-test.md` in the repository workspace with content "Smoke test push — Run __GH_AW_GITHUB_RUN_ID__" - Use the `push_to_pull_request_branch` tool to push this change - Use `pr_number: ` and `commit_message: "test: Add smoke test file"` diff --git a/pkg/linters/deferinloop/deferinloop.go b/pkg/linters/deferinloop/deferinloop.go index 6709a8c8292..243f5640ba6 100644 --- a/pkg/linters/deferinloop/deferinloop.go +++ b/pkg/linters/deferinloop/deferinloop.go @@ -18,7 +18,7 @@ import ( "github.com/github/gh-aw/pkg/logger" ) -var log = logger.New("linters:deferinloop") +var pkgLog = logger.New("linters:deferinloop") // Analyzer is the defer-in-loop analysis pass. var Analyzer = &analysis.Analyzer{ @@ -30,7 +30,7 @@ var Analyzer = &analysis.Analyzer{ } func run(pass *analysis.Pass) (any, error) { - log.Printf("analyzing package %s", pass.Pkg.Path()) + pkgLog.Printf("analyzing package %s", pass.Pkg.Path()) insp, err := astutil.Inspector(pass) if err != nil { @@ -56,7 +56,7 @@ func run(pass *analysis.Pass) (any, error) { continue } - log.Printf("flagging defer inside loop at %s", pos) + pkgLog.Printf("flagging defer inside loop at %s", pos) pass.ReportRangef(deferStmt, "defer inside a loop does not execute at the end of each iteration; it runs when the enclosing function returns, which can cause resource leaks") } diff --git a/pkg/linters/excessivefuncparams/excessivefuncparams.go b/pkg/linters/excessivefuncparams/excessivefuncparams.go index 48d2e089967..1da8c100952 100644 --- a/pkg/linters/excessivefuncparams/excessivefuncparams.go +++ b/pkg/linters/excessivefuncparams/excessivefuncparams.go @@ -14,7 +14,7 @@ import ( "github.com/github/gh-aw/pkg/logger" ) -var log = logger.New("linters:excessivefuncparams") +var pkgLog = logger.New("linters:excessivefuncparams") // DefaultMaxParams is the default maximum number of parameters allowed in a function declaration. const DefaultMaxParams = 8 @@ -37,7 +37,7 @@ func init() { } func run(pass *analysis.Pass) (any, error) { - log.Printf("analyzing package %s (max-params=%d)", pass.Pkg.Path(), maxParams) + pkgLog.Printf("analyzing package %s (max-params=%d)", pass.Pkg.Path(), maxParams) insp, err := astutil.Inspector(pass) if err != nil { @@ -75,7 +75,7 @@ func run(pass *analysis.Pass) (any, error) { if nolint.HasDirective(position, noLintLinesByFile) { return } - log.Printf("flagging %s: %d parameters exceeds limit %d", fn.Name.Name, params, maxParams) + pkgLog.Printf("flagging %s: %d parameters exceeds limit %d", fn.Name.Name, params, maxParams) pass.ReportRangef( fn.Name, "%s has %d parameters (limit: %d); consider using an options struct", diff --git a/pkg/linters/httprespbodyclose/httprespbodyclose.go b/pkg/linters/httprespbodyclose/httprespbodyclose.go index 08b4e04a058..af72ff49c68 100644 --- a/pkg/linters/httprespbodyclose/httprespbodyclose.go +++ b/pkg/linters/httprespbodyclose/httprespbodyclose.go @@ -16,7 +16,7 @@ import ( "github.com/github/gh-aw/pkg/logger" ) -var log = logger.New("linters:httprespbodyclose") +var pkgLog = logger.New("linters:httprespbodyclose") // Analyzer is the http-resp-body-close analysis pass. var Analyzer = &analysis.Analyzer{ @@ -28,7 +28,7 @@ var Analyzer = &analysis.Analyzer{ } func run(pass *analysis.Pass) (any, error) { - log.Printf("analyzing package %s", pass.Pkg.Path()) + pkgLog.Printf("analyzing package %s", pass.Pkg.Path()) insp, err := astutil.Inspector(pass) if err != nil { @@ -177,7 +177,7 @@ type respVarState struct { } func reportMissingDefer(pass *analysis.Pass, state *respVarState) { - log.Printf("flagging non-deferred Body.Close() at %s", pass.Fset.PositionFor(state.assignPos, false)) + pkgLog.Printf("flagging non-deferred Body.Close() at %s", pass.Fset.PositionFor(state.assignPos, false)) diag := analysis.Diagnostic{ Pos: state.assignPos, diff --git a/pkg/linters/httpstatuscode/httpstatuscode.go b/pkg/linters/httpstatuscode/httpstatuscode.go index 42783eec6d5..8902217b2a4 100644 --- a/pkg/linters/httpstatuscode/httpstatuscode.go +++ b/pkg/linters/httpstatuscode/httpstatuscode.go @@ -19,7 +19,7 @@ import ( "github.com/github/gh-aw/pkg/logger" ) -var log = logger.New("linters:httpstatuscode") +var pkgLog = logger.New("linters:httpstatuscode") var Analyzer = &analysis.Analyzer{ Name: "httpstatuscode", @@ -94,7 +94,7 @@ var httpStatusNames = map[int]string{ } func run(pass *analysis.Pass) (any, error) { - log.Printf("analyzing package %s", pass.Pkg.Path()) + pkgLog.Printf("analyzing package %s", pass.Pkg.Path()) root, err := astutil.Root(pass) if err != nil { @@ -154,7 +154,7 @@ func checkAndReport(pass *analysis.Pass, lit *ast.BasicLit, noLintLinesByFile ma return } - log.Printf("flagging magic HTTP status code %d at %s", code, pos) + pkgLog.Printf("flagging magic HTTP status code %d at %s", code, pos) if name, ok := httpStatusNames[code]; ok { pass.Reportf(lit.Pos(), "use %s instead of magic HTTP status code %d", name, code) diff --git a/pkg/linters/largefunc/largefunc.go b/pkg/linters/largefunc/largefunc.go index e63b2a2029c..1fbf005cc48 100644 --- a/pkg/linters/largefunc/largefunc.go +++ b/pkg/linters/largefunc/largefunc.go @@ -14,7 +14,7 @@ import ( "github.com/github/gh-aw/pkg/logger" ) -var log = logger.New("linters:largefunc") +var pkgLog = logger.New("linters:largefunc") // DefaultMaxLines is the default maximum number of lines allowed in a function body. const DefaultMaxLines = 60 @@ -37,7 +37,7 @@ func init() { } func run(pass *analysis.Pass) (any, error) { - log.Printf("analyzing package %s (max-lines=%d)", pass.Pkg.Path(), maxLines) + pkgLog.Printf("analyzing package %s (max-lines=%d)", pass.Pkg.Path(), maxLines) insp, err := astutil.Inspector(pass) if err != nil { @@ -84,7 +84,7 @@ func run(pass *analysis.Pass) (any, error) { if nolint.HasDirective(position, noLintLinesByFile) { return } - log.Printf("flagging %s: %d lines exceeds limit %d", name, lines, maxLines) + pkgLog.Printf("flagging %s: %d lines exceeds limit %d", name, lines, maxLines) pass.ReportRangef( reportNode, "%s is %d lines long (limit: %d); consider breaking it up", diff --git a/pkg/modelsdev/catalog.go b/pkg/modelsdev/catalog.go index d381be13c32..b13cec27ee9 100644 --- a/pkg/modelsdev/catalog.go +++ b/pkg/modelsdev/catalog.go @@ -26,7 +26,7 @@ var catalogURL = "https://models.dev/catalog.json" // differing only in ".", "_", or "-" compare equal. var modelIDReplacer = strings.NewReplacer(".", "-", "_", "-") -var log = logger.New("modelsdev:catalog") +var pkgLog = logger.New("modelsdev:catalog") // rawCatalog mirrors the top-level models.dev catalog JSON structure. type rawCatalog struct { @@ -71,19 +71,19 @@ func FindPricing(ctx context.Context, provider, model string) (map[string]float6 normalizedModel := strings.ToLower(trimmedModel) comparableModel := NormalizeComparableModelID(normalizedModel) - log.Printf("FindPricing: looking up provider=%q model=%q", normalizedProvider, normalizedModel) + pkgLog.Printf("FindPricing: looking up provider=%q model=%q", normalizedProvider, normalizedModel) // Provider-scoped exact match. if normalizedProvider != "" { if providerModels, ok := catalog[normalizedProvider]; ok { if pricing, ok := providerModels[normalizedModel]; ok { - log.Printf("FindPricing: provider-scoped exact match for %q/%q", normalizedProvider, normalizedModel) + pkgLog.Printf("FindPricing: provider-scoped exact match for %q/%q", normalizedProvider, normalizedModel) return pricing, true } // Comparable (dot/underscore-normalized) model ID match. for mn, pricing := range providerModels { if NormalizeComparableModelID(mn) == comparableModel { - log.Printf("FindPricing: provider-scoped comparable match %q for %q", mn, normalizedModel) + pkgLog.Printf("FindPricing: provider-scoped comparable match %q for %q", mn, normalizedModel) return pricing, true } } @@ -93,18 +93,18 @@ func FindPricing(ctx context.Context, provider, model string) (map[string]float6 // Cross-provider fallback (when provider is unknown or empty). for _, providerModels := range catalog { if pricing, ok := providerModels[normalizedModel]; ok { - log.Printf("FindPricing: cross-provider fallback match for model %q", normalizedModel) + pkgLog.Printf("FindPricing: cross-provider fallback match for model %q", normalizedModel) return pricing, true } for mn, pricing := range providerModels { if NormalizeComparableModelID(mn) == comparableModel { - log.Printf("FindPricing: cross-provider comparable match %q for %q", mn, normalizedModel) + pkgLog.Printf("FindPricing: cross-provider comparable match %q for %q", mn, normalizedModel) return pricing, true } } } - log.Printf("FindPricing: no pricing found for provider=%q model=%q", normalizedProvider, normalizedModel) + pkgLog.Printf("FindPricing: no pricing found for provider=%q model=%q", normalizedProvider, normalizedModel) return nil, false } @@ -115,14 +115,14 @@ func ensureCatalog(ctx context.Context) pricingCache { downloaded, _ := catalogCache.Get(func() (pricingCache, error) { downloaded, err := downloadAndParseCatalog(ctx) if err != nil { - log.Printf("models.dev catalog download failed (pricing fallback unavailable): %v", err) + pkgLog.Printf("models.dev catalog download failed (pricing fallback unavailable): %v", err) return pricingCache{}, nil } else { total := 0 for _, models := range downloaded { total += len(models) } - log.Printf("Downloaded models.dev catalog: %d providers, %d total models", len(downloaded), total) + pkgLog.Printf("Downloaded models.dev catalog: %d providers, %d total models", len(downloaded), total) } return downloaded, nil })