adapter

package
v0.36.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 13, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package adapter defines interfaces for all external integrations. Engines depend on these interfaces, never on concrete implementations.

Index

Constants

This section is empty.

Variables

View Source
var ErrRecipientUnknown = errors.New("comms: recipient handle not resolvable")

ErrRecipientUnknown is returned by NotifyUser when an adapter cannot resolve a handle to a user it can message directly. Callers fall back to a channel broadcast — this is never a fatal condition.

Functions

This section is empty.

Types

type AIAdapter

type AIAdapter interface {
	// Complete sends a prompt and returns the completion.
	Complete(ctx context.Context, prompt string, system string) (string, error)
}

AIAdapter manages LLM integration for content drafting.

type AgentAdapter

type AgentAdapter interface {
	// Invoke spawns the agent as a subprocess. It blocks until the agent exits.
	Invoke(ctx context.Context, req InvokeRequest) (*InvokeResult, error)
	// Capabilities describes what the agent harness supports.
	Capabilities() Capabilities
}

AgentAdapter manages coding agent integration. The build engine assembles all context (spec, MCP config, skills, system prompt) and hands the adapter a structured InvokeRequest; the adapter only translates that request into the CLI invocation for its harness.

type Capabilities added in v0.15.0

type Capabilities struct {
	MCP          bool
	Headless     bool
	Skills       bool
	SystemPrompt bool
}

Capabilities describes the features an agent harness supports.

type CommsAdapter

type CommsAdapter interface {
	// Notify sends a structured message to the configured channel.
	Notify(ctx context.Context, msg Notification) error
	// NotifyUser sends a notification directly to a specific user by handle,
	// bypassing the channel broadcast. Adapters that cannot resolve a handle
	// to a user, or that have no per-user delivery mechanism at all, return
	// ErrRecipientUnknown so the caller can fall back to Notify. Like every
	// comms call it is best-effort and never fatal.
	NotifyUser(ctx context.Context, handle string, msg Notification) error
	// PostStandup posts a formatted standup to the standup channel.
	PostStandup(ctx context.Context, standup StandupReport) error
	// FetchMentions returns recent mentions of spec IDs in configured channels.
	FetchMentions(ctx context.Context, since time.Time) ([]Mention, error)
}

CommsAdapter sends notifications and retrieves mentions from a comms platform.

type DeployAdapter

type DeployAdapter interface {
	// Trigger initiates a deployment for the given repos to the target environment.
	Trigger(ctx context.Context, repos []string, env string) (*DeployRun, error)
	// Status polls the deployment run for current state.
	Status(ctx context.Context, run *DeployRun) (*DeployStatus, error)
}

DeployAdapter manages deployment integration.

type DeployRun

type DeployRun struct {
	ID     string
	Repo   string
	Env    string
	Status string
	URL    string
}

DeployRun represents a triggered deployment.

type DeployStatus

type DeployStatus struct {
	RunID   string
	Status  string // "pending", "running", "success", "failure"
	URL     string
	Message string
}

DeployStatus represents the current state of a deployment.

type DocsAdapter

type DocsAdapter interface {
	// FetchSections retrieves the current content of the spec from the docs provider,
	// keyed by section slug.
	FetchSections(ctx context.Context, specID string) (map[string]string, error)
	// PushFull publishes the complete spec to the docs provider.
	PushFull(ctx context.Context, specID string, content string) error
	// PageURL returns the URL of the spec's page in the docs provider.
	PageURL(ctx context.Context, specID string) (string, error)
}

DocsAdapter manages documentation tool integration.

type InvokeRequest added in v0.15.0

type InvokeRequest struct {
	SpecID        string   // active spec id (e.g. SPEC-042)
	WorkDir       string   // working directory the agent runs in
	ContextFile   string   // consolidated markdown fallback for non-MCP agents
	MCPConfigPath string   // engine-generated; runs `spec mcp-server --spec <id>`
	SystemPrompt  string   // assembled build instructions
	SkillPaths    []string // reproducibility skill paths (may be empty)
	Prompt        string   // kickoff prompt (may be empty)
	Headless      bool     // -p mode for `spec fix --auto` / CI
}

InvokeRequest carries everything an agent needs for a build session.

type InvokeResult added in v0.15.0

type InvokeResult struct {
	// ExitReason is why the session ended: "completed", "error",
	// "interrupted", or "" when it could not be determined.
	ExitReason string `json:"exitReason,omitempty"`
	// ErrorClass categorises a failure (e.g. "auto_retry_exhausted",
	// "compaction_failed", "nonzero_exit"). Empty on success.
	ErrorClass string `json:"errorClass,omitempty"`
	// ErrorMessage is the harness-reported failure detail, when present.
	ErrorMessage string `json:"errorMessage,omitempty"`
	// Tokens aggregates token usage across the session, when the harness
	// reports it.
	Tokens TokenUsage `json:"tokens,omitempty"`
	// Raw holds a bounded tail of the harness output, retained for debugging
	// when structured parsing yields nothing.
	Raw string `json:"raw,omitempty"`
}

InvokeResult reports what the agent did during the session. spec-cli reconciles real per-node progress from the durable node ledger after the agent exits; this result carries the session-level signal that the ledger cannot capture — why the run ended, how it failed, and what it cost — so that autonomous (`--auto`) runs are debuggable from the activity log.

All fields are best-effort. A headless harness whose output cannot be parsed yields a zero-value result with Raw populated; callers must treat empty fields as "unknown", never as an error.

type Mention

type Mention struct {
	SpecID    string
	Channel   string
	Author    string
	Preview   string
	Timestamp time.Time
}

Mention represents a comms mention of a spec.

type Notification

type Notification struct {
	SpecID  string
	Title   string
	Message string
	Channel string
	Mention string // e.g., "@alice"
}

Notification represents a structured message to send via comms.

type PMAdapter

type PMAdapter interface {
	// FindEpic returns the key of an existing epic linked to the spec, or ""
	// when none exists. It is the idempotency guard for CreateEpic.
	FindEpic(ctx context.Context, specID string) (epicKey string, err error)
	// CreateEpic creates a new epic/issue linked to a spec and returns its key.
	CreateEpic(ctx context.Context, spec SpecMeta) (epicKey string, err error)
	// LinkEpic records a back-link from the PM issue to the spec so board
	// consumers can navigate PM -> spec. specURL may be empty.
	LinkEpic(ctx context.Context, epicKey, specID, specURL string) error
	// UpdateStatus syncs the spec's pipeline stage to the PM tool's board
	// status. A stage with no configured mapping is a clean no-op.
	UpdateStatus(ctx context.Context, epicKey string, status string) error
	// FetchUpdates returns status changes from the PM tool since last sync.
	FetchUpdates(ctx context.Context, epicKey string) (*PMUpdate, error)
	// SyncStories reconciles per-step stories under an epic, returning the
	// resulting story links. A no-op when story sync is disabled.
	SyncStories(ctx context.Context, epicKey string, stories []StorySpec) ([]StoryLink, error)
	// Validate checks credentials and configuration against the live PM tool.
	Validate(ctx context.Context) error
}

PMAdapter manages project management tool integration.

Implementations must be idempotent and degrade gracefully: an unconfigured or unreachable PM tool returns empty results and nil errors rather than blocking spec authoring (see docs/JIRA_HARDENING_PLAN.md).

type PMUpdate

type PMUpdate struct {
	Status    string
	Assignee  string
	UpdatedAt time.Time
}

PMUpdate represents status changes from a PM tool.

type PRDetail

type PRDetail struct {
	PullRequest
	ReviewComments    int
	UnresolvedThreads int
}

PRDetail represents detailed PR information.

type PullRequest

type PullRequest struct {
	Number    int
	Title     string
	Repo      string
	Branch    string
	Author    string
	URL       string
	Status    string // "open", "merged", "closed"
	Approved  bool
	CIStatus  string // "passing", "failing", "pending"
	CreatedAt time.Time
}

PullRequest represents a PR from a repo provider.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry resolves configuration to concrete adapter implementations.

func NewRegistry

func NewRegistry(cfg *config.TeamConfig) *Registry

NewRegistry creates a new adapter registry from team configuration. Concrete adapters are injected via With* methods. Unconfigured adapters are set to their noop implementations by the caller.

func (*Registry) AI

func (r *Registry) AI() AIAdapter

AI returns the AI adapter.

func (*Registry) Agent

func (r *Registry) Agent() AgentAdapter

Agent returns the agent adapter.

func (*Registry) Comms

func (r *Registry) Comms() CommsAdapter

Comms returns the comms adapter.

func (*Registry) Config

func (r *Registry) Config() *config.TeamConfig

Config returns the team configuration.

func (*Registry) Deploy

func (r *Registry) Deploy() DeployAdapter

Deploy returns the deploy adapter.

func (*Registry) Docs

func (r *Registry) Docs() DocsAdapter

Docs returns the docs adapter.

func (*Registry) PM

func (r *Registry) PM() PMAdapter

PM returns the PM adapter.

func (*Registry) Repo

func (r *Registry) Repo() RepoAdapter

Repo returns the repo adapter.

func (*Registry) WithAI

func (r *Registry) WithAI(a AIAdapter) *Registry

WithAI sets the AI adapter.

func (*Registry) WithAgent

func (r *Registry) WithAgent(a AgentAdapter) *Registry

WithAgent sets the agent adapter.

func (*Registry) WithComms

func (r *Registry) WithComms(a CommsAdapter) *Registry

WithComms sets the comms adapter.

func (*Registry) WithDeploy

func (r *Registry) WithDeploy(a DeployAdapter) *Registry

WithDeploy sets the deploy adapter.

func (*Registry) WithDocs

func (r *Registry) WithDocs(a DocsAdapter) *Registry

WithDocs sets the docs adapter.

func (*Registry) WithPM

func (r *Registry) WithPM(a PMAdapter) *Registry

WithPM sets the PM adapter.

func (*Registry) WithRepo

func (r *Registry) WithRepo(a RepoAdapter) *Registry

WithRepo sets the repo adapter.

type RepoAdapter

type RepoAdapter interface {
	// ListPRs returns open PRs matching a spec's branch pattern across its repos.
	ListPRs(ctx context.Context, repos []string, specID string) ([]PullRequest, error)
	// PRStatus returns the review/CI status of a specific PR.
	PRStatus(ctx context.Context, repo string, prNumber int) (*PRDetail, error)
	// SetPRDescription updates a PR's description.
	SetPRDescription(ctx context.Context, repo string, prNumber int, body string) error
	// RequestedReviews returns PRs where the current user is a requested reviewer.
	RequestedReviews(ctx context.Context, user string) ([]PullRequest, error)
	// InvolvedPRs returns open PRs that involve the user in any capacity —
	// authored, assigned, review-requested, or mentioned. Unlike
	// RequestedReviews, this includes the user's own PRs.
	InvolvedPRs(ctx context.Context, user string) ([]PullRequest, error)
	// OpenDraftPR opens a DRAFT pull request from head into base, returning its
	// number and URL. Draft-only by design: merge stays a human action, so no
	// merge call is exposed on this interface.
	OpenDraftPR(ctx context.Context, repo, head, base, title, body string) (number int, url string, err error)
	// SetPRBase retargets an open PR's base branch, used to re-chain a stack as
	// parent PRs merge.
	SetPRBase(ctx context.Context, repo string, prNumber int, base string) error
}

RepoAdapter manages code repository integration.

type SpecMeta

type SpecMeta struct {
	ID      string
	Title   string
	Status  string
	EpicKey string
	Repos   []string

	// Problem is a short excerpt of the problem statement, used to give the
	// PM epic meaningful context instead of just an id.
	Problem string
	// Labels are applied to the created issue (in addition to config labels).
	Labels []string
	// Cycle is the team cycle/iteration label.
	Cycle string
	// URL is a back-link to the canonical spec document.
	URL string
}

SpecMeta is a lightweight spec summary for adapter use.

type StandupReport

type StandupReport struct {
	UserName  string
	Date      string
	Yesterday []string
	Today     []string
	Blockers  []string
}

StandupReport represents a formatted standup.

type StoryLink struct {
	StepID   string
	StoryKey string
	Status   string
}

StoryLink is the result of reconciling a StorySpec: the PM story key and the status it was left in.

type StorySpec added in v0.22.1

type StorySpec struct {
	// StepID is a stable identifier for the step, used as the idempotency key.
	StepID      string
	Repo        string
	Description string
	// Status is the spec step status: pending | in-progress | complete | blocked.
	Status string
}

StorySpec describes a build step to reconcile into a PM story under an epic.

type TokenUsage added in v0.23.0

type TokenUsage struct {
	Input  int `json:"input,omitempty"`
	Output int `json:"output,omitempty"`
	Total  int `json:"total,omitempty"`
}

TokenUsage aggregates the token counts a headless harness reports over a session. Zero values mean the harness did not report that figure.

Directories

Path Synopsis
Package anthropic implements AIAdapter using the Anthropic Messages API.
Package anthropic implements AIAdapter using the Anthropic Messages API.
Package claude implements AgentAdapter for Claude Code.
Package claude implements AgentAdapter for Claude Code.
Package confluence implements DocsAdapter using the Confluence REST API.
Package confluence implements DocsAdapter using the Confluence REST API.
Package github implements RepoAdapter and DeployAdapter using the GitHub API.
Package github implements RepoAdapter and DeployAdapter using the GitHub API.
Package jira implements PMAdapter using the Jira REST API v3.
Package jira implements PMAdapter using the Jira REST API v3.
Package noop provides no-op adapter implementations for unconfigured integrations.
Package noop provides no-op adapter implementations for unconfigured integrations.
Package ollama implements AIAdapter using the Ollama local API.
Package ollama implements AIAdapter using the Ollama local API.
Package pi implements AgentAdapter for the pi.dev coding agent.
Package pi implements AgentAdapter for the pi.dev coding agent.
Package resolve creates concrete adapter implementations from team config.
Package resolve creates concrete adapter implementations from team config.
Package slack implements CommsAdapter using the Slack API.
Package slack implements CommsAdapter using the Slack API.
Package teams implements CommsAdapter using Microsoft Teams webhooks.
Package teams implements CommsAdapter using Microsoft Teams webhooks.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL