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
This analysis examined 229 non-test Go files (~207k lines of code) in the pkg/ directory to identify type consistency issues and opportunities for stronger typing. The codebase demonstrates excellent practices in some areas (minimal interface{} usage, strong semantic types in pkg/constants/constants.go), but has significant opportunities for improvement in others.
Key Findings:
✅ Excellent: Only 3 occurrences of interface{} (mostly in test files)
⚠️Needs Attention: 3,727 occurrences of any type, primarily as map[string]any for YAML/JSON handling
⚠️Duplicate Found: MCPServerConfig type defined in two locations with different field structures
✅ Best Practice Example: pkg/constants/constants.go shows excellent use of semantic types (LineLength, Version, time.Duration)
Impact Assessment:
High Priority: Replace map[string]any with structured types in frequently-used frontmatter parsing functions
Medium Priority: Consolidate duplicate MCPServerConfig type
Low Priority: Leverage semantic type patterns from constants.go across other packages
Full Analysis Report
Analysis Scope
Files Analyzed: 229 non-test Go files Total Lines: ~207,000 lines of code Primary Directory: pkg/ Detection Methods:
Serena semantic analysis for type definitions
Pattern matching for interface{} and any keywords
Symbol search for common type name patterns (Config, Options, Data)
Duplicated Type Definitions
Summary Statistics
Total unique types analyzed: 532+ type definitions
Duplicate clusters found: 1 confirmed
Exact duplicates: 0
Semantic duplicates: 1 (MCPServerConfig)
Cluster 1: MCPServerConfig - Semantic Duplicate
Type: Semantic duplicate with different field structures Occurrences: 2 Impact: Medium - Same name, different purposes
Locations:
pkg/cli/mcp_config_file.go:14-18 - Simple version for CLI config
pkg/parser/mcp.go:65-79 - Comprehensive version for workflow parsing
typeMCPServerConfigstruct {
Namestring`json:"name"`Typestring`json:"type"`// stdio, http, dockerRegistrystring`json:"registry"`// URI to installation locationCommandstring`json:"command"`// for stdioArgs []string`json:"args"`// for stdioContainerstring`json:"container"`// for dockerVersionstring`json:"version"`// optional version/tagEntrypointArgs []string`json:"entrypointArgs"`// arguments after containerURLstring`json:"url"`// for httpHeadersmap[string]string`json:"headers"`// for httpEnvmap[string]string`json:"env"`// environment variablesProxyArgs []string`json:"proxy-args"`// custom proxy argumentsAllowed []string`json:"allowed"`// allowed tools
}
Analysis:
These are not duplicates - they serve different purposes and have different field sets
The CLI version is a minimal config for local MCP server connections
The parser version is comprehensive for workflow-based MCP server definitions
Different packages, different contexts = intentional separation
Recommendation:
✅ No action needed - These are correctly separated by purpose
Consider renaming to clarify intent:
pkg/cli/mcp_config_file.go: Rename to LocalMCPServerConfig or SimpleMCPServerConfig
pkg/parser/mcp.go: Rename to WorkflowMCPServerConfig or keep as MCPServerConfig
uses, hasUses:=stepMap["uses"]
usesStr, ok:=uses.(string) // Type assertion needed
Actual usage: Always operates on GitHub Actions step structures
Suggested fix:
// Define a structured type for GitHub Actions stepstypeGitHubActionsStepstruct {
Namestring`yaml:"name,omitempty"`IDstring`yaml:"id,omitempty"`Ifstring`yaml:"if,omitempty"`Usesstring`yaml:"uses,omitempty"`Runstring`yaml:"run,omitempty"`Envmap[string]string`yaml:"env,omitempty"`Withmap[string]interface{} `yaml:"with,omitempty"`// Still needs flexibility for action inputs
}
funcApplyActionPinToStep(stepGitHubActionsStep, data*WorkflowData) GitHubActionsStep {
ifstep.Uses=="" {
returnstep
}
// No type assertions needed!// ... rest of logic
}
Benefits:
✅ No type assertions required
✅ Compile-time validation of field access
✅ Better IDE autocomplete
✅ Self-documenting API
Trade-off: ⚠️ Less flexible for unexpected fields (but those can go in a map[string]any "extra" field if needed)
Usage: Called for extracting tools, mcp, runtimes from frontmatter
Suggested fix: Use generic types with structured returns
// Define structured types for known frontmatter sectionstypeFrontmatterToolsstruct {
GitHub*GitHubToolConfig`yaml:"github,omitempty"`Bash*BashToolConfig`yaml:"bash,omitempty"`Playwright*PlaywrightToolConfig`yaml:"playwright,omitempty"`// ... other toolsCustommap[string]any`yaml:",inline"`// Catch-all for unknown tools
}
funcextractToolsFromFrontmatter(frontmattermap[string]any) (*FrontmatterTools, error) {
toolsData, exists:=frontmatter["tools"]
if!exists {
return&FrontmatterTools{}, nil
}
// Marshal back to YAML and unmarshal into structured type// This gives us both structure AND flexibilityyamlBytes, _:=yaml.Marshal(toolsData)
vartoolsFrontmatterToolsiferr:=yaml.Unmarshal(yamlBytes, &tools); err!=nil {
returnnil, err
}
return&tools, nil
}
Benefits:
✅ Structured access to known fields
✅ Still supports unknown/custom fields via Custom map[string]any
✅ Validation happens at unmarshal time
✅ Clear API for consumers
Example 3: Function Parameters with any
High-frequency pattern: Functions accepting any for JSON-like data
Analysis: This is a reasonable use of any because:
It's a generic serialization utility
Accepts any JSON-serializable value
Not part of a type-checked API
Recommendation: ✅ Keep as-is but add documentation:
// saveTrialResult serializes any JSON-marshallable value to a file.// The result parameter accepts any type that can be marshaled to JSON.funcsaveTrialResult(filenamestring, resultany, verbosebool) error
Category 3: Best Practices - Learn from constants.go
Location: pkg/constants/constants.go Impact: Inspiration for the rest of the codebase
Excellent patterns demonstrated:
Semantic Types for Clarity:
// LineLength represents a line length in characterstypeLineLengthint// Version represents a software version stringtypeVersionstringconstMaxExpressionLineLengthLineLength=120constDefaultClaudeCodeVersionVersion="2.0.44"
time.Duration for Time Values:
// Uses time.Duration for type safety and clear unitsconstDefaultAgenticWorkflowTimeout=20*time.MinuteconstDefaultToolTimeout=60*time.Second
Deprecation Strategy:
// Deprecated: Use DefaultToolTimeout insteadconstDefaultToolTimeoutSeconds=int(DefaultToolTimeout/time.Second)
Recommendation: Apply these patterns elsewhere!
Refactoring Recommendations
Priority 1: High - Document map[string]any Usage
Recommendation: Add clear documentation to all functions using map[string]any
Rationale:
Complete replacement would be a massive refactor (100+ functions)
Current pattern works but lacks documentation
Quick win: Document what structure is expected
Steps:
Audit all functions accepting/returning map[string]any
Add comments describing expected structure
Add examples in comments
Example:
// extractMapFromFrontmatter extracts a nested map from workflow frontmatter.// Expected frontmatter structure:// tools:// github:// allowed: [...]// bash:// enabled: true// Returns an empty map if key doesn't exist or isn't a map.funcextractMapFromFrontmatter(frontmattermap[string]any, keystring) map[string]any
Estimated effort: 4-6 hours Impact: Medium - Better maintainability with minimal risk
Priority 2: Medium - Create Structured Types for Common Patterns
Recommendation: Introduce structured types for the most frequently accessed map[string]any patterns
Target areas:
GitHub Actions step structures (high usage in pkg/workflow/action_pins.go, pkg/workflow/tools.go)
Frontmatter sections (tools, mcp, safe-outputs)
Runtime configurations
Steps:
Define GitHubActionsStep struct with common fields + Extra map[string]any
Define FrontmatterConfig struct with known sections + Custom map[string]any
Estimated effort: 12-16 hours Impact: High - Significantly improved type safety in core functions
Priority 3: Low - Expand Semantic Types Pattern
Recommendation: Apply pkg/constants/constants.go patterns to other packages
Opportunities:
Create semantic types in pkg/workflow:
package workflow
// JobName represents a GitHub Actions job identifiertypeJobNamestring// StepID represents a step identifier within a jobtypeStepIDstringconstAgentJobNameJobName="agent"constActivationJobNameJobName="activation"
Time values in pkg/cli:
package cli
// PollInterval represents a duration between poll attemptstypePollInterval time.DurationconstDefaultPollIntervalPollInterval=5*time.Second
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: githubnext/gh-aw
Executive Summary
This analysis examined 229 non-test Go files (~207k lines of code) in the
pkg/directory to identify type consistency issues and opportunities for stronger typing. The codebase demonstrates excellent practices in some areas (minimalinterface{}usage, strong semantic types inpkg/constants/constants.go), but has significant opportunities for improvement in others.Key Findings:
interface{}(mostly in test files)anytype, primarily asmap[string]anyfor YAML/JSON handlingMCPServerConfigtype defined in two locations with different field structurespkg/constants/constants.goshows excellent use of semantic types (LineLength,Version,time.Duration)Impact Assessment:
map[string]anywith structured types in frequently-used frontmatter parsing functionsMCPServerConfigtypeFull Analysis Report
Analysis Scope
Files Analyzed: 229 non-test Go files
Total Lines: ~207,000 lines of code
Primary Directory:
pkg/Detection Methods:
interface{}andanykeywordsDuplicated Type Definitions
Summary Statistics
Cluster 1: MCPServerConfig - Semantic Duplicate
Type: Semantic duplicate with different field structures
Occurrences: 2
Impact: Medium - Same name, different purposes
Locations:
pkg/cli/mcp_config_file.go:14-18- Simple version for CLI configpkg/parser/mcp.go:65-79- Comprehensive version for workflow parsingAnalysis:
Recommendation:
pkg/cli/mcp_config_file.go: Rename toLocalMCPServerConfigorSimpleMCPServerConfigpkg/parser/mcp.go: Rename toWorkflowMCPServerConfigor keep asMCPServerConfigUntyped Usages
Summary Statistics
interface{}usages: 3 (excellent! mostly in test files)anyusages: 3,727 (primarilymap[string]anyfor YAML/JSON)map[string]anyfor dynamic frontmatter/YAML parsingCategory 1: map[string]any for YAML/JSON Handling
Impact: High - Core pattern used throughout workflow compilation
Prevalence: Dominant pattern in ~100+ functions across
pkg/workflowandpkg/cliContext: Why map[string]any is Used
The codebase processes GitHub Actions workflows written in YAML with dynamic frontmatter. The
map[string]anypattern is used because:map[string]anyby default for unknown structuresThis is a classic trade-off: flexibility vs. type safety.
Example 1: ApplyActionPinToStep Function
pkg/workflow/action_pins.go:141Actual usage: Always operates on GitHub Actions step structures
Suggested fix:
map[string]any"extra" field if needed)Example 2: extractMapFromFrontmatter Function
pkg/workflow/tools.go:154Usage: Called for extracting
tools,mcp,runtimesfrom frontmatterSuggested fix: Use generic types with structured returns
Custom map[string]anyExample 3: Function Parameters with any
High-frequency pattern: Functions accepting
anyfor JSON-like dataLocations with this pattern:
pkg/workflow/runtime_setup.go:detectFromMCPConfigs(tools map[string]any, ...)pkg/workflow/runtime_setup.go:applyRuntimeOverrides(runtimes map[string]any, ...)pkg/workflow/runtime_setup.go:formatYAMLValue(value any) stringpkg/cli/trial_command.go:parseJSONArtifact(filePath string, ...) map[string]anypkg/cli/trial_command.go:saveTrialResult(filename string, result any, ...) errorCommon pattern: Generic utility functions that need to handle arbitrary data
Recommendation: These are acceptable uses of
anyfor truly generic utilities, BUT:formatYAMLValue, could use type switch with known typesCategory 2: Legitimate any Usage
Impact: Low - Appropriate use for generic utilities
Example: saveTrialResult Function
Analysis: This is a reasonable use of
anybecause:Recommendation: ✅ Keep as-is but add documentation:
Category 3: Best Practices - Learn from constants.go
Location:
pkg/constants/constants.goImpact: Inspiration for the rest of the codebase
Excellent patterns demonstrated:
Recommendation: Apply these patterns elsewhere!
Refactoring Recommendations
Priority 1: High - Document map[string]any Usage
Recommendation: Add clear documentation to all functions using
map[string]anyRationale:
Steps:
map[string]anyExample:
Estimated effort: 4-6 hours
Impact: Medium - Better maintainability with minimal risk
Priority 2: Medium - Create Structured Types for Common Patterns
Recommendation: Introduce structured types for the most frequently accessed
map[string]anypatternsTarget areas:
pkg/workflow/action_pins.go,pkg/workflow/tools.go)tools,mcp,safe-outputs)Steps:
GitHubActionsStepstruct with common fields +Extra map[string]anyFrontmatterConfigstruct with known sections +Custom map[string]anymap[string]any↔ structured typesExample migration path:
Estimated effort: 12-16 hours
Impact: High - Significantly improved type safety in core functions
Priority 3: Low - Expand Semantic Types Pattern
Recommendation: Apply
pkg/constants/constants.gopatterns to other packagesOpportunities:
Estimated effort: 3-4 hours
Impact: Medium - Clearer APIs, better compile-time checks
Priority 4: Low - Rename MCPServerConfig Types
Recommendation: Clarify naming for the two MCPServerConfig types
Changes:
pkg/cli/mcp_config_file.go:LocalMCPServerConfigpkg/parser/mcp.go: KeepMCPServerConfig(it's the canonical version)Estimated effort: 30 minutes
Impact: Low - Clearer intent, prevents confusion
Implementation Checklist
P1: Add documentation to
map[string]anyfunctions (4-6 hours)extractMapFromFrontmatterand related functionsApplyActionPinToStepexpected structureP2: Create structured types for common patterns (12-16 hours)
GitHubActionsStepstructFrontmatterConfigstructP3: Expand semantic types pattern (3-4 hours)
JobName,StepIDtypes in workflow packagePollIntervaltype in cli packageRuntimeTypeenumP4: Rename MCPServerConfig types (30 minutes)
pkg/cli/mcp_config_file.goAnalysis Metadata
interface{}, 3,727any)map[string]anyfor YAML/JSON frontmatter handlingKey Takeaways
What's Working Well ✅
map[string]anyusage is consistent (not random)What Needs Improvement⚠️
map[string]anyfunctions lack structure documentationRecommended Approach 🎯
Start small, prove value, scale up:
Philosophy: The codebase is mature and working. Don't break what works. Instead, incrementally improve type safety where it adds the most value.
Beta Was this translation helpful? Give feedback.
All reactions