Documentation
¶
Overview ¶
Package forges integrates remote git forges (GitHub, GitLab, Gitea/Codeberg) by orchestrating their first-party CLI tools (gh, glab, tea).
Design: the CLI tools own API pagination, error mapping, the git credential helpers, AND their own credential stores — vibekit talks to each store exclusively through the CLI's documented subcommands (login/logout/status; see auth.go and discover.go) and never reads or writes another program's config file. The one documented exception is glab's read-only discovery parser (glab_config.go), kept only because glab ships no machine-readable status output. vibekit owns the UX, the unified API surface that the agent and the web UI both consume, and the GitHub OAuth device flow (oauth/device_flow.go — see login.go for the split). No token-refresh path exists on either side: PATs and device-flow tokens are used until they expire or are disconnected.
There is no encrypted credential store. The CLIs persist tokens in their own stores under the persistent /config volume. The container is single-user; file permissions are sufficient.
Index ¶
- Constants
- Variables
- func EnsureCLI(ctx context.Context, kind Kind) error
- func LoginWithPAT(ctx context.Context, p LoginPATParams) error
- func Logout(ctx context.Context, kind Kind, host string) error
- func MakeID(kind Kind, host string) string
- func ParseRepo(s string) (owner, name string, err error)
- func SetConfigHome(p string)
- type Check
- type ConfiguredForge
- type CreateIssueParams
- type CreatePRParams
- type CreateReleaseParams
- type DeviceFlowResponse
- type ForgeErrCode
- type ForgeOps
- type HTTPHandler
- type Issue
- type Kind
- type Label
- type ListState
- type LoginPATParams
- type Manager
- func (m *Manager) Get(id string) *ConfiguredForge
- func (m *Manager) Invalidate()
- func (m *Manager) List(ctx context.Context) []ConfiguredForge
- func (m *Manager) Probe(ctx context.Context, id string) error
- func (m *Manager) Provider(id string) (ForgeOps, error)
- func (m *Manager) Refresh(ctx context.Context) error
- type MergeMethod
- type PR
- type PollResult
- type Release
- type Repo
- type User
Constants ¶
const ( StatusSuccess = "success" StatusFailure = "failure" StatusError = "error" StatePending = "pending" StateSkipped = "skipped" StateCompleted = "completed" )
Exported status/state constants defining the forge protocol vocabulary.
const CmdTimeout = 30 * time.Second
CmdTimeout is the default per-command timeout. Long enough for large repo lists; short enough that a wedged forge doesn't pin the request.
const ListTimeout = 60 * time.Second
ListTimeout is for paginated listings that may take longer.
Variables ¶
var EnsureTool func(ctx context.Context, name string) error
EnsureTool is the tools-engine hook that installs a tool by name and waits for it. Wired from main.go; nil in tests/dev, where a missing CLI simply surfaces as an error.
var ErrNotInstalled = cliexec.ErrNotInstalled
ErrNotInstalled signals the backing CLI is not on PATH. Aliased to the cliexec sentinel (which runCmd actually returns) — the package previously declared a SEPARATE errors.New with the same message, so every errors.Is against this symbol silently never matched.
var ErrNotLoggedIn = cliexec.ErrNotLoggedIn
ErrNotLoggedIn signals the CLI is installed but no auth is configured for this host. Aliased for the same reason as ErrNotInstalled.
Functions ¶
func EnsureCLI ¶
EnsureCLI checks if the CLI for the given kind is on PATH, and if not, installs it through the tools engine. Safe to call repeatedly.
func LoginWithPAT ¶
func LoginWithPAT(ctx context.Context, p LoginPATParams) error
LoginWithPAT performs a PAT-based login: install the CLI, log it in natively (the CLIs validate the token against the forge at login time), then verify with Whoami and roll back on failure.
func Logout ¶
Logout disconnects a forge: removes the credential from the CLI's own store via its logout subcommand.
func ParseRepo ¶
ParseRepo splits a "owner/name" string. Returns an error if the format is invalid. Both parts must be non-empty.
func SetConfigHome ¶
func SetConfigHome(p string)
SetConfigHome overrides the config root for tests. Pass "" to reset to the default.
Types ¶
type Check ¶
type Check struct {
Name string `json:"name"`
Status string `json:"status"` // "queued" | "in_progress" | stateCompleted
Conclusion string `json:"conclusion"` // statusSuccess | statusFailure | "cancelled" | stateSkipped | ""
URL string `json:"url,omitempty"`
}
Check is a single CI status check for a commit.
type ConfiguredForge ¶
type ConfiguredForge struct {
ID string `json:"id"`
Kind Kind `json:"kind"`
Host string `json:"host"`
Username string `json:"username,omitempty"`
Email string `json:"email,omitempty"`
LastError string `json:"last_error,omitempty"`
LastProbed int64 `json:"last_probed,omitempty"`
Connected bool `json:"connected"`
// CLIMissing marks a connection whose backing CLI binary is absent
// (uninstalled/disabled in Settings → Tools, or a fresh tools volume
// against a kept config volume) while a configuration for it still
// exists. The row renders as a warning with a reinstall pointer; it
// is never probed and cannot be disconnected until the CLI returns.
CLIMissing bool `json:"cli_missing,omitempty"`
}
ConfiguredForge is one connected forge backend, discovered through the CLIs' own status subcommands (see discover.go).
type CreateIssueParams ¶
type CreateIssueParams struct {
Title string `json:"title"`
Body string `json:"body,omitempty"`
Labels []string `json:"labels,omitempty"`
}
CreateIssueParams describes an issue to create.
type CreatePRParams ¶
type CreatePRParams struct {
Title string `json:"title"`
Body string `json:"body,omitempty"`
SourceBranch string `json:"source_branch"`
TargetBranch string `json:"target_branch"`
Labels []string `json:"labels,omitempty"`
Draft bool `json:"draft,omitempty"`
}
CreatePRParams describes a PR to create.
type CreateReleaseParams ¶
type CreateReleaseParams struct {
TagName string `json:"tag_name"`
Name string `json:"name,omitempty"`
Body string `json:"body,omitempty"`
Target string `json:"target,omitempty"` // commit SHA or branch
Draft bool `json:"draft,omitempty"`
Prerelease bool `json:"prerelease,omitempty"`
}
CreateReleaseParams describes a release to create.
type DeviceFlowResponse ¶
type DeviceFlowResponse = oauth.DeviceFlowResponse
DeviceFlowResponse describes a started OAuth device flow. Re-exported from the oauth sub-package for API compatibility.
func StartGitHubDeviceFlow ¶
func StartGitHubDeviceFlow(ctx context.Context) (*DeviceFlowResponse, error)
StartGitHubDeviceFlow initiates the OAuth device flow with GitHub.
type ForgeErrCode ¶
type ForgeErrCode string
ForgeErrCode is a typed error code for machine-readable forge HTTP error responses.
const ( ForgeErrCLINotInstalled ForgeErrCode = "cli_not_installed" ForgeErrNotLoggedIn ForgeErrCode = "not_logged_in" )
ForgeErrCLINotInstalled and the following constants define the ForgeErrCode values for machine-readable HTTP error responses.
type ForgeOps ¶
type ForgeOps interface {
// Kind returns the backend kind (github/gitlab/gitea).
Kind() Kind
// Host returns the forge hostname this provider is bound to.
Host() string
// Whoami returns the authenticated account, or an error if not
// logged in (or the CLI is not installed).
Whoami(ctx context.Context) (*User, error)
// ListRepos returns repositories accessible to the authenticated
// account (owned + member).
ListRepos(ctx context.Context) ([]Repo, error)
// ListPRs lists pull/merge requests for repo.
ListPRs(ctx context.Context, repo string, state ListState) ([]PR, error)
// CreatePR opens a new pull/merge request.
CreatePR(ctx context.Context, repo string, p *CreatePRParams) (*PR, error)
// MergePR merges an open PR.
MergePR(ctx context.Context, repo string, number int, method MergeMethod) error
// ClosePR closes (without merging) an open PR.
ClosePR(ctx context.Context, repo string, number int) error
// ListIssues lists issues for repo.
ListIssues(ctx context.Context, repo string, state ListState) ([]Issue, error)
// CreateIssue files a new issue.
CreateIssue(ctx context.Context, repo string, p CreateIssueParams) (*Issue, error)
// CloseIssue closes an open issue.
CloseIssue(ctx context.Context, repo string, number int) error
// CommitStatus returns CI checks for a commit ref (branch / SHA).
CommitStatus(ctx context.Context, repo, ref string) ([]Check, error)
// ListReleases returns recent releases for repo.
ListReleases(ctx context.Context, repo string) ([]Release, error)
// CreateRelease cuts a new release.
CreateRelease(ctx context.Context, repo string, p CreateReleaseParams) (*Release, error)
// ListLabels returns labels defined on repo.
ListLabels(ctx context.Context, repo string) ([]Label, error)
}
ForgeOps is the unified abstraction over a specific forge backend. Each implementation shells out to the corresponding CLI tool.
Methods take a context for cancellation and a host for routing (each Provider instance is bound to one host but methods accept it explicitly so multi-host instances are possible later).
type HTTPHandler ¶
type HTTPHandler struct {
// contains filtered or unexported fields
}
HTTPHandler exposes the forges package over HTTP.
func NewHTTPHandler ¶
func NewHTTPHandler(m *Manager, b api.Broadcaster) *HTTPHandler
NewHTTPHandler builds an HTTPHandler with the given Manager. broadcaster may be nil; when nil, forge change events are silently dropped.
func (*HTTPHandler) RegisterRoutes ¶
func (h *HTTPHandler) RegisterRoutes(mux *http.ServeMux)
RegisterRoutes installs the /api/forges/* mux entries.
func (*HTTPHandler) SetOnChange ¶ added in v0.1.184
func (h *HTTPHandler) SetOnChange(fn func())
SetOnChange wires a callback fired whenever a forge connection changes (PAT login, OAuth completion, disconnect, refresh). Called once at composition; used to refresh the steering forge-snapshot cache and regenerate environment.md. The callback must not block — it runs on the HTTP request path — and must not capture the request context (composition kicks its work onto the app-lifetime context).
type Issue ¶
type Issue struct {
Title string `json:"title"`
Body string `json:"body,omitempty"`
State string `json:"state"`
Author string `json:"author,omitempty"`
URL string `json:"url,omitempty"`
Labels []string `json:"labels,omitempty"`
Number int `json:"number"`
CreatedAt int64 `json:"created_at,omitempty"`
UpdatedAt int64 `json:"updated_at,omitempty"`
}
Issue represents a forge issue.
type Kind ¶
type Kind string
Kind identifies a forge backend.
const ( KindGitHub Kind = "github" KindGitLab Kind = "gitlab" KindGitea Kind = "gitea" // also covers Codeberg (codeberg.org is a Gitea instance) KindCodeberg Kind = "codeberg" // synonym for KindGitea, host=codeberg.org )
KindGitHub and the following constants define the valid Kind values identifying forge backends.
func AllKinds ¶
func AllKinds() []Kind
AllKinds returns every supported forge kind. Stable ordering for UI rendering.
func (Kind) DefaultHost ¶
DefaultHost returns the canonical hostname for the kind, or "" if no default exists (self-hosted Gitea/Forgejo).
type Label ¶
type Label struct {
Name string `json:"name"`
Color string `json:"color,omitempty"`
Description string `json:"description,omitempty"`
}
Label is a forge label (used on PRs and issues).
type ListState ¶
type ListState string
ListState is a typed enum for PR/issue listing state filters.
type LoginPATParams ¶
LoginPATParams describes a PAT-based login (GitLab/Gitea/Codeberg). The CLIs discover the account identity from the token themselves.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager owns the list of configured forges.
func (*Manager) Get ¶
func (m *Manager) Get(id string) *ConfiguredForge
Get returns the configured forge with the given ID, or nil.
func (*Manager) Invalidate ¶
func (m *Manager) Invalidate()
Invalidate clears the cache so the next List/Get reloads.
func (*Manager) List ¶
func (m *Manager) List(ctx context.Context) []ConfiguredForge
List returns all configured forges, refreshing from CLI configs if the cache is stale.
func (*Manager) Probe ¶
Probe runs a Whoami against the forge to verify auth still works and updates the Connected/LastProbed/LastError fields.
func (*Manager) Provider ¶
Provider returns a ForgeOps for the given configured forge ID. Returns an error if the ID is unknown.
func (*Manager) Refresh ¶
Refresh re-queries every CLI's own status output and rebuilds the forge list. Presence-only: gh's network-tested per-account "state" is deliberately not consulted (Probe is the sole network path), and gh's own connection test fails fast offline, so the subprocess cost per stale TTL stays bounded by CmdTimeout in the worst case.
type MergeMethod ¶
type MergeMethod string
MergeMethod is a typed enum for PR merge strategies.
const ( MergeCommit MergeMethod = "merge" MergeSquash MergeMethod = "squash" MergeRebase MergeMethod = "rebase" )
MergeCommit and the following constants define the valid MergeMethod values for PR merge strategies.
type PR ¶
type PR struct {
Title string `json:"title"`
Body string `json:"body,omitempty"`
State string `json:"state"`
Author string `json:"author,omitempty"`
SourceBranch string `json:"source_branch"`
TargetBranch string `json:"target_branch"`
URL string `json:"url,omitempty"`
Number int `json:"number"`
CreatedAt int64 `json:"created_at,omitempty"`
UpdatedAt int64 `json:"updated_at,omitempty"`
Mergeable bool `json:"mergeable,omitempty"`
Draft bool `json:"draft,omitempty"`
}
PR represents a pull/merge request.
type PollResult ¶
PollResult is the per-poll status during the device flow.
func PollGitHubDeviceFlow ¶
func PollGitHubDeviceFlow(ctx context.Context, deviceCode string) (PollResult, error)
PollGitHubDeviceFlow checks if the user has approved the device. On complete, the token is written to gh's config and the helper is set up.
type Release ¶
type Release struct {
TagName string `json:"tag_name"`
Name string `json:"name,omitempty"`
Body string `json:"body,omitempty"`
URL string `json:"url,omitempty"`
PublishedAt int64 `json:"published_at,omitempty"`
Draft bool `json:"draft,omitempty"`
Prerelease bool `json:"prerelease,omitempty"`
}
Release represents a tagged release.
type Repo ¶
type Repo struct {
Owner string `json:"owner"`
Name string `json:"name"`
FullName string `json:"full_name"`
DefaultBranch string `json:"default_branch,omitempty"`
URL string `json:"url,omitempty"`
CloneURL string `json:"clone_url,omitempty"`
Description string `json:"description,omitempty"`
Private bool `json:"private,omitempty"`
Archived bool `json:"archived,omitempty"`
Fork bool `json:"fork,omitempty"`
UpdatedAt int64 `json:"updated_at,omitempty"` // unix millis
}
Repo is a remote repository accessible via the authenticated forge.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package cliexec provides CLI subprocess execution with structured output capture, size-capped buffers, and typed errors.
|
Package cliexec provides CLI subprocess execution with structured output capture, size-capped buffers, and typed errors. |
|
Package gitea provides the Gitea/Codeberg ForgeOps implementation.
|
Package gitea provides the Gitea/Codeberg ForgeOps implementation. |
|
Package github provides the GitHub ForgeOps implementation.
|
Package github provides the GitHub ForgeOps implementation. |
|
Package gitlab provides the GitLab ForgeOps implementation.
|
Package gitlab provides the GitLab ForgeOps implementation. |
|
Package oauth implements the GitHub OAuth device flow protocol.
|
Package oauth implements the GitHub OAuth device flow protocol. |