githubtools

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 7, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package githubtools registers the GitHub protocol client's operations as typed MCP tools and HTTP routes on the CSF MCP endpoint csf serve already has. tools.gen.go is generated from ipc/github/api.github.com.json, the same file the client is generated from, so a tool and the client call behind it cannot drift: the tool's name, description and input and output types all come from GitHub's own description. This package adds no process and starts no goroutine.

Every call is recorded with its actor: a virtual session, named by the assignment its request carries in AssignmentHeader, or the operator. The record goes to the host's GitHub log (<state>/github.jsonl), which the Grafana panel's collector reads, and, for a virtual session, to its run's event log, which its Workbench card shows. Merging follows a MergePolicy held as data with the operator ruling it carries out.

Index

Constants

View Source
const (
	// AssignmentHeader names the virtual session a request acts for: its
	// assignment identifier, which the harness puts on every session's MCP
	// requests. A request without it acts for the operator.
	AssignmentHeader = session.AssignmentHeader
	// LogFile is the host's GitHub log under the state directory.
	LogFile = "github.jsonl"
	// RoutePrefix is where the tools' HTTP routes live: RoutePrefix plus
	// the operationId, such as /api/github/pulls/merge.
	RoutePrefix = "/api/github/"
	// ToolMarkPullRequestReady takes a draft out of draft: the one tool not
	// in GitHub's REST description, so the one not generated.
	ToolMarkPullRequestReady = session.ReadyToolName

	// ActorOperator and ActorVirtualSession are who made a call.
	ActorOperator       ActorKind = "operator"
	ActorVirtualSession ActorKind = "virtual_session"

	// OutcomeOK and OutcomeFailed are how a call ended.
	OutcomeOK     = "ok"
	OutcomeFailed = "failed"
)
View Source
const (
	ToolChecksListForRef             = "ChecksListForRef"
	ToolGitGetRef                    = "GitGetRef"
	ToolIssuesAddBlockedByDependency = "IssuesAddBlockedByDependency"
	ToolIssuesCreate                 = "IssuesCreate"
	ToolIssuesCreateComment          = "IssuesCreateComment"
	ToolIssuesGet                    = "IssuesGet"
	ToolIssuesListComments           = "IssuesListComments"
	ToolIssuesListForRepo            = "IssuesListForRepo"
	ToolIssuesUpdate                 = "IssuesUpdate"
	ToolPullsCreate                  = "PullsCreate"
	ToolPullsGet                     = "PullsGet"
	ToolPullsList                    = "PullsList"
	ToolPullsMerge                   = "PullsMerge"
	ToolPullsUpdate                  = "PullsUpdate"
	ToolReposGetCommit               = "ReposGetCommit"
	ToolReposListWebhookDeliveries   = "ReposListWebhookDeliveries"
	ToolReposListWebhooks            = "ReposListWebhooks"
)

The generated GitHub tools' names.

Variables

View Source
var (
	// ErrNoClient reports tools built without the GitHub protocol client.
	ErrNoClient = errors.New("github tools: a GitHub client is required")
	// ErrNoStateDirectory reports tools built without the state directory.
	ErrNoStateDirectory = errors.New("github tools: a state directory is required")
	// ErrInvalidOption reports a nil option or a value the tools cannot use.
	ErrInvalidOption = errors.New("github tools: invalid option")
	// ErrChecksRequired reports a merge the policy refuses because a check
	// run on the head has not passed.
	ErrChecksRequired = errors.New("github tools: the merge policy requires passing checks")
	// ErrHeldBranch reports a merge the guard refuses because the pull
	// request's head branch belongs to a held slice. It reads as the first
	// words of the refusal the agent is given.
	ErrHeldBranch = errors.New("this branch is held")
	// ErrGoldenMetrics reports a merge the golden metrics refuse: the merge
	// result lowers the seed files, breaks a directory main's seed held clean,
	// or raises the chief violations.
	ErrGoldenMetrics = errors.New("github tools: the golden metrics refuse the merge")
)
View Source
var DefaultMergePolicy = MergePolicy{
	Method:        github.PullsmergeJSONBodyMergeMethodSquash,
	RequireChecks: false,
	Ruling:        "WE'RE BUILDING THE WHOLE THING AND THEN FIXING ALL THE BUGS, WE'RE MERGING EVERYTHING, NO CHECKS",
	RuledAt:       "2026-10-05T02:09Z",
}

DefaultMergePolicy is the ruling in force: merge every pull request as soon as it has content, squashed, with no checks. The repository has no branch protection, so an administrator's merge and a plain one are the same REST call.

Functions

This section is empty.

Types

type ActorKind

type ActorKind string

ActorKind is who made a GitHub call.

type CallCollector

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

CallCollector exports the GitHub measurement, read afresh from the GitHub log at each scrape.

func NewCallCollector

func NewCallCollector(state string) *CallCollector

NewCallCollector builds the collector over the GitHub log under state.

func (*CallCollector) Collect

func (collector *CallCollector) Collect(output chan<- prometheus.Metric)

Collect implements prometheus.Collector.

func (*CallCollector) Describe

func (collector *CallCollector) Describe(output chan<- *prometheus.Desc)

Describe implements prometheus.Collector.

type CallCounts

type CallCounts struct {
	Calls map[CallKey]int
	// RateLimit and RateRemaining are the latest record's that carried a
	// rate limit; zero when none did.
	RateLimit     int
	RateRemaining int
}

CallCounts is the measurement over the host's GitHub log.

func CountCalls

func CountCalls(stateDirectory string) (CallCounts, error)

CountCalls reads the GitHub log under stateDirectory. A missing log is no calls; a line that is not a record is skipped.

type CallKey

type CallKey struct {
	Operation string
	Actor     ActorKind
	Outcome   string
}

CallKey is one series of the call count.

type CallRecord

type CallRecord struct {
	Time       time.Time `json:"time"`
	Operation  string    `json:"operation"`
	Actor      ActorKind `json:"actor"`
	Assignment string    `json:"assignment,omitempty"`
	Repository string    `json:"repository"`
	Number     int       `json:"number,omitempty"`
	Outcome    string    `json:"outcome"`
	Error      string    `json:"error,omitempty"`
	// RateLimit and RateRemaining are the core rate limit GitHub reported on
	// the call's response.
	RateLimit     int          `json:"rate_limit,omitempty"`
	RateRemaining int          `json:"rate_remaining,omitempty"`
	Policy        *MergePolicy `json:"policy,omitempty"`
}

CallRecord is one GitHub call as the host's GitHub log records it.

type ChecksListForRefInput

type ChecksListForRefInput struct {
	Owner  string                         `json:"owner" jsonschema:"The account owner of the repository"`
	Repo   string                         `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	Ref    string                         `json:"ref" jsonschema:"The commit reference"`
	Params *github.CheckslistForRefParams `json:"params,omitempty" jsonschema:"query parameters"`
}

ChecksListForRefInput is the input of the ChecksListForRef tool.

type GitGetRefInput

type GitGetRefInput struct {
	Owner string `json:"owner" jsonschema:"The account owner of the repository"`
	Repo  string `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	Ref   string `json:"ref" jsonschema:"The Git reference"`
}

GitGetRefInput is the input of the GitGetRef tool.

type GitHubTools

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

GitHubTools serves the GitHub operations as tools and records every call.

func NewGitHubTools

func NewGitHubTools(options ...GitHubToolsOption) (*GitHubTools, error)

NewGitHubTools validates the whole option set before building the tools.

func (*GitHubTools) Invoke

func (tools *GitHubTools) Invoke(ctx context.Context, name string, input []byte) ([]byte, error)

Invoke calls the tool named name in-process with its JSON input, as the operator: what the csf github verb does.

func (*GitHubTools) MergePolicy

func (tools *GitHubTools) MergePolicy() MergePolicy

MergePolicy is the policy the PullsMerge tool follows.

func (*GitHubTools) Names

func (tools *GitHubTools) Names() []string

Names lists every tool's name.

func (*GitHubTools) Register

func (tools *GitHubTools) Register(router gin.IRouter)

Register mounts every GitHub operation's HTTP route on the caller's router.

func (*GitHubTools) Tools

func (tools *GitHubTools) Tools() []csf.Option

Tools is every GitHub operation as an MCP tool for csf.New.

type GitHubToolsOption

type GitHubToolsOption func(tools *GitHubTools) error

GitHubToolsOption configures GitHubTools.

func WithClient

func WithClient(client *github.GitHubClient) GitHubToolsOption

WithClient grants the GitHub protocol client. Required.

func WithClock

func WithClock(source clock.IClock) GitHubToolsOption

WithClock replaces the system clock the records are stamped with.

func WithGoldenMetrics

func WithGoldenMetrics(measurer GoldenMeasurer) GitHubToolsOption

WithGoldenMetrics grants the golden metrics gate every merge runs: the pull request's base revision is main, its head revision is the merge result, and a merge that lowers the seed files, breaks a directory main's seed held clean, or raises the chief violations is refused. Without it no golden metrics are measured.

func WithLogger

func WithLogger(logger *slog.Logger) GitHubToolsOption

WithLogger logs records the tools could not write.

func WithMergeGuard

func WithMergeGuard(guard MergeGuard) GitHubToolsOption

WithMergeGuard grants the held-branch check every merge runs on the pull request's head branch: a branch the guard reports held is refused with its reason. Without it no branch is checked.

func WithMergePolicy

func WithMergePolicy(policy MergePolicy) GitHubToolsOption

WithMergePolicy replaces DefaultMergePolicy.

func WithStateDirectory

func WithStateDirectory(directory string) GitHubToolsOption

WithStateDirectory names the harness state directory: the GitHub log is written there, and each virtual session's run is found there. Required.

type GoldenMeasurer

type GoldenMeasurer func(ctx context.Context, owner, repo, revision string) (prod.Reading, error)

GoldenMeasurer measures the golden metrics at one revision: the per directory chief counts the merge quality gate compares between main and the merge result (csf/prod). The host wires the tree's measurer here. A nil measurer checks nothing; when it runs, a revision that cannot be measured fails the merge closed.

type IssuesAddBlockedByDependencyInput

type IssuesAddBlockedByDependencyInput struct {
	Owner       string                                             `json:"owner" jsonschema:"The account owner of the repository"`
	Repo        string                                             `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	IssueNumber int                                                `json:"issue_number" jsonschema:"The number that identifies the issue"`
	Body        github.IssuesaddBlockedByDependencyJSONRequestBody `json:"body" jsonschema:"the request body"`
}

IssuesAddBlockedByDependencyInput is the input of the IssuesAddBlockedByDependency tool.

type IssuesCreateCommentInput

type IssuesCreateCommentInput struct {
	Owner       string                                    `json:"owner" jsonschema:"The account owner of the repository"`
	Repo        string                                    `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	IssueNumber int                                       `json:"issue_number" jsonschema:"The number that identifies the issue"`
	Body        github.IssuescreateCommentJSONRequestBody `json:"body" jsonschema:"the request body"`
}

IssuesCreateCommentInput is the input of the IssuesCreateComment tool.

type IssuesCreateInput

type IssuesCreateInput struct {
	Owner string                             `json:"owner" jsonschema:"The account owner of the repository"`
	Repo  string                             `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	Body  github.IssuescreateJSONRequestBody `json:"body" jsonschema:"the request body"`
}

IssuesCreateInput is the input of the IssuesCreate tool.

type IssuesGetInput

type IssuesGetInput struct {
	Owner       string `json:"owner" jsonschema:"The account owner of the repository"`
	Repo        string `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	IssueNumber int    `json:"issue_number" jsonschema:"The number that identifies the issue"`
}

IssuesGetInput is the input of the IssuesGet tool.

type IssuesListCommentsInput

type IssuesListCommentsInput struct {
	Owner       string                           `json:"owner" jsonschema:"The account owner of the repository"`
	Repo        string                           `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	IssueNumber int                              `json:"issue_number" jsonschema:"The number that identifies the issue"`
	Params      *github.IssueslistCommentsParams `json:"params,omitempty" jsonschema:"query parameters"`
}

IssuesListCommentsInput is the input of the IssuesListComments tool.

type IssuesListForRepoInput

type IssuesListForRepoInput struct {
	Owner  string                          `json:"owner" jsonschema:"The account owner of the repository"`
	Repo   string                          `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	Params *github.IssueslistForRepoParams `json:"params,omitempty" jsonschema:"query parameters"`
}

IssuesListForRepoInput is the input of the IssuesListForRepo tool.

type IssuesUpdateInput

type IssuesUpdateInput struct {
	Owner       string                             `json:"owner" jsonschema:"The account owner of the repository"`
	Repo        string                             `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	IssueNumber int                                `json:"issue_number" jsonschema:"The number that identifies the issue"`
	Body        github.IssuesupdateJSONRequestBody `json:"body" jsonschema:"the request body"`
}

IssuesUpdateInput is the input of the IssuesUpdate tool.

type ListOutput

type ListOutput struct {
	Items json.RawMessage `json:"items"`
}

ListOutput is a list GitHub answered with, as the object an MCP result is.

type MarkPullRequestReadyInput

type MarkPullRequestReadyInput struct {
	Owner      string `json:"owner" jsonschema:"The account owner of the repository"`
	Repo       string `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	PullNumber int    `json:"pull_number" jsonschema:"The number that identifies the pull request"`
}

MarkPullRequestReadyInput is the input of the MarkPullRequestReady tool.

type MergeGuard

type MergeGuard func(ctx context.Context, branch string) (reason string, held bool, err error)

MergeGuard is the held-branch check every merge runs: given a pull request's head branch, it reports whether the branch is held and why. The host wires the slice dispatcher here, so a held slice's branch cannot merge. A nil guard checks nothing; when it runs, a pull request that cannot be read fails the merge closed, and a branch it does not report held merges.

type MergePolicy

type MergePolicy struct {
	Method github.PullsmergeJSONBodyMergeMethod `json:"method"`
	// RequireChecks refuses a merge unless every check run on the head has
	// completed and none failed.
	RequireChecks bool `json:"require_checks"`
	// Ruling is the operator's ruling, verbatim, and RuledAt when it was made.
	Ruling  string `json:"ruling"`
	RuledAt string `json:"ruled_at"`
}

MergePolicy is how the PullsMerge tool merges, held as data with the operator ruling it carries out.

type PullsCreateInput

type PullsCreateInput struct {
	Owner string                            `json:"owner" jsonschema:"The account owner of the repository"`
	Repo  string                            `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	Body  github.PullscreateJSONRequestBody `json:"body" jsonschema:"the request body"`
}

PullsCreateInput is the input of the PullsCreate tool.

type PullsGetInput

type PullsGetInput struct {
	Owner      string `json:"owner" jsonschema:"The account owner of the repository"`
	Repo       string `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	PullNumber int    `json:"pull_number" jsonschema:"The number that identifies the pull request"`
}

PullsGetInput is the input of the PullsGet tool.

type PullsListInput

type PullsListInput struct {
	Owner  string                  `json:"owner" jsonschema:"The account owner of the repository"`
	Repo   string                  `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	Params *github.PullslistParams `json:"params,omitempty" jsonschema:"query parameters"`
}

PullsListInput is the input of the PullsList tool.

type PullsMergeInput

type PullsMergeInput struct {
	Owner      string                           `json:"owner" jsonschema:"The account owner of the repository"`
	Repo       string                           `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	PullNumber int                              `json:"pull_number" jsonschema:"The number that identifies the pull request"`
	Body       github.PullsmergeJSONRequestBody `json:"body" jsonschema:"the request body"`
}

PullsMergeInput is the input of the PullsMerge tool.

type PullsUpdateInput

type PullsUpdateInput struct {
	Owner      string                            `json:"owner" jsonschema:"The account owner of the repository"`
	Repo       string                            `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	PullNumber int                               `json:"pull_number" jsonschema:"The number that identifies the pull request"`
	Body       github.PullsupdateJSONRequestBody `json:"body" jsonschema:"the request body"`
}

PullsUpdateInput is the input of the PullsUpdate tool.

type ReposGetCommitInput

type ReposGetCommitInput struct {
	Owner  string                       `json:"owner" jsonschema:"The account owner of the repository"`
	Repo   string                       `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	Ref    string                       `json:"ref" jsonschema:"The commit reference"`
	Params *github.ReposgetCommitParams `json:"params,omitempty" jsonschema:"query parameters"`
}

ReposGetCommitInput is the input of the ReposGetCommit tool.

type ReposListWebhookDeliveriesInput

type ReposListWebhookDeliveriesInput struct {
	Owner  string                                   `json:"owner" jsonschema:"The account owner of the repository"`
	Repo   string                                   `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	HookId int                                      `json:"hook_id" jsonschema:"The unique identifier of the hook"`
	Params *github.ReposlistWebhookDeliveriesParams `json:"params,omitempty" jsonschema:"query parameters"`
}

ReposListWebhookDeliveriesInput is the input of the ReposListWebhookDeliveries tool.

type ReposListWebhooksInput

type ReposListWebhooksInput struct {
	Owner  string                          `json:"owner" jsonschema:"The account owner of the repository"`
	Repo   string                          `json:"repo" jsonschema:"The name of the repository without the '.git' extension"`
	Params *github.ReposlistWebhooksParams `json:"params,omitempty" jsonschema:"query parameters"`
}

ReposListWebhooksInput is the input of the ReposListWebhooks tool.

Jump to

Keyboard shortcuts

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