Skip to content

refactor(pkg): invert the public API aliases so pkg owns the exported types #928

Description

@devlikebear

Part of #919. Phase 2 of the public library boundary track. LP-009.

Prerequisite: #927 (LP-008).
Blocks #929 (LP-010).

Summary

Move the real type definitions into pkg/* and leave aliases behind in internal/*, reversing the current direction so the public API is the source of truth.

Problem

Every public package is a type-alias facade over an internal one:

// pkg/llm/exports.go
type ChatMessage = internal.ChatMessage
type Client      = internal.Client

Three consequences, in order of severity:

  1. The public API is undocumented. pkg.go.dev does not publish internal/ docs, so a consumer sees type ChatMessage = llm.ChatMessage and cannot see a single field. For a library that is offered to external consumers, this is close to disqualifying.
  2. No compiler-enforced boundary. Any refactor of an internal type is an immediate breaking change to downstream consumers, and nothing in review or CI shows it. The blast radius is invisible at the point of change.
  3. The direction encodes the wrong intent. internal is where design happens and pkg follows. If the library is to be promoted, that has to reverse.

docs/public-agent-packages.md already commits to these packages as a supported surface, so the gap is between the stated intent and the mechanism.

Scope

  • Invert pkg/llm first — 4 internal dependencies makes it the lowest-risk starting point. Move ChatMessage, ContentBlock, ToolCall, ToolSchema, ChatOptions, ChatResponse, Usage, Client, and the role/tier types into pkg/llm.
  • Leave type X = pkg.X aliases in internal/llm so no internal call site changes in the same PR.
  • Repeat for pkg/session, pkg/memory, pkg/skill (2-3 dependencies each).
  • Then pkg/tools and pkg/agentloop, which refactor(tool): split internal/tool into core primitives and TARS app tools #927 has made tractable.
  • Write doc comments on every exported type and function as they move — this is the point of the exercise, not a follow-up.
  • Keep pkg/tarsclient as is; it already has zero internal dependencies.
  • Confirm no import cycle is introduced, especially around internal/auth and internal/llmdefaults.

Acceptance Criteria

  • go doc github.com/devlikebear/tars/pkg/llm ChatMessage shows the fields.
  • Every exported identifier in the inverted packages has a doc comment.
  • No behavior change; internal call sites are untouched or mechanically updated.
  • No import cycles.
  • examples/min-agent builds unchanged.

Validation

  • go vet ./... and a doc-comment lint over pkg/
  • make test
  • make test-diff
  • make lint-diff
  • make build
  • Manual go doc inspection of each inverted package

Out of Scope

  • Redesigning the API. This moves definitions; it does not change shapes.
  • A v1.0 commitment.
  • Inverting internal/agentruntime, workstore, or anything else that stays internal.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestgoPull requests that update go codemlp-domain-platformMLP: Domain-agnostic agent platform

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions