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: this codebase has remarkably strong type discipline. Sweeping every non‐test .go file under pkg/ — ~705 files in pkg/workflow + pkg/cli alone, plus pkg/parser, pkg/console, pkg/types, pkg/constants, pkg/agentdrain and ~20 util packages — I collected 676 top‐level type definitions across 673 unique names. The duplicate‐type problem this audit usually uncovers basically isn't here: only 3 type names collide across files, and all 3 are intentional WebAssembly build‐tag variants (ProgressBar, SpinnerWrapper, RepositoryFeatures). Zero accidental duplicate types to consolidate — a genuinely nice result.
The opportunity is on the untyped side, and it's nuanced. There are zero bare interface{} usages (the code consistently uses the modern any alias) — also great. But there are ~2,600 map[string]any / []any usages and ~100 untyped exported constants. Most of the any maps are idiomatic and correct — they live at YAML/JSON frontmatter boundaries where dynamic shape is unavoidable. The real wins are narrow: (1) any‐typed frontmatter helpers that immediately do cascading type assertions, which one typed Frontmatter struct could clean up, and (2) untyped constants in pkg/constants/ — a near‐zero‐cost typing win.
Full Analysis Report
Duplicated Type Definitions
Summary Statistics
Total type definitions: 676 · Unique names: 673
Name collisions (same name, 2+ non‐test files): 3
Real duplicates to consolidate (exact/near/semantic): 0
All three collisions are the native vs. WebAssembly build‐tag pattern (selected at compile time via //go:build / _wasm.go). These are the correct idiom for platform‐specific types — leave as‐is:
Type
Locations
Why it's fine
ProgressBar
pkg/console/progress.go:31 vs progress_wasm.go:7
Full TUI vs lightweight WASM output
SpinnerWrapper
pkg/console/spinner.go:96 vs spinner_wasm.go:10
Full TUI vs no‐op WASM stub
RepositoryFeatures
pkg/workflow/repository_features_validation.go:58 vs ..._wasm.go:5
Real vs disabled validation in WASM
Recommendation: No duplicate‐type work needed. The type layer is in great shape.
Untyped Usages
Summary Statistics
Category
Approx. count
Verdict
Bare interface{}
0
✅ Clean — uses any alias
Bare any (params/returns/fields)
~700+
⚠️ Mostly boundary code; a subset improvable
map[...]any / []any
~2,600
i️ Overwhelmingly idiomatic YAML/JSON boundaries
Untyped exported constants
~100
⚠️ Cheapest, highest‐clarity win
Counts are approximate (parallel per‐package scans; the any vs map[...]any split varies by scanner). The conclusions hold: bare interface{} is genuinely absent, map‐of‐any dominates, untyped constants number in the dozens‐to‐~100.
Category 1 — any params in frontmatter parsers (the real opportunity)
Impact: High. A handful of helpers accept any, then cascade .(type) assertions to recover a known shape. Typed wrappers move errors to compile time.
// pkg/workflow/engine.go:166,178,191 — only ever int|string|nilfuncparseMaxEffectiveTokensValue(rawany) int64funcparseMaxRunsValue(rawany) intfuncparseMaxTurnsValue(rawany) string// pkg/workflow/known_needs_expressions.go:125 — customJobs is really map[string]*JobfuncfilterExpressionsForActivation(..., customJobsmap[string]any, ...) []*ExpressionMapping// pkg/cli/codemod_*.go — repeated ~dozens of times; each re-asserts nested keysApply: func(contentstring, frontmattermap[string]any) (string, bool, error)
// pkg/cli/codemod_permissions_write.go:44 — known scopes -> read|write|noneifm, ok:=permissionsValue.(map[string]any); ok { ... }
// type PermissionScope string; type PermissionLevel string// type Permissions map[PermissionScope]PermissionLevel
A single (even partial) typed Frontmatter struct with a custom unmarshaler would remove the most‐repeated assertion pattern in pkg/cli.
Impact: Medium · Effort: Low. Explicit types document intent and prevent accidental numeric promotion. Concentrated in pkg/constants/:
// pkg/constants/constants.goconstDefaultGitHubLockdown=false// -> boolconstDefaultMCPGatewayPayloadSizeThreshold=524288// -> int64 (bytes)// pkg/constants/job_constants.goconstDefaultRateLimitMax=5// -> intconstDefaultRateLimitWindow=60// -> int (minutes)// pkg/workflow/safe_outputs_validation_config.goconstMaxBodyLength=65000// -> int// pkg/workflow/repo_memory.goconstdefaultRepoMemoryMaxFileSize=102400// -> int64 (bytes)// pkg/cli/audit_cross_run.goconstmcpErrorRateThreshold=0.10// -> named float64 (ratio)// pkg/cli/forecast_montecarlo.goconstmonteCarloIterations=10_000// -> int
For unit‐carrying values, a named type (type Bytes int64, type Minutes int) adds semantic safety; otherwise an explicit primitive type is enough.
Category 3 — any struct fields (mostly justified)
FormField.Value (pkg/console/console_types.go:46) and InputDefinition.Default (pkg/types/input_definition.go:18) hold genuinely heterogeneous values. Recommendation is documentation (or generics, e.g. FormField[T any]) rather than forcing a concrete type.
What I deliberately did NOT flag
The large body of map[string]any / []any at true serialization boundaries — YAML unmarshaling, frontmatter hashing/marshaling, GitHub API decoding, template data maps — is idiomatic Go. Converting it would fight the serialization layer for no safety gain. It makes up the bulk of the ~2,600 count and is intentionally out of scope.
Refactoring Recommendations
Priority 1 (High impact): Type the frontmatter boundary. Define a (partial) Frontmatter struct or focused sub‐structs (Permissions, SafeOutputs, Tools) with a custom unmarshaler; migrate codemod_*.goApply functions and pkg/workflowparse*Value helpers off raw map[string]any assertions. Effort: high.
Priority 2 (High impact): Replace any params where the shape is known — e.g. filterExpressionsForActivation (map[string]any → map[string]*Job) and the numeric parse*Value helpers. Effort: medium.
Priority 3 (Low effort): Add explicit types to untyped constants in pkg/constants/ and friends; use named unit types for byte/minute/ratio values. Impact: medium.
Implementation Checklist
Confirm no duplicate‐type work needed (3 collisions are intentional build‐tag variants) ✅
Define a typed Frontmatter (or sub‐structs) for the codemod Apply boundary
Migrate pkg/cli/codemod_*.go Apply functions off raw map[string]any assertions
Type pkg/workflowparse*Value helpers and filterExpressionsForActivation
Add explicit types (incl. named unit types) to untyped constants
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: this codebase has remarkably strong type discipline. Sweeping every non‐test
.gofile underpkg/— ~705 files inpkg/workflow+pkg/clialone, pluspkg/parser,pkg/console,pkg/types,pkg/constants,pkg/agentdrainand ~20 util packages — I collected 676 top‐level type definitions across 673 unique names. The duplicate‐type problem this audit usually uncovers basically isn't here: only 3 type names collide across files, and all 3 are intentional WebAssembly build‐tag variants (ProgressBar,SpinnerWrapper,RepositoryFeatures). Zero accidental duplicate types to consolidate — a genuinely nice result.The opportunity is on the untyped side, and it's nuanced. There are zero bare
interface{}usages (the code consistently uses the modernanyalias) — also great. But there are ~2,600map[string]any/[]anyusages and ~100 untyped exported constants. Most of theanymaps are idiomatic and correct — they live at YAML/JSON frontmatter boundaries where dynamic shape is unavoidable. The real wins are narrow: (1)any‐typed frontmatter helpers that immediately do cascading type assertions, which one typedFrontmatterstruct could clean up, and (2) untyped constants inpkg/constants/— a near‐zero‐cost typing win.Full Analysis Report
Duplicated Type Definitions
Summary Statistics
Result: No accidental duplication found ✅
All three collisions are the native vs. WebAssembly build‐tag pattern (selected at compile time via
//go:build/_wasm.go). These are the correct idiom for platform‐specific types — leave as‐is:ProgressBarpkg/console/progress.go:31vsprogress_wasm.go:7SpinnerWrapperpkg/console/spinner.go:96vsspinner_wasm.go:10RepositoryFeaturespkg/workflow/repository_features_validation.go:58vs..._wasm.go:5Recommendation: No duplicate‐type work needed. The type layer is in great shape.
Untyped Usages
Summary Statistics
interface{}anyaliasany(params/returns/fields)map[...]any/[]anyCategory 1 —
anyparams in frontmatter parsers (the real opportunity)Impact: High. A handful of helpers accept
any, then cascade.(type)assertions to recover a known shape. Typed wrappers move errors to compile time.A single (even partial) typed
Frontmatterstruct with a custom unmarshaler would remove the most‐repeated assertion pattern inpkg/cli.Category 2 — Untyped exported constants (cheapest win)
Impact: Medium · Effort: Low. Explicit types document intent and prevent accidental numeric promotion. Concentrated in
pkg/constants/:For unit‐carrying values, a named type (
type Bytes int64,type Minutes int) adds semantic safety; otherwise an explicit primitive type is enough.Category 3 —
anystruct fields (mostly justified)FormField.Value(pkg/console/console_types.go:46) andInputDefinition.Default(pkg/types/input_definition.go:18) hold genuinely heterogeneous values. Recommendation is documentation (or generics, e.g.FormField[T any]) rather than forcing a concrete type.What I deliberately did NOT flag
The large body of
map[string]any/[]anyat true serialization boundaries — YAML unmarshaling, frontmatter hashing/marshaling, GitHub API decoding, template data maps — is idiomatic Go. Converting it would fight the serialization layer for no safety gain. It makes up the bulk of the ~2,600 count and is intentionally out of scope.Refactoring Recommendations
Frontmatterstruct or focused sub‐structs (Permissions,SafeOutputs,Tools) with a custom unmarshaler; migratecodemod_*.goApplyfunctions andpkg/workflowparse*Valuehelpers off rawmap[string]anyassertions. Effort: high.anyparams where the shape is known — e.g.filterExpressionsForActivation(map[string]any→map[string]*Job) and the numericparse*Valuehelpers. Effort: medium.pkg/constants/and friends; use named unit types for byte/minute/ratio values. Impact: medium.Implementation Checklist
Frontmatter(or sub‐structs) for the codemodApplyboundarypkg/cli/codemod_*.goApply functions off rawmap[string]anyassertionspkg/workflowparse*Valuehelpers andfilterExpressionsForActivationmap[string]any/[]anyas‐is (intentional)Analysis Metadata
pkg/workflow(395) +pkg/cli(310), pluspkg/parser(43),pkg/console(26),pkg/agentdrain,pkg/types,pkg/constants, ~20 util packages (non‐test)interface{}, ~2,600map[...]any/[]any(mostly idiomatic), ~100 untyped constantsBeta Was this translation helpful? Give feedback.
All reactions