### Workflow Installation Instructions Source: https://github.com/github/gh-aw/blob/main/scratchpad/safe-output-messages.md Provide users with instructions to add the workflow to their repository, including a CLI command and a link to the usage guide. ```markdown > > To add this workflow in your repository, run `gh aw add owner/repo/path@ref`. See [usage guide](https://github.github.com/gh-aw/setup/cli/). ``` -------------------------------- ### Install and Configure Ollama Source: https://github.com/github/gh-aw/blob/main/pkg/cli/workflows/test-ollama-threat-detection.md Installs Ollama, starts its service in the background, and waits for it to become ready. Includes error handling and logging for each step. ```javascript const fs = require('fs'); const path = require('path'); // ===== INSTALL OLLAMA ===== core.info('🚀 Starting Ollama installation...'); try { core.info('📥 Downloading Ollama installer...'); await exec.exec('curl', ['-fsSL', 'https://ollama.com/install.sh', '-o', '/tmp/install-ollama.sh']); core.info('📦 Installing Ollama...'); await exec.exec('sh', ['/tmp/install-ollama.sh']); core.info('✅ Verifying Ollama installation...'); const versionOutput = await exec.getExecOutput('ollama', ['--version']); core.info(`Ollama version: ${versionOutput.stdout.trim()}`); core.info('✅ Ollama installed successfully'); } catch (error) { core.setFailed(`Failed to install Ollama: ${error instanceof Error ? error.message : String(error)}`); throw error; } // ===== START OLLAMA SERVICE ===== core.info('🚀 Starting Ollama service...'); const logDir = '/tmp/gh-aw/ollama-logs'; if (!fs.existsSync(logDir)) { fs.mkdirSync(logDir, { recursive: true }); } // Start Ollama service in background const ollamaServeLog = fs.openSync(`${logDir}/ollama-serve.log`, 'w'); const ollamaServeErrLog = fs.openSync(`${logDir}/ollama-serve-error.log`, 'w'); exec.exec('ollama', ['serve'], { detached: true, silent: true, outStream: fs.createWriteStream(`${logDir}/ollama-serve.log`), errStream: fs.createWriteStream(`${logDir}/ollama-serve-error.log`) }).then(() => { core.info('Ollama service started in background'); }).catch(err => { core.warning(`Ollama service background start: ${err.message}`); }); // Wait for service to be ready core.info('⏳ Waiting for Ollama service to be ready...'); let retries = 30; while (retries > 0) { try { await exec.exec('curl', ['-f', 'http://localhost:11434/api/version'], { silent: true }); core.info('✅ Ollama service is ready'); break; } catch (e) { retries--; if (retries === 0) { throw new Error('Ollama service did not become ready in time'); } await new Promise(resolve => setTimeout(resolve, 1000)); } } ``` -------------------------------- ### Generate Npm Install Steps Source: https://github.com/github/gh-aw/blob/main/scratchpad/adding-new-engines.md Use this function to generate installation steps for npm-based engines. Set the last parameter to true to include Node.js setup. ```go npmSteps := GenerateNpmInstallSteps( "@company/engine", version, "Install Engine", "engine-cli", true, // Include Node.js setup ) steps = append(steps, npmSteps...) ``` -------------------------------- ### Base Ubuntu Image Setup Source: https://github.com/github/gh-aw/blob/main/research/ubuntulatest.md Starts with the Ubuntu 24.04 base image and configures non-interactive package installation and UTC timezone. ```dockerfile FROM ubuntu:24.04 # Prevent interactive prompts during package installation ENV DEBIAN_FRONTEND=noninteractive # Set timezone (GitHub Actions uses UTC) RUN ln -snf /usr/share/zoneinfo/UTC /etc/localtime && echo UTC > /etc/timezone ``` -------------------------------- ### Complete Workflow Example with gh-aw CLI Source: https://github.com/github/gh-aw/blob/main/actions/setup-cli/README.md A full GitHub Actions workflow demonstrating checkout, gh-aw CLI installation, and verification. ```yaml name: Test gh-aw on: [push] jobs: test: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v6 - name: Install gh-aw uses: github/gh-aw/actions/setup-cli@main with: version: v0.37.18 - name: Verify installation run: | gh aw version gh aw --help ``` -------------------------------- ### Install Development Dependencies Source: https://github.com/github/gh-aw/blob/main/DEVGUIDE.md Install Go dependencies for the project. Use 'deps-dev' for a full development setup including linters. ```bash # Install basic Go dependencies make deps # For full development (including linter) make deps-dev ``` -------------------------------- ### Add Workflow with Interactive Setup Source: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/setup/cli.md Adds a new workflow to the repository using an interactive guided setup process. It checks requirements and prompts for necessary information. ```bash gh aw add-wizard githubnext/agentics/ci-doctor ``` -------------------------------- ### Add Pre-Steps for Threat Detection Setup Source: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/threat-detection.md Define steps that run before the AI engine executes. Use these for setup tasks like connecting to a private AI gateway or installing security tools. ```yaml safe-outputs: create-pull-request: threat-detection: steps: - name: Connect to Security Gateway run: | echo "Setting up secure connection to analysis gateway..." # Authentication and connection setup ``` -------------------------------- ### Prefix Matching for Repositories Example Source: https://github.com/github/gh-aw/blob/main/scratchpad/guard-policies-specification.md Demonstrates using prefix matching with wildcards to allow repositories starting with specific prefixes within an organization. ```yaml tools: github: mode: remote toolsets: [default] allowed-repos: - "myorg/api-*" # Matches api-gateway, api-service, etc. - "myorg/web-*" # Matches web-frontend, web-backend, etc. min-integrity: approved ``` -------------------------------- ### Start a Trial Run Source: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/experimental/trial-ops.md Initiates a trial run for a specified workflow from GitHub. The CLI creates a temporary private repository, installs and executes the workflow, and saves results locally and on GitHub. ```bash gh aw trial githubnext/agentics/weekly-research ``` -------------------------------- ### Install oh-my-opencode Source: https://github.com/github/gh-aw/blob/main/scratchpad/oh-my-code.md Use the interactive installer or paste the command into OpenCode for agent-assisted installation. ```bash # Interactive installer bunx oh-my-opencode install ``` ```bash # Or let an agent do it # Paste into OpenCode: "Install and configure oh-my-opencode" ``` -------------------------------- ### Install Dependencies Source: https://github.com/github/gh-aw/blob/main/DEVGUIDE.md Install Go and npm dependencies for the first time or after dependency changes. `deps-dev` also installs development tools like linters. ```bash make deps # Install Go and npm dependencies (~1.5min first run) ``` ```bash make deps-dev # Add development tools like linter (~5-8min) ``` -------------------------------- ### Using Pre-configured Styles Source: https://github.com/github/gh-aw/blob/main/pkg/styles/README.md Demonstrates how to use predefined styles like Error, Success, and Command for rendering text. Also shows how to create custom styles using adaptive colors. ```go import "github.com/github/gh-aw/pkg/styles" // Use pre-configured styles fmt.Println(styles.Error.Render("Something went wrong")) fmt.Println(styles.Success.Render("Operation completed")) fmt.Println(styles.Command.Render("gh aw compile")) // Use adaptive colors for custom styles customStyle := lipgloss.NewStyle( Foreground(styles.ColorInfo), Bold(true) ) fmt.Println(customStyle.Render("Custom styled text")) ``` -------------------------------- ### Pin Node.js Version in Dockerfile Source: https://github.com/github/gh-aw/blob/main/research/ubuntulatest.md Example of pinning a specific Node.js version during the Docker image build process. It fetches the NodeSource setup script and installs the specified version. ```dockerfile # Pin Node.js version ARG NODE_VERSION=20.20.0 RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \ apt-get install -y nodejs=${NODE_VERSION}* ``` -------------------------------- ### Initialize and Use Coordinator Source: https://github.com/github/gh-aw/blob/main/pkg/agentdrain/README.md Demonstrates initializing a Coordinator with specified stages, loading default weights, training with an event, analyzing an event, accessing clusters, and saving/restoring snapshots and weights. ```go stages := []string{"plan", "tool_call", "finish"} coord, err := agentdrain.NewCoordinator(cfg, stages) // Load default trained weights err = coord.LoadDefaultWeights() // Training phase — route events from known-good runs to stage miners result, err := coord.TrainEvent(evt) // Analyze an event result, report, err := coord.AnalyzeEvent(evt) // Access all clusters across all stages allClusters := coord.AllClusters() // Save/restore snapshots snapshots, err := coord.SaveSnapshots() err = coord.LoadSnapshots(snapshots) // Save/restore coordinator weights as JSON data, err := coord.SaveWeightsJSON() err = coord.LoadWeightsJSON(data) ``` -------------------------------- ### Fetch Specific Branches with Checkout Source: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/checkout.md Specify individual branches or use glob patterns with `fetch` to retrieve only the necessary refs. For example, `fetch: ["main", "feature/*"]` will fetch the `main` branch and any branches starting with `feature/`. `fetch-depth: 0` is used to get the full history. ```yaml checkout: - repository: org/target-repo github-token: ${{ secrets.CROSS_REPO_PAT }} fetch: ["main", "feature/*"] fetch-depth: 0 ``` -------------------------------- ### Complete Dockerfile Example Source: https://github.com/github/gh-aw/blob/main/research/ubuntulatest.md A comprehensive Dockerfile setting up an Ubuntu 24.04 environment with essential tools, programming languages, and Docker. ```dockerfile FROM ubuntu:24.04 # Prevent interactive prompts ENV DEBIAN_FRONTEND=noninteractive # Set timezone RUN ln -snf /usr/share/zoneinfo/UTC /etc/localtime && echo UTC > /etc/timezone # Update system and install essentials RUN apt-get update && apt-get upgrade -y && \ apt-get install -y \ build-essential \ curl \ wget \ git \ unzip \ zip \ tar \ gzip \ bzip2 \ xz-utils \ ca-certificates \ gnupg \ lsb-release \ software-properties-common \ sudo \ jq \ vim \ nano \ openssh-client \ rsync # Install Node.js 20 LTS RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \ apt-get install -y nodejs && \ npm install -g yarn pnpm # Install Python 3.12 RUN apt-get install -y \ python3 \ python3-pip \ python3-venv \ python3-dev && \ ln -s /usr/bin/python3 /usr/bin/python && \ ln -s /usr/bin/pip3 /usr/bin/pip # Install Docker RUN install -m 0755 -d /etc/apt/keyrings && \ curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc && \ chmod a+r /etc/apt/keyrings/docker.asc && \ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ tee /etc/apt/sources.list.d/docker.list > /dev/null && \ apt-get update && \ apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # Install GitHub CLI RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | \ dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && \ chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg && \ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | \ tee /etc/apt/sources.list.d/github-cli.list > /dev/null && \ apt-get update && \ apt-get install -y gh # Install Java (Temurin 17 & 21) RUN wget -qO - https://packages.adoptium.net/artifactory/api/gpg/key/public | \ gpg --dearmor -o /usr/share/keyrings/adoptium.gpg && \ echo "deb [signed-by=/usr/share/keyrings/adoptium.gpg] https://packages.adoptium.net/artifactory/deb $(lsb_release -cs) main" | \ tee /etc/apt/sources.list.d/adoptium.list && \ apt-get update && \ apt-get install -y temurin-17-jdk temurin-21-jdk # Set Java 17 as default ENV JAVA_HOME=/usr/lib/jvm/temurin-17-jdk-amd64 ENV PATH="${JAVA_HOME}/bin:${PATH}" # Install Go ARG GO_VERSION=1.23.12 RUN wget https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz && \ tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz && \ rm go${GO_VERSION}.linux-amd64.tar.gz ENV PATH="/usr/local/go/bin:${PATH}" ENV GOPATH=/root/go ENV PATH="${GOPATH}/bin:${PATH}" # Install Ruby RUN apt-get install -y ruby-full # Set up environment variables ENV DEBIAN_FRONTEND= ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin # Cleanup RUN apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* # Set working directory WORKDIR /workspace # Default command CMD ["/bin/bash"] ``` -------------------------------- ### Compile Command Examples Source: https://github.com/github/gh-aw/blob/main/scratchpad/cli-command-patterns.md Illustrates practical usage examples for the 'compile' command, covering basic usage, common options, and advanced scenarios like compiling directories or using watch mode. ```go Examples: gh aw compile workflow.md # Compile single workflow gh aw compile workflow.md -v # Verbose output gh aw compile -d .github/workflows # Compile directory gh aw compile workflow.md --watch # Watch mode gh aw compile --all # Compile all workflows ``` -------------------------------- ### JSON-RPC Error: Dependency Installation Failure Source: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/specs/mcp-scripts-specification.md Example of a JSON-RPC error response indicating a failure during the installation of a required dependency for a tool. ```json { "jsonrpc": "2.0", "error": { "code": -32603, "message": "Internal error", "data": { "error": "Dependency installation failed", "dependency": "requests", "package_manager": "pip", "stderr": "Could not find a version that satisfies the requirement requests" } }, "id": "req-101" } ``` -------------------------------- ### Initialize gh-aw with Templates Source: https://github.com/github/gh-aw/blob/main/scratchpad/mdflow.md Demonstrates how to initialize gh-aw projects using different curated templates, including a basic option and an mdflow-inspired minimal syntax. ```bash gh aw init issue-responder gh aw init pr-reviewer --basic gh aw init daily-report --template mdflow ``` -------------------------------- ### Generate Engine Installation Steps Source: https://github.com/github/gh-aw/blob/main/scratchpad/adding-new-engines.md Implement GetInstallationSteps to define the sequence of GitHub Actions steps required to set up your engine. This can include secret validation, package installation, and firewall configuration. ```go func (e *MyEngine) GetInstallationSteps(workflowData *WorkflowData) []GitHubActionStep { myEngineLog.Printf("Generating installation steps: workflow=%s", workflowData.Name) // Skip installation if custom command is specified if workflowData.EngineConfig != nil && workflowData.EngineConfig.Command != "" { myEngineLog.Printf("Skipping installation: custom command specified (%s)", workflowData.EngineConfig.Command) return []GitHubActionStep{} } var steps []GitHubActionStep // Add secret validation step secretValidation := GenerateMultiSecretValidationStep( []string{"MY_ENGINE_API_KEY"}, "My AI Engine", "https://github.github.com/gh-aw/reference/engines/#my-ai-engine", ) steps = append(steps, secretValidation) // Determine engine version version := "1.0.0" // Default version if workflowData.EngineConfig != nil && workflowData.EngineConfig.Version != "" { version = workflowData.EngineConfig.Version } // Add installation steps (example: npm package) npmSteps := GenerateNpmInstallSteps( "@my-company/my-engine", version, "Install My AI Engine", "my-engine", true, // Include Node.js setup ) steps = append(steps, npmSteps...) // Add firewall installation if enabled if isFirewallEnabled(workflowData) { firewallConfig := getFirewallConfig(workflowData) agentConfig := getAgentConfig(workflowData) var awfVersion string if firewallConfig != nil { awfVersion = firewallConfig.Version } awfInstall := generateAWFInstallationStep(awfVersion, agentConfig) if len(awfInstall) > 0 { steps = append(steps, awfInstall) } } return steps } ``` -------------------------------- ### Install Go Source: https://github.com/github/gh-aw/blob/main/research/ubuntulatest.md Installs a specified version of Go (defaulting to 1.23.12) by downloading and extracting the archive. Sets up Go environment variables. ```dockerfile # Install Go ARG GO_VERSION=1.23.12 RUN wget https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz && \ tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz && \ rm go${GO_VERSION}.linux-amd64.tar.gz ENV PATH="/usr/local/go/bin:${PATH}" ENV GOPATH=/root/go ENV PATH="${GOPATH}/bin:${PATH}" # Verify installation RUN go version ``` -------------------------------- ### Example Workflow Pattern for Analyzing Pull Requests Source: https://github.com/github/gh-aw/blob/main/pkg/workflow/testdata/wasm_golden/fixtures/shared/mcp-pagination.md This markdown example outlines a workflow for analyzing pull requests incrementally, starting with a summary and fetching details only when necessary to manage token limits. ```markdown # Analyze Recent Pull Requests 1. Fetch 10 most recent PRs (stay under token limit) 2. For each PR, get summary without full diff 3. If detailed analysis needed, fetch files for specific PR separately 4. Process results incrementally rather than loading everything at once ``` -------------------------------- ### Initialize and Analyze Agent Event Source: https://github.com/github/gh-aw/blob/main/pkg/agentdrain/README.md Demonstrates how to create a coordinator, load default weights, and analyze an incoming agent event to detect new behavior patterns. ```go import "github.com/github/gh-aw/pkg/agentdrain" // Create a coordinator with default config cfg := agentdrain.DefaultConfig() stages := []string{"plan", "tool_call", "finish"} coord, err := agentdrain.NewCoordinator(cfg, stages) if err != nil { panic(err) } // Load pre-trained weights if err := coord.LoadDefaultWeights(); err != nil { panic(err) } // Analyze an incoming agent event evt := agentdrain.AgentEvent{ Stage: "tool_call", Fields: map[string]string{"tool": "read_file", "path": "/workspace/main.go"}, } result, report, err := coord.AnalyzeEvent(evt) if err != nil { panic(err) } if report.IsNewTemplate { fmt.Printf("New behavior pattern detected (score=%.2f): %s\n", report.AnomalyScore, report.Reason) } ``` -------------------------------- ### Example of Interactive Workflow Selection and Input Source: https://github.com/github/gh-aw/blob/main/docs/interactive-run-mode.md This example demonstrates the user experience within the interactive mode, from workflow selection to input filling and execution confirmation. ```bash $ gh aw run # Displays workflow list # Select workflow with arrow keys # Fill in inputs # Confirm and run ``` -------------------------------- ### Custom Prompt Configuration Source: https://github.com/github/gh-aw/blob/main/specs/security-architecture-spec.md Configure custom prompts to guide threat detection. This example specifies a focus on SQL injection vulnerabilities. ```yaml threat-detection: prompt: "Focus on SQL injection vulnerabilities" ``` -------------------------------- ### Go Test Fixture Example Source: https://github.com/github/gh-aw/blob/main/scratchpad/dev.md Shows how to use test fixtures by reading data from the `testdata/` directory for testing file parsing. Requires the `testify` package for assertions. ```go // Use testdata/ directory for fixtures func TestParseWorkflow(t *testing.T) { data, err := os.ReadFile("testdata/workflow.md") require.NoError(t, err) wf, err := ParseWorkflow(data) require.NoError(t, err) assert.Equal(t, "Test Workflow", wf.Name) } ``` -------------------------------- ### List Engines with Details CLI Example Source: https://github.com/github/gh-aw/blob/main/scratchpad/engine-review-summary.md This command can be used to list available engines and their detailed capabilities. ```bash gh aw engines list --detailed ``` -------------------------------- ### Setup Node.js Action Source: https://github.com/github/gh-aw/blob/main/pkg/cli/workflows/test-claude-playwright-screenshots.md Configures Node.js environment with caching for npm dependencies, specifying the cache path for the docs directory. ```yaml - name: Setup Node.js uses: actions/setup-node@v6 with: node-version: '24' cache: 'npm' cache-dependency-path: 'docs/package-lock.json' ``` -------------------------------- ### Clone and Setup Repository Source: https://github.com/github/gh-aw/blob/main/DEVGUIDE.md Clone the gh-aw repository and navigate into the project directory. ```bash # Clone the repository git clone https://github.com/github/gh-aw.git cd gh-aw ``` -------------------------------- ### Tool Description with Constraints Source: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/specs/safe-outputs-specification.md Example of a tool schema ('add_comment') detailing its functionality and enforced constraints. This description guides LLMs to avoid violations. ```json { "name": "add_comment", "description": "Add a comment to an existing GitHub issue, pull request, or discussion. IMPORTANT: Comments are subject to validation constraints enforced by the MCP server - maximum 65536 characters for the complete comment (including footer which is added automatically), 10 mentions (@username), and 50 links. Exceeding these limits will result in an immediate error with specific guidance.", "inputSchema": { "type": "object", "properties": { "body": { "type": "string", "description": "The comment text in Markdown format. CONSTRAINTS: The complete comment (your body text + automatically added footer) must not exceed 65536 characters total. A footer (~200-500 characters) is automatically appended, so leave adequate space. Maximum 10 mentions (@username), maximum 50 links (http/https URLs). If these limits are exceeded, the tool call will fail with a detailed error message indicating which constraint was violated." } } } } ``` -------------------------------- ### Test My Engine Installation Steps Source: https://github.com/github/gh-aw/blob/main/scratchpad/adding-new-engines.md Ensure that the GetInstallationSteps method returns a non-empty list of steps, including secret validation. ```go func TestMyEngineInstallationSteps(t *testing.T) { engine := NewMyEngine() workflowData := &WorkflowData{ Name: "test-workflow", ParsedTools: &ToolsConfig{}, } steps := engine.GetInstallationSteps(workflowData) assert.NotNil(t, steps) assert.NotEmpty(t, steps) // Should have at least secret validation } ``` -------------------------------- ### TypeScript Example for Copilot SDK Usage Source: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/specs/copilot-sdk-driver-specification.md This example demonstrates how to use the Copilot SDK in a Node.js environment. It requires specific environment variables to be set for configuration, including API endpoints, authentication tokens, and model details. Ensure the '@github/copilot-sdk' package is installed. ```typescript import { readFile } from "node:fs/promises"; import { CopilotClient, RuntimeConnection } from "@github/copilot-sdk"; const promptPath = process.env.GH_AW_PROMPT; const sdkUri = process.env.COPILOT_SDK_URI; const connectionToken = process.env.COPILOT_CONNECTION_TOKEN; const model = process.env.COPILOT_MODEL; if (!promptPath || !sdkUri || !connectionToken || !model) { throw new Error("Missing required standalone environment variables."); } const rawTimeoutValue = process.env.COPILOT_SDK_SEND_TIMEOUT_MS; const sendTimeoutMs = rawTimeoutValue && /^[1-9]\d*$/.test(rawTimeoutValue) ? Number(rawTimeoutValue) : 600000; const allowedLogLevels = new Set(["none", "error", "warning", "info", "debug", "all"]); const rawLogLevel = process.env.COPILOT_SDK_LOG_LEVEL || "warning"; const logLevel = allowedLogLevels.has(rawLogLevel) ? rawLogLevel : "warning"; const workingDirectory = process.env.GITHUB_WORKSPACE || process.cwd(); const prompt = await readFile(promptPath, "utf8"); const client = new CopilotClient({ connection: RuntimeConnection.forUri(sdkUri, { connectionToken, }), workingDirectory, logLevel, }); await client.start(); try { const session = await client.createSession({ model }); const response = await session.sendAndWait({ prompt }, { timeoutMs: sendTimeoutMs }); console.log(response); await session.disconnect(); } finally { await client.stop(); } ``` -------------------------------- ### Setup Action Usage Source: https://github.com/github/gh-aw/blob/main/actions/setup/README.md This snippet shows how to use the setup action in a GitHub Actions workflow. It specifies the destination directory for the copied script files. ```yaml steps: - uses: actions/checkout@v6 with: sparse-checkout: | actions - name: Setup Scripts uses: ./actions/setup with: destination: ${{ runner.temp }}/gh-aw/actions ``` -------------------------------- ### Valid Unix/Linux/macOS Payload Directory Paths Source: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/mcp-gateway.md Examples of absolute paths that are valid for the `payloadDir` configuration on Unix-like systems. These paths must start with '/'. ```text "/var/lib/mcp-gateway/payloads" "/tmp/gateway-payloads" "/opt/mcp/data/payloads" ``` -------------------------------- ### Inspect Custom Spans Source: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/guides/open-telemetry.mdx Filter and inspect spans emitted by your tool using `jq`. This example selects spans where the span name starts with 'my-tool'. ```bash cat otel.jsonl | jq 'select(.resourceSpans[].scopeSpans[].spans[].name | startswith("my-tool"))' ``` -------------------------------- ### Godoc Comment for GetInstallationSteps Source: https://github.com/github/gh-aw/blob/main/scratchpad/adding-new-engines.md Example of a godoc comment for the GetInstallationSteps method, explaining its purpose and what it includes. ```go // GetInstallationSteps returns the GitHub Actions steps needed to install My AI Engine // Includes secret validation and npm package installation func (e *MyEngine) GetInstallationSteps(workflowData *WorkflowData) []GitHubActionStep { // ... } ``` -------------------------------- ### Valid Windows Payload Directory Paths Source: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/mcp-gateway.md Examples of absolute paths that are valid for the `payloadDir` configuration on Windows systems. These paths must start with a drive letter followed by ':' and '\'. ```text "C:\\Program Files\\MCP Gateway\\payloads" "D:\\gateway\\payloads" "C:\\temp\\payloads" ``` -------------------------------- ### Custom Server Type with Tools Configuration Source: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/mcp-gateway.md An example of a custom server type configuration that includes specific tools for its implementation. This demonstrates a more detailed setup for a custom server type. ```json { "mcpServers": { "my-custom-server": { "type": "safeinputs", "tools": { "greet": { "description": "Greet user", "script": "return { message: 'Hello!' };" } } } }, "gateway": { "port": 8080, "domain": "localhost", "apiKey": "secret" }, "customSchemas": { "safeinputs": "https://docs.github.com/gh-aw/schemas/mcp-scripts-config.schema.json" } } ``` -------------------------------- ### Example Output: Live GitHub API Test (With Token) Source: https://github.com/github/gh-aw/blob/main/actions/setup/js/TESTING_LIVE_API.md This output demonstrates a successful run of the standalone live GitHub API test script, showing the computed hash and a summary of the process. ```bash $ GITHUB_TOKEN=ghp_xxx node test-live-github-api.cjs 🔍 Testing frontmatter hash with live GitHub API Repository: github/gh-aw Branch: main Workflow: .github/workflows/audit-workflows.md 📡 Connecting to GitHub API... 📥 Fetching workflow from GitHub API... ✅ Success! Hash computed from live GitHub API data: db7af18719075a860ef7e08bb6f49573ac35fbd88190db4f21da3499d3604971 🔄 Verifying determinism (fetching again)... ✅ Hashes match - computation is deterministic 📊 Summary: - Successfully fetched workflow from live GitHub API - Processed workflow with imports (shared/mcp/tavily.md, etc.) - Computed deterministic SHA-256 hash - Verified hash consistency across multiple API calls ✨ All tests passed! The JavaScript implementation works correctly with GitHub API. ``` -------------------------------- ### End-to-End Testing with Playwright CLI Source: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/playwright.md Configure a workflow for end-to-end testing. This setup starts a development server on localhost:3000 and then uses Playwright CLI to navigate and capture screenshots on failure. ```yaml --- on: workflow_dispatch: tools: playwright: mode: cli bash: [":*"] network: allowed: - defaults - playwright - "localhost" permissions: contents: read --- # E2E Testing Start the dev server on localhost:3000, then drive a full user journey with `playwright-cli browser_navigate --url "http://localhost:3000"`. Report any failures with screenshots. ``` -------------------------------- ### Complete MCP Script Example with Imports and Outputs Source: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/mcp-scripts.md A full example demonstrating workflow dispatch, importing an MCP script, defining a tool to analyze text, and creating a GitHub discussion with the results. ```yaml --- on: workflow_dispatch engine: copilot imports: - shared/pr-data-mcp-script.md mcp-scripts: analyze-text: description: "Analyze text and return statistics" inputs: text: type: string required: true script: | const words = text.split(/\s+/).filter(w => w.length > 0); return { word_count: words.length, char_count: text.length, avg_word_length: (text.length / words.length).toFixed(2) }; safe-outputs: create-discussion: category: "General" --- Analyze provided text using the `analyze-text` tool and create a discussion with results. ``` -------------------------------- ### Usage Examples for semverutil Source: https://github.com/github/gh-aw/blob/main/pkg/semverutil/README.md Demonstrates common use cases including normalizing version strings, parsing into structured types, comparing versions, and checking compatibility. ```go import "github.com/github/gh-aw/pkg/semverutil" // Normalize a version string semverutil.EnsureVPrefix("1.2.3") // → "v1.2.3" // Parse into structured type ver := semverutil.ParseVersion("v1.2.3") if ver != nil { fmt.Println(ver.Major, ver.Minor, ver.Patch) // 1 2 3 } // Compare versions semverutil.Compare("v2.0.0", "v1.9.9") // 1 (v2 is newer) // Check major-version compatibility semverutil.IsCompatible("v5.1.0", "v5") // true semverutil.IsCompatible("v6.0.0", "v5") // false ``` -------------------------------- ### Get High Token Usage Runs with jq Source: https://github.com/github/gh-aw/blob/main/scratchpad/mcp_logs_guardrails.md Filter runs based on token usage using `jq`. This example selects runs where token usage exceeds 10000 tokens. ```json { "jq": ".runs | map(select(.token_usage > 10000))" } ``` -------------------------------- ### Complete Minimal Dockerfile Example Source: https://github.com/github/gh-aw/blob/main/scratchpad/ubuntulatest.md A comprehensive Dockerfile for an Ubuntu 24.04 environment, including base packages, Node.js, Python, Docker, and GitHub CLI. Sets up the working directory and environment variables. ```dockerfile FROM ubuntu:24.04 # Avoid prompts from apt ENV DEBIAN_FRONTEND=noninteractive ENV TZ=UTC # Update and install base packages RUN apt-get update && apt-get upgrade -y && \ apt-get install -y \ ca-certificates \ curl \ wget \ git \ gnupg \ lsb-release \ software-properties-common \ build-essential \ cmake \ make \ jq \ unzip \ zip \ tar \ gzip \ rsync \ openssh-client && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* # Install Node.js 20.x RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \ apt-get install -y nodejs && \ npm install -g yarn npm@latest && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* # Install Python RUN apt-get update && \ apt-get install -y \ python3 \ python3-pip \ python3-venv \ python3-dev && \ python3 -m pip install --upgrade pip setuptools wheel && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* # Install Docker RUN curl -fsSL https://get.docker.com | sh && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* # Install GitHub CLI RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | \ dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && \ chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg && \ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | \ tee /etc/apt/sources.list.d/github-cli.list && \ apt-get update && \ apt-get install -y gh && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* # Set up working directory RUN mkdir -p /github/workspace /github/home WORKDIR /github/workspace # Set environment variables ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin ENV GITHUB_WORKSPACE=/github/workspace ENV HOME=/github/home # Default command CMD ["/bin/bash"] ``` -------------------------------- ### Complete Go Example for Issue Creation Source: https://github.com/github/gh-aw/blob/main/scratchpad/errors.md This Go example shows how to validate issue configurations and create an issue with error handling and simulated API calls. It includes custom validation functions and retry logic. ```go package main import ( "fmt" "os" "github.com/github/gh-aw/pkg/console" "github.com/github/gh-aw/pkg/workflow" ) type IssueConfig struct { Title string Body string Labels []string State string } func ValidateAndCreateIssue(config *IssueConfig) error { // Validate inputs if err := validateIssueConfig(config); err != nil { fmt.Fprintln(os.Stderr, console.FormatErrorMessage(err.Error())) return err } // Attempt to create issue if err := createIssueWithRetry(config); err != nil { fmt.Fprintln(os.Stderr, console.FormatErrorMessage(err.Error())) return err } fmt.Fprintln(os.Stderr, console.FormatSuccessMessage("Issue created successfully")) return nil } func validateIssueConfig(config *IssueConfig) error { // Validate title if err := workflow.ValidateRequired("title", config.Title); err != nil { return err } if err := workflow.ValidateMaxLength("title", config.Title, 256); err != nil { return err } // Validate body if err := workflow.ValidateMaxLength("body", config.Body, 65536); err != nil { return err } // Validate state validStates := []string{"open", "closed"} if err := workflow.ValidateInList("state", config.State, validStates); err != nil { return err } return nil } func createIssueWithRetry(config *IssueConfig) error { // Simulate API call with potential failure err := callGitHubAPI(config) if err != nil { return workflow.NewOperationError( "create", "issue", "", err, "Check repository access and rate limits", ) } return nil } func callGitHubAPI(config *IssueConfig) error { // Actual GitHub API call would go here return nil } ``` -------------------------------- ### Workflow Step with Script Mode Source: https://github.com/github/gh-aw/blob/main/scratchpad/actions.md Example GitHub Actions job step for direct script execution in Script mode. This involves checking out the repository and running the setup script manually. ```yaml jobs: create_issue: runs-on: ubuntu-latest steps: - name: Checkout actions folder uses: actions/checkout@v6 with: repository: github/gh-aw sparse-checkout: | actions path: /tmp/gh-aw/actions-source depth: 1 persist-credentials: false - name: Setup Scripts run: | bash /tmp/gh-aw/actions-source/actions/setup/setup.sh env: INPUT_DESTINATION: /opt/gh-aw/actions - name: Create Output Issue id: create_issue uses: ./actions/create-issue env: GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} with: token: ${{ secrets.GITHUB_TOKEN }} ``` -------------------------------- ### Go: Get Action Dependencies Source: https://github.com/github/gh-aw/blob/main/scratchpad/actions.md This Go function maps action names to their required JavaScript files. It includes special handling for the 'setup' action to dynamically discover all script files. ```go func getActionDependencies(actionName string) []string { // For setup, use the dynamic script discovery // This ensures all .cjs files are included automatically if actionName == "setup" { return workflow.GetAllScriptFilenames() } return []string{} } ``` -------------------------------- ### Finalize Context with Pre-Agent Steps Source: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/steps-jobs.md Add custom steps before the agent job starts to ensure prerequisites like MCP installation or configuration are completed. This is useful for last-moment validations or context preparation. ```yaml pre-agent-steps: - name: Finalize Context run: ./scripts/prepare-agent-context.sh ``` -------------------------------- ### Setup Go and Python Runtimes in AWF Source: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/sandbox.md Use setup actions for Go and Python within the AWF sandbox. Both `go build` and `python3` commands will be available after these steps. ```yaml --- jobs: setup: steps: - uses: actions/setup-go@v5 with: go-version: '1.25' - uses: actions/setup-python@v5 with: python-version: '3.12' --- Use `go build` or `python3` - both are available. ``` -------------------------------- ### Get Summary with First N Runs using jq Source: https://github.com/github/gh-aw/blob/main/scratchpad/mcp_logs_guardrails.md Combine summary statistics with a limited number of recent runs using `jq`. This example shows the summary and the first 5 runs. ```json { "jq": "{summary, runs: .runs[:5]}" } ``` -------------------------------- ### Shell Script Retry Configuration Source: https://github.com/github/gh-aw/blob/main/scratchpad/error-recovery-patterns.md Basic shell script setup for retrying operations, defining maximum attempts and initial delay. This example uses `set -euo pipefail` for robust error handling. ```bash #!/usr/bin/env bash set -euo pipefail # Configuration MAX_ATTEMPTS=3 RETRY_DELAY=2 # Initial delay in seconds ``` -------------------------------- ### Test Action Locally Source: https://github.com/github/gh-aw/blob/main/actions/setup/README.md Execute this script to test the setup action locally. It handles building the action scripts and verifying the file copy process. ```bash ./test-setup-local.sh ``` -------------------------------- ### Build and Verify Development Environment Source: https://github.com/github/gh-aw/blob/main/DEVGUIDE.md Verify GitHub CLI authentication, run all tests, check code formatting, run the linter, and build the binary. ```bash # Verify GitHub CLI is authenticated gh auth status # Run all tests to ensure everything works make test # Check code formatting make fmt-check # Run linter (may require golangci-lint installation) make lint # Build and test the binary make build ./gh-aw --help ```