You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Good news first: gh-aw is already an unusually well-typed Go codebase. I scanned 920 non-test .go files under pkg/ (~740 named types) and found zero raw interface{} literals in production code β the project uniformly uses any, and the large majority of its ~2,850 any occurrences are genuinely dynamic (YAML frontmatter, GitHub/GraphQL JSON, MCP/JSON-RPC, generic conversion helpers). Plenty of domain enums already exist (PermissionLevel, EngineName, OutcomeStatus, ShellType). So this is a polish pass, not a rescue.
That said, the wins are real: one exact duplicate (AntigravityResponse/GeminiResponse, byte-for-byte identical), 9 near-duplicate structs (clustered in CLI logs/audit and the action-pinning manifest, where the same data is modeled twice), and a pattern of implicit string-enum constants β plain string fields switched against a fixed literal set. The three highest-value enum fixes (console.CompilerError.Type, cli.ArgumentType, github.MultiLabelLogic) each harden a field that is actively dispatched on, so a typo like "warn" silently hits a default branch today.
Full Analysis Report
Duplicated Type Definitions
Stats: ~740 types Β· 13 clusters reported (1 exact, 9 near, 3 semantic; 3 more excluded as intentional).
Cluster 1 β CLI-response struct (EXACT, High): pkg/workflow/antigravity_logs.go:13AntigravityResponse is identical to pkg/workflow/gemini_logs.go:13GeminiResponse β same {Response string; Stats map[string]any} incl. json tags. Fix: one shared CLIJSONResponse + shared ParseLogMetrics helper. ~1h.
Cluster 2 β Action-pinning manifest (NEAR, High): actionpins/actionpins.goContainerPin(:46)/ResolutionFailure(:74)/ActionPin(:38) duplicated by workflow/safe_update_manifest.goGHAWManifestContainer(:32)/GHAWManifestResolutionFailure(:40)/GHAWManifestAction(:23). Fix: reuse actionpins types, convert at JSON boundary. 2β3h.
Cluster 3 β MCP tool-usage container (NEAR, High): cli/audit_report.go:163MCPToolUsageData vs cli/logs_models.go:178MCPToolUsageSummary β same slices, former adds optional *GuardPolicySummary. Fix: merge with omitempty. 1β2h.
Cluster 4 β Domain/firewall analysis (NEAR, High): cli/access_log.go:33DomainAnalysis vs cli/firewall_log.go:131FirewallAnalysis β both embed DomainBuckets + total + allowed/blocked pair, near-identical AddMetrics. Fix: shared embedded base; firewall keeps RequestsByDomain. 2β3h.
Clusters 5β13 (medium / low)
5 (Near, med)cli/logs_report_firewall.go:12AccessLogSummary vs :22FirewallLogSummary β collapse once Cluster 4 is unified.
6 (Near, med)cli/access_log.go:19AccessLogEntry vs cli/firewall_log.go:116FirewallLogEntry β overlapping string proxy-log records; OK to keep separate given distinct formats.
7 (Near, med)cli/logs_models.go:148MissingToolSummary vs :167MissingDataSummary β identical but the key field. Extract embedded base; MCPFailureSummary (:158) shares a subset.
Stats: raw interface{} in production = 0 Β· any ~2,850 (mostly legit-dynamic, excluded) Β· 16 implicit-enum/const opportunities.
gh-aw correctly uses any for dynamic data (frontmatter, GitHub/GraphQL JSON, MCP/JSON-RPC, generic helpers) β not flagged. Opportunities are string-enum constants and the fields they back.
Category 1 β stringly-typed fields actively switched on (High):
pkg/console/console_types.go:13CompilerError.Type string (error/warning/info) becomes type ErrorSeverity string. Dispatched at console.go:42, console_wasm.go:19; set raw in ~6 sites. Prevents typo to silent default.
pkg/cli/mcp_registry_types.go:71Argument.Type string (consts at :113-116) becomes type ArgumentType string. Compared at mcp_registry.go:171,180.
pkg/github/label_objective_mapping.go:27MultiLabelLogic string (sum/max/first; consts at constants.go:136-140) becomes type MultiLabelLogic string; switched at :65-94; replace literal default at :62.
Category 2 β implicit string-enum const groups (Medium):
cli/outcomes_history.go:19-23 historySource{Issues,PRs,All} β type HistorySource string
cli/env_command.go:24-28 defaultsScope{Repo,Org,Ent} β type DefaultsScope string
parser/json_path_locator.go:226PathSegment.Type (key/index, verified closed) β type PathSegmentKind string
workflow/mcp_scripts_parser.go:36-38Mode (http/stdio) β type MCPScriptsMode string
cli/mcp_registry_types.go:107-110 Status{Active,Inactive} β type ServerStatus string
Category 3 β lower-impact (8)
console/console_types.go:42FormField.Type β type FormFieldType string
cli/logs_safe_output_chains.go:15-19 temporaryIDMapStatus β type TemporaryIDMapStatus string
parser/mcp.go:179safeOutputToolName 10-literal switch β type SafeOutputToolName string (boundary values)
cli/gateway_logs_types.go:61-68 guardPolicyErrorCode -32001..-32006 β type GuardPolicyErrorCode int
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
π€ Typist β Go Type Consistency Analysis
Analysis of repository: github/gh-aw
Executive Summary
Good news first: gh-aw is already an unusually well-typed Go codebase. I scanned 920 non-test
.gofiles underpkg/(~740 named types) and found zero rawinterface{}literals in production code β the project uniformly usesany, and the large majority of its ~2,850anyoccurrences are genuinely dynamic (YAML frontmatter, GitHub/GraphQL JSON, MCP/JSON-RPC, generic conversion helpers). Plenty of domain enums already exist (PermissionLevel,EngineName,OutcomeStatus,ShellType). So this is a polish pass, not a rescue.That said, the wins are real: one exact duplicate (
AntigravityResponse/GeminiResponse, byte-for-byte identical), 9 near-duplicate structs (clustered in CLI logs/audit and the action-pinning manifest, where the same data is modeled twice), and a pattern of implicit string-enum constants β plainstringfields switched against a fixed literal set. The three highest-value enum fixes (console.CompilerError.Type,cli.ArgumentType,github.MultiLabelLogic) each harden a field that is actively dispatched on, so a typo like"warn"silently hits a default branch today.Full Analysis Report
Duplicated Type Definitions
Stats: ~740 types Β· 13 clusters reported (1 exact, 9 near, 3 semantic; 3 more excluded as intentional).
Cluster 1 β CLI-response struct (EXACT, High):
pkg/workflow/antigravity_logs.go:13AntigravityResponseis identical topkg/workflow/gemini_logs.go:13GeminiResponseβ same{Response string; Stats map[string]any}incl. json tags. Fix: one sharedCLIJSONResponse+ sharedParseLogMetricshelper. ~1h.Cluster 2 β Action-pinning manifest (NEAR, High):
actionpins/actionpins.goContainerPin(:46)/ResolutionFailure(:74)/ActionPin(:38) duplicated byworkflow/safe_update_manifest.goGHAWManifestContainer(:32)/GHAWManifestResolutionFailure(:40)/GHAWManifestAction(:23). Fix: reuse actionpins types, convert at JSON boundary. 2β3h.Cluster 3 β MCP tool-usage container (NEAR, High):
cli/audit_report.go:163MCPToolUsageDatavscli/logs_models.go:178MCPToolUsageSummaryβ same slices, former adds optional*GuardPolicySummary. Fix: merge withomitempty. 1β2h.Cluster 4 β Domain/firewall analysis (NEAR, High):
cli/access_log.go:33DomainAnalysisvscli/firewall_log.go:131FirewallAnalysisβ both embedDomainBuckets+ total + allowed/blocked pair, near-identicalAddMetrics. Fix: shared embedded base; firewall keepsRequestsByDomain. 2β3h.Clusters 5β13 (medium / low)
cli/logs_report_firewall.go:12AccessLogSummaryvs:22FirewallLogSummaryβ collapse once Cluster 4 is unified.cli/access_log.go:19AccessLogEntryvscli/firewall_log.go:116FirewallLogEntryβ overlapping string proxy-log records; OK to keep separate given distinct formats.cli/logs_models.go:148MissingToolSummaryvs:167MissingDataSummaryβ identical but the key field. Extract embedded base;MCPFailureSummary(:158) shares a subset.cli/logs_models.go:110/119/127/138(MissingToolReport,NoopReport,MissingDataReport,MCPFailureReport) shareTimestamp,WorkflowName string; RunID int64. ExtractReportProvenance.cli/audit_report.go:200MCPServerStats,cli/audit_expanded.go:89MCPServerHealthDetail,cli/audit_cross_run.go:81MCPServerCrossRunHealthβ 3 projections of per-server health; define canonical metric type.workflow/compiler_types.go:431SkipIfMatchConfigvs:438SkipIfNoMatchConfigβ differ only Max/Min; shared{Query,Scope}base.workflow/update_entity_helpers.go:100UpdateEntityJobParamsvsworkflow/close_entity_helpers.go:90CloseEntityJobParamsβ share 5 fields; extract base.cli/audit_comparison.go:44AuditComparisonIntDeltavs:50AuditComparisonStringDeltaβ replace with genericDelta[T comparable].intent/resolver.go:49PullRequestData,cli/pr_command.go:27PRInfo,cli/pr_automerge.go:21PullRequestβ 3 PR models; OK but worth a shared DTO audit.RepositoryFeatures,SpinnerWrapper,ProgressBar); MCP config already consolidated aroundtypes.BaseMCPServerConfig.Untyped Usages
Stats: raw
interface{}in production = 0 Β·any~2,850 (mostly legit-dynamic, excluded) Β· 16 implicit-enum/const opportunities.Category 1 β stringly-typed fields actively switched on (High):
pkg/console/console_types.go:13CompilerError.Type string(error/warning/info) becomestype ErrorSeverity string. Dispatched atconsole.go:42,console_wasm.go:19; set raw in ~6 sites. Prevents typo to silent default.pkg/cli/mcp_registry_types.go:71Argument.Type string(consts at :113-116) becomestype ArgumentType string. Compared atmcp_registry.go:171,180.pkg/github/label_objective_mapping.go:27MultiLabelLogic string(sum/max/first; consts at constants.go:136-140) becomestype MultiLabelLogic string; switched at :65-94; replace literal default at :62.Category 2 β implicit string-enum const groups (Medium):
cli/outcomes_history.go:19-23historySource{Issues,PRs,All} βtype HistorySource stringcli/env_command.go:24-28defaultsScope{Repo,Org,Ent} βtype DefaultsScope stringparser/json_path_locator.go:226PathSegment.Type(key/index, verified closed) βtype PathSegmentKind stringworkflow/mcp_scripts_parser.go:36-38Mode(http/stdio) βtype MCPScriptsMode stringcli/mcp_registry_types.go:107-110Status{Active,Inactive} βtype ServerStatus stringCategory 3 β lower-impact (8)
console/console_types.go:42FormField.Typeβtype FormFieldType stringcli/logs_safe_output_chains.go:15-19temporaryIDMapStatus βtype TemporaryIDMapStatus stringparser/mcp.go:179safeOutputToolName10-literal switch βtype SafeOutputToolName string(boundary values)cli/gateway_logs_types.go:61-68guardPolicyErrorCode -32001..-32006 βtype GuardPolicyErrorCode intparser/import_field_extractor.go:1097declared-type switch βtype InputType string(field stays string, dynamic YAML)workflow/safe_jobs_needs_validation.go:174-178unvisited/visiting/visited βtype visitState int+ iotacli/import_url_fetcher.go:204-209segment labels mixed with a count β splittype urlSegment stringparser/remote_fetch.go:914fetchRemoteFileContent(... any)β*remoteFileContent struct(sole call site passes concrete; marginal, mirrors api.RESTClient.Get)Refactoring Recommendations (prioritized)
AntigravityResponse/GeminiResponseintoCLIJSONResponse. ~1h, low risk.ErrorSeverity/ArgumentType/MultiLabelLogicnamed types + update call sites. 2β4h.pkg/clilogs/audit near-duplicates via shared embedded bases (ReportProvenance, domain-analysis base, per-server metric) and mergeMCPToolUsage*. ~1 day.Implementation Checklist
AntigravityResponse+GeminiResponseintoCLIJSONResponseErrorSeverity/ArgumentType/MultiLabelLogictypes + update fields/call sitesDomainAnalysis/FirewallAnalysis(+ summaries) via shared baseMCPToolUsageData/MCPToolUsageSummaryReportProvenancefor the four agentic report recordsactionpinstypes in workflow manifest codego build ./...+ full test suite after each refactorMetadata: 920 files Β· ~740 types Β· 13 duplicate clusters Β· 16 untyped findings Β· 0 raw
interface{}Β· Serena semantic analysis + structural matching + reference tracing Β· 2026-06-17References: Β§27689495906
Beta Was this translation helpful? Give feedback.
All reactions