Documentation
¶
Index ¶
- Variables
- func BuildCampaignGenerator() *workflow.WorkflowData
- func BuildOrchestrator(spec *CampaignSpec, campaignFilePath string) (*workflow.WorkflowData, string)
- func ComputeCompiledState(spec CampaignSpec, workflowsDir string) string
- func CreateSpecSkeleton(rootDir, id string, force bool) (string, error)
- func FetchCursorFreshnessFromRepoMemory(cursorGlob string) (cursorPath string, cursorUpdatedAt string)
- func NewCommand() *cobra.Command
- func RenderClosingInstructions() string
- func RenderOrchestratorInstructions(data CampaignPromptData) string
- func RenderProjectUpdateInstructions(data CampaignPromptData) string
- func RenderWorkflowExecution(data CampaignPromptData) string
- func ValidateProjectUpdatePayload(payload any, expectedProjectURL string, expectedCampaignID string) []string
- func ValidateSpec(spec *CampaignSpec) []string
- func ValidateSpecWithSchema(spec *CampaignSpec) []string
- func ValidateWorkflowsExist(spec *CampaignSpec, workflowsDir string) []string
- type CampaignApprovalPolicy
- type CampaignGovernancePolicy
- type CampaignKPI
- type CampaignMetricsSnapshot
- type CampaignPromptData
- type CampaignRuntimeStatus
- type CampaignSpec
- type CampaignValidationResult
- type FusionResult
- type WorkflowMatch
Constants ¶
This section is empty.
Variables ¶
var CampaignGoalKeywords = map[string][]string{
"security": {
"security", "vulnerability", "vulnerabilities", "scan", "scanning",
"cve", "audit", "compliance", "threat", "detection",
},
"dependencies": {
"dependency", "dependencies", "upgrade", "update", "npm", "pip",
"package", "packages", "version", "outdated",
},
"documentation": {
"doc", "docs", "documentation", "guide", "guides", "readme",
"wiki", "reference", "tutorial",
},
"quality": {
"quality", "test", "testing", "lint", "linting", "coverage",
"code-quality", "static-analysis", "sonar",
},
"cicd": {
"ci", "cd", "build", "deploy", "deployment", "release",
"pipeline", "automation", "continuous",
},
}
CampaignGoalKeywords maps campaign types to relevant keywords
Functions ¶
func BuildCampaignGenerator ¶ added in v0.37.0
func BuildCampaignGenerator() *workflow.WorkflowData
BuildCampaignGenerator constructs the campaign-generator workflow This workflow is triggered when users label issues with "create-agentic-campaign" and handles campaign creation, project setup, and assignment to Copilot Coding Agent
func BuildOrchestrator ¶
func BuildOrchestrator(spec *CampaignSpec, campaignFilePath string) (*workflow.WorkflowData, string)
BuildOrchestrator constructs a minimal agentic workflow representation for a given CampaignSpec. The resulting WorkflowData is compiled via the standard CompileWorkflowDataWithValidation pipeline, and the orchestratorPath determines the emitted .lock.yml name.
func ComputeCompiledState ¶
func ComputeCompiledState(spec CampaignSpec, workflowsDir string) string
ComputeCompiledState inspects the compiled state of all workflows referenced by a campaign. It returns:
"Yes" - all referenced workflows exist and are compiled & up-to-date "No" - at least one workflow exists but is missing a lock file or is stale "Missing workflow" - at least one referenced workflow markdown file does not exist "N/A" - campaign does not reference any workflows
func CreateSpecSkeleton ¶
CreateSpecSkeleton creates a new campaign spec YAML file under .github/workflows/ with a minimal skeleton definition. It returns the relative file path created.
func FetchCursorFreshnessFromRepoMemory ¶ added in v0.33.10
func FetchCursorFreshnessFromRepoMemory(cursorGlob string) (cursorPath string, cursorUpdatedAt string)
FetchCursorFreshnessFromRepoMemory finds the latest cursor/checkpoint file matching cursorGlob in the memory/campaigns branch and returns the matched path along with a best-effort freshness timestamp derived from git history.
Errors are treated as "no cursor" rather than failing the command.
func NewCommand ¶
NewCommand creates the `gh aw campaign` command that surfaces first-class campaign definitions from YAML files.
func RenderClosingInstructions ¶ added in v0.33.2
func RenderClosingInstructions() string
RenderClosingInstructions renders the closing instructions
func RenderOrchestratorInstructions ¶ added in v0.33.2
func RenderOrchestratorInstructions(data CampaignPromptData) string
RenderOrchestratorInstructions renders the orchestrator instructions with the given data.
func RenderProjectUpdateInstructions ¶ added in v0.33.2
func RenderProjectUpdateInstructions(data CampaignPromptData) string
RenderProjectUpdateInstructions renders the project update instructions with the given data
func RenderWorkflowExecution ¶ added in v0.37.0
func RenderWorkflowExecution(data CampaignPromptData) string
RenderWorkflowExecution renders the workflow execution instructions with the given data.
func ValidateProjectUpdatePayload ¶ added in v0.34.4
func ValidateProjectUpdatePayload(payload any, expectedProjectURL string, expectedCampaignID string) []string
ValidateProjectUpdatePayload enforces the governed update-project contract.
This validator is intentionally deterministic: - JSON Schema enforces payload shape. - Semantic checks enforce equality constraints that JSON Schema cannot.
payload is expected to be a YAML/JSON-decoded structure (map[string]any, etc.).
func ValidateSpec ¶
func ValidateSpec(spec *CampaignSpec) []string
ValidateSpec performs lightweight semantic validation of a single CampaignSpec and returns a slice of human-readable problems.
It uses JSON schema validation first, then adds additional semantic checks.
func ValidateSpecWithSchema ¶
func ValidateSpecWithSchema(spec *CampaignSpec) []string
ValidateSpecWithSchema validates a CampaignSpec against the JSON schema. Returns a list of validation error messages, or an empty list if valid.
func ValidateWorkflowsExist ¶
func ValidateWorkflowsExist(spec *CampaignSpec, workflowsDir string) []string
ValidateWorkflowsExist checks that all workflows referenced in a campaign spec actually exist in the .github/workflows directory. Returns a list of problems for workflows that don't exist.
Types ¶
type CampaignApprovalPolicy ¶
type CampaignApprovalPolicy struct {
RequiredApprovals int `yaml:"required-approvals,omitempty" json:"required-approvals,omitempty"`
RequiredRoles []string `yaml:"required-roles,omitempty" json:"required-roles,omitempty"`
ChangeControl bool `yaml:"change-control,omitempty" json:"change-control,omitempty"`
}
CampaignApprovalPolicy captures basic approval expectations for a campaign. It is intentionally lightweight and advisory; enforcement is left to workflows and organizational process.
type CampaignGovernancePolicy ¶ added in v0.33.10
type CampaignGovernancePolicy struct {
// MaxNewItemsPerRun caps how many new items (issues/PRs) the launcher should
// add to the Project board per run. 0 means "use defaults".
MaxNewItemsPerRun int `yaml:"max-new-items-per-run,omitempty" json:"max_new_items_per_run,omitempty"`
// MaxDiscoveryItemsPerRun caps how many candidate issues/PRs the launcher
// and orchestrator may scan during discovery in a single run.
// 0 means "use defaults".
MaxDiscoveryItemsPerRun int `yaml:"max-discovery-items-per-run,omitempty" json:"max_discovery_items_per_run,omitempty"`
// MaxDiscoveryPagesPerRun caps how many pages of results the launcher and
// orchestrator may fetch in a single run.
// 0 means "use defaults".
MaxDiscoveryPagesPerRun int `yaml:"max-discovery-pages-per-run,omitempty" json:"max_discovery_pages_per_run,omitempty"`
// OptOutLabels is a list of labels that opt an issue/PR out of campaign
// tracking. Items with any of these labels should be ignored by launcher/
// orchestrator.
OptOutLabels []string `yaml:"opt-out-labels,omitempty" json:"opt_out_labels,omitempty"`
// DoNotDowngradeDoneItems prevents moving Project status backwards (e.g.
// Done -> In Progress) if the underlying issue/PR is reopened.
DoNotDowngradeDoneItems *bool `yaml:"do-not-downgrade-done-items,omitempty" json:"do_not_downgrade_done_items,omitempty"`
// MaxProjectUpdatesPerRun controls the update-project safe-output maximum
// for generated coordinator workflows. 0 means "use defaults".
MaxProjectUpdatesPerRun int `yaml:"max-project-updates-per-run,omitempty" json:"max_project_updates_per_run,omitempty"`
// MaxCommentsPerRun controls the add-comment safe-output maximum for
// generated coordinator workflows. 0 means "use defaults".
MaxCommentsPerRun int `yaml:"max-comments-per-run,omitempty" json:"max_comments_per_run,omitempty"`
}
CampaignGovernancePolicy captures lightweight pacing and opt-out policies. This is intentionally scoped to what gh-aw can apply safely and consistently via prompts and safe-output job limits.
type CampaignKPI ¶ added in v0.34.0
type CampaignKPI struct {
// ID is an optional stable identifier for this KPI.
ID string `yaml:"id,omitempty" json:"id,omitempty"`
// Name is a human-readable KPI name.
Name string `yaml:"name" json:"name"`
// Priority indicates whether this KPI is the primary KPI or a supporting KPI.
// Expected values: primary, supporting.
Priority string `yaml:"priority,omitempty" json:"priority,omitempty"`
// Unit is an optional unit string (e.g., percent, days, count).
Unit string `yaml:"unit,omitempty" json:"unit,omitempty"`
// Baseline is the baseline KPI value.
Baseline float64 `yaml:"baseline" json:"baseline"`
// Target is the target KPI value.
Target float64 `yaml:"target" json:"target"`
// TimeWindowDays is the rolling time window (in days) used to compute the KPI.
TimeWindowDays int `yaml:"time-window-days" json:"time-window-days"`
// Direction indicates whether improvement means increasing or decreasing.
// Expected values: increase, decrease.
Direction string `yaml:"direction,omitempty" json:"direction,omitempty"`
// Source describes the signal source used to compute the KPI.
// Expected values: ci, pull_requests, code_security, custom.
Source string `yaml:"source,omitempty" json:"source,omitempty"`
}
CampaignKPI defines a single KPI used for campaign measurement.
type CampaignMetricsSnapshot ¶
type CampaignMetricsSnapshot struct {
Date string `json:"date"` // Required: YYYY-MM-DD format
CampaignID string `json:"campaign_id"` // Required: campaign identifier
TasksTotal int `json:"tasks_total"` // Required: total task count (>= 0)
TasksCompleted int `json:"tasks_completed"` // Required: completed task count (>= 0)
TasksInProgress int `json:"tasks_in_progress,omitempty"`
TasksBlocked int `json:"tasks_blocked,omitempty"`
VelocityPerDay float64 `json:"velocity_per_day,omitempty"`
EstimatedCompletion string `json:"estimated_completion,omitempty"`
}
CampaignMetricsSnapshot describes the JSON structure used by campaign metrics snapshots written into the memory/campaigns branch.
This mirrors the example in the campaigns guide:
{
"date": "2025-01-16",
"campaign_id": "security-q1-2025",
"tasks_total": 200,
"tasks_completed": 15,
"tasks_in_progress": 30,
"tasks_blocked": 5,
"velocity_per_day": 7.5,
"estimated_completion": "2025-02-12"
}
func FetchMetricsFromRepoMemory ¶
func FetchMetricsFromRepoMemory(metricsGlob string) (*CampaignMetricsSnapshot, error)
FetchMetricsFromRepoMemory attempts to load the latest JSON metrics snapshot matching the provided glob from the memory/campaigns branch. It is best-effort: errors are logged and treated as "no metrics" rather than failing the command.
type CampaignPromptData ¶ added in v0.33.2
type CampaignPromptData struct {
// CampaignID is the unique identifier for this campaign.
CampaignID string
// CampaignName is the human-readable name of this campaign.
CampaignName string
// Objective is the campaign objective statement.
Objective string
// KPIs is the KPI definition list for this campaign.
KPIs []CampaignKPI
// ProjectURL is the GitHub Project URL
ProjectURL string
// CursorGlob is a glob for locating the durable cursor/checkpoint file in repo-memory.
CursorGlob string
// MetricsGlob is a glob for locating the metrics snapshot directory in repo-memory.
MetricsGlob string
// MaxDiscoveryItemsPerRun caps how many candidate items may be scanned during discovery.
MaxDiscoveryItemsPerRun int
// MaxDiscoveryPagesPerRun caps how many pages may be fetched during discovery.
MaxDiscoveryPagesPerRun int
// MaxProjectUpdatesPerRun caps how many project update writes may happen per run.
MaxProjectUpdatesPerRun int
// MaxProjectCommentsPerRun caps how many comments may be written per run.
MaxProjectCommentsPerRun int
// Workflows is the list of worker workflow IDs associated with this campaign.
Workflows []string
}
CampaignPromptData holds data for rendering campaign orchestrator prompts.
type CampaignRuntimeStatus ¶
type CampaignRuntimeStatus struct {
ID string `json:"id" console:"header:ID"`
Name string `json:"name" console:"header:Name"`
Workflows []string `json:"workflows,omitempty" console:"header:Workflows,omitempty"`
Compiled string `json:"compiled" console:"header:Compiled"`
// Optional metrics from repo-memory (when MetricsGlob is set and a
// matching JSON snapshot is found on the memory/campaigns branch).
MetricsTasksTotal int `json:"metrics_tasks_total,omitempty" console:"header:Tasks Total,omitempty"`
MetricsTasksCompleted int `json:"metrics_tasks_completed,omitempty" console:"header:Tasks Completed,omitempty"`
MetricsVelocityPerDay float64 `json:"metrics_velocity_per_day,omitempty" console:"header:Velocity/Day,omitempty"`
MetricsEstimatedCompletion string `json:"metrics_estimated_completion,omitempty" console:"header:ETA,omitempty"`
// Optional durable cursor/checkpoint info from repo-memory.
CursorPath string `json:"cursor_path,omitempty" console:"header:Cursor Path,omitempty,maxlen:40"`
CursorUpdatedAt string `json:"cursor_updated_at,omitempty" console:"header:Cursor Updated,omitempty,maxlen:30"`
}
CampaignRuntimeStatus represents the live status of a campaign, including compiled workflow state and optional metrics/cursor info.
func BuildRuntimeStatus ¶
func BuildRuntimeStatus(spec CampaignSpec, workflowsDir string) CampaignRuntimeStatus
BuildRuntimeStatus builds a CampaignRuntimeStatus for a single campaign spec.
type CampaignSpec ¶
type CampaignSpec struct {
ID string `yaml:"id" json:"id" console:"header:ID"`
Name string `yaml:"name" json:"name" console:"header:Name,maxlen:30"`
Description string `yaml:"description,omitempty" json:"description,omitempty" console:"header:Description,omitempty,maxlen:60"`
// Objective is an optional outcome-owned statement describing what success means
// for this campaign.
Objective string `yaml:"objective,omitempty" json:"objective,omitempty" console:"header:Objective,omitempty,maxlen:60"`
// KPIs is an optional list of KPIs used to measure progress toward the objective.
// Recommended: 1 primary KPI plus up to 2 supporting KPIs.
KPIs []CampaignKPI `yaml:"kpis,omitempty" json:"kpis,omitempty"`
// ProjectURL points to the GitHub Project used as the primary campaign
// dashboard.
ProjectURL string `yaml:"project-url,omitempty" json:"project_url,omitempty" console:"header:Project URL,omitempty,maxlen:40"`
// Version is an optional spec version string (for example: v1).
// When omitted, it defaults to v1 during validation.
Version string `yaml:"version,omitempty" json:"version,omitempty" console:"header:Version,omitempty"`
// Workflows associates this campaign with one or more workflow IDs
// (basename of the Markdown file without .md).
Workflows []string `yaml:"workflows,omitempty" json:"workflows,omitempty" console:"header:Workflows,omitempty,maxlen:40"`
// TrackerLabel is an optional label used to discover worker-created issues/PRs
// (for example: campaign:security-q1-2025). When set, the discovery precomputation
// step will search for items with this label.
TrackerLabel string `yaml:"tracker-label,omitempty" json:"tracker_label,omitempty" console:"header:Tracker Label,omitempty,maxlen:40"`
// DiscoveryRepos defines the explicit list of repositories (in owner/repo format)
// where worker workflows are discovered. This controls the scope of GitHub searches
// for issues/PRs created by worker workflows.
DiscoveryRepos []string `yaml:"discovery-repos,omitempty" json:"discovery_repos,omitempty" console:"header:Discovery Repos,omitempty,maxlen:60"`
// DiscoveryOrgs optionally defines the list of GitHub organizations where worker
// workflows are discovered. When specified, any repository within these organizations
// is searched for worker-created issues/PRs.
DiscoveryOrgs []string `yaml:"discovery-orgs,omitempty" json:"discovery_orgs,omitempty" console:"header:Discovery Orgs,omitempty,maxlen:40"`
// AllowedRepos defines the explicit list of repositories (in owner/repo format)
// that this campaign is allowed to discover and operate on. When omitted, defaults
// to the current repository where the campaign is defined.
AllowedRepos []string `yaml:"allowed-repos,omitempty" json:"allowed_repos,omitempty" console:"header:Allowed Repos,omitempty,maxlen:60"`
// AllowedOrgs optionally defines the list of GitHub organizations that this
// campaign is allowed to discover and operate on. When specified, any repository
// within these organizations is considered in-scope.
AllowedOrgs []string `yaml:"allowed-orgs,omitempty" json:"allowed_orgs,omitempty" console:"header:Allowed Orgs,omitempty,maxlen:40"`
// MemoryPaths documents where this campaign writes its repo-memory
// (for example: memory/campaigns/incident-response/**).
MemoryPaths []string `yaml:"memory-paths,omitempty" json:"memory_paths,omitempty" console:"header:Memory Paths,omitempty,maxlen:40"`
// MetricsGlob is an optional glob (relative to the repository root)
// used to locate JSON metrics snapshots stored in the
// memory/campaigns branch. When set, `gh aw campaign status` will
// attempt to read the latest matching metrics file and surface a few
// key fields.
MetricsGlob string `yaml:"metrics-glob,omitempty" json:"metrics_glob,omitempty" console:"header:Metrics Glob,omitempty,maxlen:30"`
// CursorGlob is an optional glob (relative to the repository root)
// used to locate a durable cursor/checkpoint file stored in the
// memory/campaigns branch. When set, generated coordinator workflows
// will be instructed to continue incremental discovery from this cursor
// and `gh aw campaign status` will surface its freshness.
CursorGlob string `yaml:"cursor-glob,omitempty" json:"cursor_glob,omitempty" console:"header:Cursor Glob,omitempty,maxlen:30"`
// Owners lists the primary human owners for this campaign.
Owners []string `yaml:"owners,omitempty" json:"owners,omitempty" console:"header:Owners,omitempty,maxlen:30"`
// ExecutiveSponsors lists executive stakeholders or sponsors who are
// accountable for the outcome of this campaign.
ExecutiveSponsors []string `` /* 127-byte string literal not displayed */
// RiskLevel is an optional free-form field (e.g. low/medium/high).
RiskLevel string `yaml:"risk-level,omitempty" json:"risk_level,omitempty" console:"header:Risk Level,omitempty"`
// State describes the lifecycle stage of the campaign definition.
// Valid values are: planned, active, paused, completed, archived.
State string `yaml:"state,omitempty" json:"state,omitempty" console:"header:State,omitempty"`
// Tags provide free-form categorization for reporting (for example:
// security, modernization, rollout).
Tags []string `yaml:"tags,omitempty" json:"tags,omitempty" console:"header:Tags,omitempty,maxlen:30"`
// AllowedSafeOutputs documents which safe-outputs operations this
// campaign is expected to use (for example: create-issue,
// create-pull-request). This is currently informational but can be
// enforced by validation in the future.
AllowedSafeOutputs []string `` /* 133-byte string literal not displayed */
// ProjectGitHubToken is an optional GitHub token expression (e.g.,
// ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}) used for GitHub Projects v2
// operations. When specified, this token is passed to the update-project
// safe output configuration in the generated orchestrator workflow.
ProjectGitHubToken string `` /* 126-byte string literal not displayed */
// Governance configures lightweight pacing and opt-out policies for campaign
// orchestrator workflows. These guardrails are primarily enforced through
// generated prompts and safe-output maxima.
Governance *CampaignGovernancePolicy `yaml:"governance,omitempty" json:"governance,omitempty"`
// ApprovalPolicy describes high-level approval expectations for this
// campaign (for example: number of approvals and required roles).
ApprovalPolicy *CampaignApprovalPolicy `yaml:"approval-policy,omitempty" json:"approval-policy,omitempty"`
// Engine specifies the AI engine to use for the campaign orchestrator.
// Valid values: copilot, claude, codex, custom.
// Default: copilot (when not specified).
Engine string `yaml:"engine,omitempty" json:"engine,omitempty" console:"header:Engine,omitempty"`
// ConfigPath is populated at load time with the relative path of
// the YAML file on disk, to help users locate definitions.
ConfigPath string `yaml:"-" json:"config_path" console:"header:Config Path,maxlen:60"`
}
CampaignSpec defines a first-class campaign configuration loaded from YAML frontmatter in Markdown files.
Files are discovered from the local repository under:
.github/workflows/*.campaign.md
This provides a thin, declarative layer on top of existing agentic workflows and repo-memory conventions.
func FilterSpecs ¶
func FilterSpecs(specs []CampaignSpec, pattern string) []CampaignSpec
FilterSpecs filters campaigns by a simple substring match on ID or Name (case-insensitive). When pattern is empty, all campaigns are returned.
func LoadSpecs ¶
func LoadSpecs(rootDir string) ([]CampaignSpec, error)
LoadSpecs scans the repository for campaign spec files and returns a slice of CampaignSpec. Campaign specs are stored as .campaign.md files in .github/workflows/. If the workflows directory does not exist, it returns an empty slice and no error.
func ValidateSpecFromFile ¶
func ValidateSpecFromFile(filePath string) (*CampaignSpec, []string, error)
ValidateSpecFromFile validates a campaign spec file by loading and validating it. This is useful for validation commands that operate on files directly.
type CampaignValidationResult ¶
type CampaignValidationResult struct {
ID string `json:"id" console:"header:ID"`
Name string `json:"name" console:"header:Name"`
ConfigPath string `json:"config_path" console:"header:Config Path"`
Problems []string `json:"problems,omitempty" console:"header:Problems,omitempty"`
}
CampaignValidationResult represents the result of validating a campaign spec.
type FusionResult ¶ added in v0.37.0
type FusionResult struct {
OriginalWorkflowID string // Original workflow ID
CampaignWorkflowID string // New workflow ID in campaign folder
OutputPath string // Path to the fused workflow file
WorkflowDispatch bool // Whether workflow_dispatch was added
}
FusionResult contains the result of fusing a workflow for campaign use
func FuseMultipleWorkflows ¶ added in v0.37.0
func FuseMultipleWorkflows(rootDir string, workflowIDs []string, campaignID string) ([]FusionResult, error)
FuseMultipleWorkflows fuses multiple workflows for a campaign
func FuseWorkflowForCampaign ¶ added in v0.37.0
func FuseWorkflowForCampaign(rootDir string, workflowID string, campaignID string) (*FusionResult, error)
FuseWorkflowForCampaign takes an existing workflow and adapts it for campaign use by adding workflow_dispatch trigger and storing it in a campaign-specific folder
type WorkflowMatch ¶ added in v0.37.0
type WorkflowMatch struct {
ID string // Workflow ID (basename without .md)
FilePath string // Relative path to workflow file
Name string // Workflow name from frontmatter
Description string // Workflow description
Keywords []string // Matching keywords
Score int // Match score (higher is better)
}
WorkflowMatch represents a discovered workflow that matches campaign goals
func DiscoverWorkflows ¶ added in v0.37.0
func DiscoverWorkflows(rootDir string, campaignGoals []string) ([]WorkflowMatch, error)
DiscoverWorkflows scans the repository for existing workflows that match campaign goals