feat: expose teamsctl as a public Go SDK - #14
Merged
Conversation
Move the Teams client out of internal/ into pkg/ (teamsauth + teamsctl) so other Go projects can import it, and export the service API: ResolveConversationTarget, ResolveIndividualTargets, FindOneOnOneConversation, FindGroupConversation, Me/Identity, and the Message/SendOptions types. CLI and MCP wiring stay internal and consume the pkg packages. Backfill the message author for the signed-in user: Teams leaves imDisplayName empty on your own messages, so Messages now substitutes the account's display name when the sender MRI matches (directly, or derived from objectId), and exposes sender_id.
There was a problem hiding this comment.
Pull request overview
Exposes teamsctl as a public Go SDK by moving the Teams auth/client logic into pkg/teamsauth + pkg/teamsctl, while keeping CLI/MCP wiring internal. It also improves message author attribution by backfilling the signed-in user’s display name when Teams omits it and adds sender_id to message records.
Changes:
- Introduces public SDK surface in
pkg/teamsctl(conversations resolution, sending, identity, message author backfill). - Introduces
pkg/teamsauthfor token storage (keyring + file fallback) and OAuth automation helpers. - Rewires internal CLI and MCP server to consume the new
pkg/*packages.
Reviewed changes
Copilot reviewed 10 out of 23 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| pkg/teamsctl/service.go | Updates auth import path and adds cached best-effort currentUser() helper. |
| pkg/teamsctl/service_test.go | Adds a test ensuring NewService passes keyring tokens to the Teams API client constructor. |
| pkg/teamsctl/send.go | Adds public Service.Send plus mention resolution and message formatting utilities. |
| pkg/teamsctl/send_test.go | Adds tests for formatting and mention substitution helpers. |
| pkg/teamsctl/resolve.go | Adds public recipient phrase resolution (ResolveConversationTarget, one-on-one/group lookup helpers). |
| pkg/teamsctl/resolve_test.go | Updates tests to reflect refactor/moves of helper functions. |
| pkg/teamsctl/models.go | Extends Message model with SenderID. |
| pkg/teamsctl/messages.go | Backfills self-message author name and exposes SenderID; factors mapping into messageRecords. |
| pkg/teamsctl/messages_test.go | Adds tests for self-sender detection and author backfill behavior. |
| pkg/teamsctl/identity.go | Adds public Me() identity accessor that returns a stable SDK Identity type. |
| pkg/teamsctl/conversations.go | Adds conversation discovery/filtering, caching/enrichment, and shared ID utilities. |
| pkg/teamsctl/conversations_test.go | Adds test asserting one-on-one chats are preferred in filtering. |
| pkg/teamsauth/tokens.go | Adds token validation/loading and keyring-first storage with file fallback. |
| pkg/teamsauth/tokens_test.go | Adds tests for expiry validation, config dir resolution, keyring/file fallback behavior, and CheckTokens. |
| pkg/teamsauth/oauth.go | Adds OAuth URL building + callback parsing and tenant discovery helper. |
| pkg/teamsauth/oauth_test.go | Adds tests for auth URL formation and callback parsing behaviors. |
| pkg/teamsauth/models.go | Adds options and internal auth model types (claims, tenants, token kinds). |
| pkg/teamsauth/command.go | Adds an auth subcommand runner for internal CLI to call into the auth workflow. |
| pkg/teamsauth/browser.go | Implements the Chrome/chromedp-based multi-token auth flow and Chrome path resolution. |
| pkg/teamsauth/browser_test.go | Adds tests for resolving direct executables vs macOS app bundles. |
| pkg/teamsauth/autofill.go | Adds best-effort login form autofill loop for chromedp-based auth. |
| internal/teamsctl/mcp.go | Switches MCP server implementation to use the new pkg/teamsctl SDK APIs/types. |
| internal/teamsctl/cli.go | Switches internal CLI to use pkg/teamsauth and pkg/teamsctl instead of internal client/auth. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
133
to
137
| ids := strings.Split(flags.Arg(0), ",") | ||
| if err = service.Send(ids, content, tctl.SendOptions{Format: *format, Mentions: mentions}); err != nil { | ||
| return err | ||
| } | ||
| return writeJSON(stdout, map[string]interface{}{"sent": true, "conversation_ids": ids}) |
Export SplitIDs from pkg/teamsctl and use it in the CLI so the send output reports the same normalized IDs (trimmed, deduped, non-empty) that Service.Send actually messages, instead of the raw comma split. Restores the pre-refactor normalization in messages/send.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Moves the Teams client out of
internal/intopkg/(teamsauth+teamsctl) so other Go projects can import it, and exports the service API (ResolveConversationTarget,FindOneOnOneConversation,Me/Identity,Message/SendOptions, etc.). CLI and MCP wiring stay internal and consume the pkg packages.Also fixes the blank message author for the signed-in user: Teams leaves
imDisplayNameempty on your own messages, soMessagesnow substitutes the account's display name when the sender MRI matches (directly, or derived fromobjectId) and exposessender_id.Verified:
go build,go vetclean;go test= 35 passed / 5 packages.