Skip to content

Conversation

@newhook
Copy link
Owner

@newhook newhook commented Jan 29, 2026

Summary

This PR adds interfaces to packages that wrap external CLI tools (git, mise, github, zellij, beads) to enable unit testing without external dependencies. Each package now has a testable interface that can be mocked in tests.

Changes

internal/git

  • Added Operations interface with 7 methods: PushSetUpstream, Pull, Clone, FetchBranch, BranchExists, ValidateExistingBranch, ListBranches
  • Created cliOperations struct implementing the interface
  • Added Default variable for the standard implementation
  • Kept existing package-level functions as wrappers (marked deprecated) for backward compatibility

internal/mise

  • Added Operations interface with 8 methods: IsManaged, Trust, Install, HasTask, RunTask, Exec, Initialize, InitializeWithOutput
  • Created cliOperations struct implementing the interface
  • Added Default variable for the standard implementation
  • Kept existing package-level functions as wrappers (marked deprecated) for backward compatibility

internal/github

  • Added ClientInterface with 6 methods: GetPRStatus, PostPRComment, PostReplyToComment, PostReviewReply, ResolveReviewThread, GetJobLogs
  • Added compile-time check ensuring *Client implements ClientInterface
  • Updated call sites in internal/feedback to use interface instead of concrete type

internal/zellij

  • Added ClientInterface covering all session, tab, and pane operations (25 methods)
  • Added compile-time check ensuring *Client implements ClientInterface
  • Updated call site in internal/tui/tui_plan.go to use interface

internal/beads (new file: cli.go)

  • Added CLI interface for bd command operations: Init, InstallHooks, Create, Close, Reopen, Update, AddComment, AddLabels, SetExternalRef, AddDependency
  • Added Reader interface for database queries: GetBead, GetBeadsWithDeps, ListBeads, GetReadyBeads, GetTransitiveDependencies, GetBeadWithChildren
  • Created cliImpl struct with DefaultCLI variable
  • Added compile-time check ensuring *Client implements Reader

Issues Resolved

  • ac-eepp: Extract interfaces for testability (Epic)
  • ac-eepp.1: Add Operations interface to internal/git
  • ac-eepp.2: Add Operations interface to internal/mise
  • ac-eepp.3: Add ClientInterface to internal/github
  • ac-eepp.4: Add ClientInterface to internal/zellij
  • ac-eepp.5: Add CLI and Reader interfaces to internal/beads

Testing

  • All existing package-level functions continue to work unchanged (backward compatible)
  • Compile-time interface checks verify implementations are correct
  • No breaking changes to existing code

Notes

  • Existing package-level functions are marked as deprecated but remain functional
  • Tests can now inject mock implementations via the interface variables (e.g., git.Default, mise.Default, beads.DefaultCLI)

🤖 Generated with Claude Code

newhook and others added 9 commits January 28, 2026 23:48
- Define Operations interface with 7 methods (PushSetUpstream, Pull, Clone, FetchBranch, BranchExists, ValidateExistingBranch, ListBranches)
- Create cliOperations struct implementing the interface
- Add Default variable for production use
- Keep existing functions as wrappers for backward compatibility

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Define Operations interface with 8 methods (IsManaged, Trust, Install, HasTask, RunTask, Exec, Initialize, InitializeWithOutput)
- Create cliOperations struct implementing the interface
- Add Default variable for production use
- Keep existing functions as wrappers for backward compatibility

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Define ClientInterface with 6 methods (GetPRStatus, PostPRComment, PostReplyToComment, PostReviewReply, ResolveReviewThread, GetJobLogs)
- Add compile-time check that Client implements ClientInterface
- Update internal/feedback to accept interface instead of *Client

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Define ClientInterface covering session, tab, and pane operations
- Add compile-time check that Client implements ClientInterface
- Update internal/tui to accept interface instead of *Client

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Created cli.go with:
- CLI interface for bd command operations (Init, InstallHooks, Create,
  Close, Reopen, Update, AddComment, AddLabels, SetExternalRef, AddDependency)
- Reader interface for database queries (GetBead, GetBeadsWithDeps,
  ListBeads, GetReadyBeads, GetTransitiveDependencies, GetBeadWithChildren)
- cliImpl struct implementing CLI using the bd command
- DefaultCLI variable for the default implementation
- Compile-time check that Client implements Reader

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Move beadsDir from method parameters to struct field, matching the
Reader/Client pattern. Init and InstallHooks remain package-level
functions as they're setup operations.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Move dir from method parameters to struct field, matching the
beads CLI pattern. Package-level functions remain for convenience.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
SessionManager handles session lifecycle (list, create, delete).
Session is bound to a specific session name and handles tabs, panes,
and input operations without repeating the session parameter.

ClientInterface remains for backward compatibility, embedding both.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Callers now use m.zj.Session(session).Method() pattern instead of
passing session to each method call.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@newhook newhook merged commit 5ed4ffd into main Jan 29, 2026
3 checks passed
@newhook newhook deleted the feat/extract-interfaces-for-testability branch January 29, 2026 14:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants