-
Notifications
You must be signed in to change notification settings - Fork 15
Description
Overview
Analysis of 75 non-test Go files across 22 packages catalogued ~529 functions/methods. The codebase continues to be generally well-organized. Five findings from the previous analysis remain unresolved, and one new finding has been introduced since that run: a new internal/dockerutil/ single-function package that fragments Docker-related utilities.
Full Report
Analysis Metadata
- Total Go Files Analyzed: 75 (72 in
internal/, 3 at root:main.go,tools.go,version.go) - Total Functions Catalogued: ~529
- Packages Analyzed: 22 internal packages
- Outliers Found: 3 (see below)
- Micro-files Found: 5 (see below)
- New Package Fragmentation: 1 (
internal/dockerutil/) - Detection Method: Naming pattern analysis + function signature review + cross-package usage analysis
- Analysis Date: 2026-03-09
- Previous Issue: [refactor] Semantic Function Clustering Analysis — Micro-files, Outlier Functions, and Ad-hoc Utilities #1678 (closed — all findings remain unresolved)
Identified Issues
1. 🔴 internal/tty/ — Two Single-Function Micro-files
Files: internal/tty/tty.go (15 lines) and internal/tty/container.go (35 lines)
Both live in package tty and both detect environment/terminal characteristics. Neither has an import-cycle reason for its own file — the comment in container.go notes the constraint is that tty cannot import logger, which is a package-level constraint, not a file-level constraint.
| File | Function | Lines |
|---|---|---|
tty.go |
IsStderrTerminal() bool |
15 |
container.go |
IsRunningInContainer() bool |
35 |
Recommendation: Merge container.go into tty.go. Total file stays under 55 lines.
Estimated Effort: 10 minutes
Impact: Eliminates one file; both terminal-detection functions are discoverable in one place.
2. 🔴 NEW: internal/dockerutil/env.go — Single-Function Micro-Package
This is a new finding not present in the previous analysis.
File: internal/dockerutil/env.go (41 lines)
Package: dockerutil
Sole Function: ExpandEnvArgs(args []string) []string
Only Caller: internal/mcp/connection.go:128
// internal/dockerutil/env.go — sole function in package
func ExpandEnvArgs(args []string) []string {
// Converts "-e VAR_NAME" to "-e VAR_NAME=value" by reading process environment
}// internal/mcp/connection.go:128 — only call site
expandedArgs := dockerutil.ExpandEnvArgs(args)Problem: Creating an entire package for a single utility function used in only one place adds unnecessary fragmentation and import overhead. The repository already has internal/config/docker_helpers.go (115 lines) with Docker-related utilities (checkDockerAccessible, validateContainerID, runDockerInspect, checkPortMapping, checkStdinInteractive, checkLogDirMounted).
Options:
- Move to
internal/config/docker_helpers.go— consolidates all Docker utilities in one place. Update caller toconfig.ExpandEnvArgs(args). - Move to
internal/mcp/connection.go— since it has exactly one caller, make it a private local helper (expandEnvArgs). Most minimal change.
Recommendation: Option 2 (inline as private helper in mcp/connection.go) — it has one caller, is 20 lines of logic, and has no reason to be independently importable. If Docker env expansion logic grows, revisit.
Estimated Effort: 20 minutes
Impact: Removes one package, clarifies ownership.
3. 🟡 internal/auth/header.go:TruncateSessionID — Outlier Utility in Auth Package
File: internal/auth/header.go:172
Function:
func TruncateSessionID(sessionID string) string {
if sessionID == "" {
return "(none)"
}
if len(sessionID) <= 8 {
return sessionID
}
return sessionID[:8] + "..."
}Callers: internal/server/sdk_logging.go (5 call sites — all logging calls)
Problem: This is a string utility (truncate for safe logging), not an authentication concern. The repository already has internal/strutil/truncate.go with Truncate() and TruncateWithSuffix(). The function's purpose — safe session ID display in logs — is orthogonal to header parsing.
Comparison:
// strutil.TruncateWithSuffix (existing) — only differences are
// the "(none)" empty-string handling and the hardcoded 8-char limit
func TruncateWithSuffix(s string, maxLen int, suffix string) string { ... }Recommendation: Move TruncateSessionID to internal/strutil/truncate.go. Update sdk_logging.go to import strutil instead of auth for this function. Keep the function name and behaviour identical.
Estimated Effort: 20 minutes
Impact: Single source of truth for truncation; auth package stays focused on authentication logic.
4. 🟡 internal/server/transport.go — Misleading Filename
File: internal/server/transport.go (54 lines)
Sole Public Function: CreateHTTPServerForMCP(addr string, unifiedServer *UnifiedServer, apiKey string) *http.Server
Problem: The name "transport" implies a low-level transport protocol concern. Compare the asymmetry:
| File | Function | Mode |
|---|---|---|
transport.go |
CreateHTTPServerForMCP |
Unified |
routed.go |
CreateHTTPServerForRoutedMode |
Routed |
Both are HTTP server factory functions. One lives in a mode-named file, the other in a generic "transport" file. The actual MCP transport layer is in internal/mcp/http_transport.go, making the name doubly confusing.
Recommendation: Rename transport.go → unified_server.go (or http_server_unified.go) to mirror routed.go. The logger variable logTransport would need renaming to avoid conflict with logUnified in unified.go — use logHTTPServer instead.
Estimated Effort: 15 minutes
Impact: Consistent naming across server factory files; easier discovery.
5. 🟡 internal/cmd/root.go — Config Output Functions Are Outliers
File: internal/cmd/root.go (648 lines)
Misplaced Functions (lines ~481–587):
writeGatewayConfigToStdout(cfg, listenAddr, mode string) error(line 481, 3 lines)writeGatewayConfig(cfg, listenAddr, mode string, w io.Writer) error(line 485, ~90 lines)loadEnvFile(path string) error(line 587, ~35 lines)
Problem: root.go's responsibility is CLI wiring (run, preRun, postRun, Execute). writeGatewayConfig is a ~90-line config serialization routine that builds and writes JSON per spec §5.4. This is a serialization concern, not a CLI lifecycle concern.
Recommendation: Extract to internal/cmd/config_output.go. This mirrors the existing pattern of split responsibility files in internal/cmd/ (flags_core.go, flags_logging.go, flags_difc.go, flags_launch.go).
Estimated Effort: 30 minutes
Impact: Reduces root.go from 648 → ~525 lines; config output logic is more discoverable.
6. 🟢 internal/cmd/flags_launch.go — Single-Flag Micro-file
File: internal/cmd/flags_launch.go (21 lines)
Content: One constant (defaultSequentialLaunch), one variable (sequentialLaunch), and an init() block.
Observation: The pattern of flags_*.go files is intentional in this codebase for feature-specific flag grouping. However, flags_launch.go has only a single flag compared to flags_core.go (47 lines), flags_logging.go (55 lines), and flags_difc.go (236 lines). It adds a file with negligible organizational benefit.
Recommendation: Merge into internal/cmd/flags.go (99 lines). Resulting file would be ~120 lines — still reasonable. Alternatively, keep if launch-specific flags are expected to grow.
Estimated Effort: 10 minutes
Impact: Minor — reduces file count by one.
7. 🟢 internal/config/config_payload.go — Thin Constants File
File: internal/config/config_payload.go (30 lines)
Content: 3 exported constants (DefaultPayloadDir, DefaultLogDir, DefaultPayloadSizeThreshold) + 1 init() function (10 lines) registering a DefaultsSetter.
Recommendation: Merge constants and init() into internal/config/config_core.go (307 lines → ~337 lines, still manageable). The constants define operational defaults, not a distinct feature concern.
Estimated Effort: 15 minutes
Impact: Reduces file count; groups operational defaults with core config definitions.
Well-Organized Patterns (No Changes Needed)
internal/logger/: 12 files with clear separation (file logger, slog adapter, sanitize, RPC formatters).global_helpers.gocorrectly centralizes init/close.internal/difc/: DIFC labels/evaluator/resource split is semantically clear; no outliers.internal/config/: Theconfig_*.gofeature-per-file naming pattern is consistently applied.internal/mcp/:connection.go+http_transport.gosplit correctly isolates HTTP-specific transport complexity.internal/cmd/flags_*.go: ThegetDefault*()helper pattern is intentional (documented inflags.go).internal/launcher/log_helpers.go: 126-line logging helper file is tightly coupled to launcher state — appropriate placement.
Summary of Recommendations
| Priority | Finding | File(s) | Effort |
|---|---|---|---|
| 🔴 High | Merge tty/ micro-files |
container.go → tty.go |
10 min |
| 🔴 High | Remove single-function dockerutil package |
dockerutil/env.go → inline in mcp/connection.go |
20 min |
| 🟡 Medium | Move TruncateSessionID to strutil |
auth/header.go:172 → strutil/truncate.go |
20 min |
| 🟡 Medium | Rename transport.go to unified_server.go |
server/transport.go |
15 min |
| 🟡 Medium | Extract config output from root.go |
root.go → config_output.go |
30 min |
| 🟢 Low | Merge flags_launch.go into flags.go |
cmd/flags_launch.go |
10 min |
| 🟢 Low | Merge config_payload.go into config_core.go |
config/config_payload.go |
15 min |
Total Estimated Effort: ~2 hours
Implementation Checklist
- Merge
internal/tty/container.gointointernal/tty/tty.go - Move
dockerutil.ExpandEnvArgsinline tointernal/mcp/connection.go; deleteinternal/dockerutil/package - Move
TruncateSessionIDfrominternal/auth/header.gotointernal/strutil/truncate.go; update callers - Rename
internal/server/transport.go→unified_server.go(verify logger var naming) - Extract
writeGatewayConfig*frominternal/cmd/root.gotointernal/cmd/config_output.go - Merge
internal/cmd/flags_launch.gointointernal/cmd/flags.go - Merge
internal/config/config_payload.goconstants intoconfig_core.go - Run
make agent-finishedafter each change to verify no regressions
References:
- §22874653737
- §22829753438 (previous analysis run)
Generated by Semantic Function Refactoring · ◷