refactor: split oversized functions (update 1555L, runNormalMode 648L, New 502L)
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 134
- Forks
- 24
- Avg merge
- 8h 59m
- Merged PRs (30d)
- 23
Description
Summary
Function lengths below are exact, measured via AST (not brace-counting). Each bullet should be its own PR, in the listed order — smallest and most mechanical first.
Sequence
pkg/kit/extensions_bridge.go:24bridgeExtensions— 390 lines. Registers tools, commands, widgets, themes and shortcuts in one function. Split per registration concern. Low risk, mechanical.cmd/root.go:973runNormalMode— 648 lines. Sequential phases (logging, prefs, MCP config, kit options, session setup, TUI launch) that extract cleanly into phase functions. Then group the 47-fieldrunModeDeps(cmd/root.go:1723) into ~3 sub-structs (bridge getters / static snapshot / action funcs).internal/agent/agent.go:611GenerateWithCallbacks— 434 lines. Split the streaming vs non-streaming fork intogenerateStreaming/generateSimple. Pairs naturally with theHasAnyCallback()helper.pkg/kit/kit.go:1500New— 502 lines. Private phase funcs (applyOptions,resolveModelConfig,initExtensions); public signature unchanged. Covered bykit_test.go,bare_test.go,viper_isolation_test.go.internal/ui/model.go:1652update— 1555 lines, ~99 case labels. Its own dedicated PR, nothing bundled. Delegate per-domain to handler methods living in the existingstream.go/message_nav.go/ etc. Highest leverage, highest regression surface; lean onmodel_test.go(1377 lines),children_test.go,message_nav_test.go.
Other >100-line functions exist (70 total; internal/ui/input.go:275 Update 328, cmd/extension_context.go:40 328, pkg/kit/kit.go:2684 generate 295, internal/extensions/runner.go:177 normalizeContext 284) but are lower priority.
Constraints — these would reintroduce known pitfalls
- Do not convert
extensions.Context(84 fields,internal/extensions/api.go:47) to an interface. Yaegi cannot synthesise interfaces at runtime (genInterfaceWrappernil deref); the function-field design is deliberate. - Do not refactor anything on the
View/distributeHeightmeasurement path while splittingmodel.go— height must be measured through the same render path asView(), so changes there are high-risk and low-reward. - Preserve the
go appInstance.NotifyWidgetUpdate()async pattern; never introduce a synchronousprog.Send()insideUpdate().
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
For a first PR, start at pkg/kit/extensions_bridge.go:24 and inspect bridgeExtensions alongside its registration concerns. Keep the listed sequence and constraints in view; for the kit.New and UI work, use kit_test.go, bare_test.go, viper_isolation_test.go, model_test.go, children_test.go, and message_nav_test.go to verify behavior remains covered.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cli, developer-experience, tooling
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100