diff --git a/.github/workflows/doc-maintainer.lock.yml b/.github/workflows/doc-maintainer.lock.yml index d178ac345..45b123843 100644 --- a/.github/workflows/doc-maintainer.lock.yml +++ b/.github/workflows/doc-maintainer.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"16eb71b6c213a7052433080ebca8a68346b6f8d9683c03ccbc62fe8b6b0506aa","body_hash":"549a11666803cdba99c9cde62365525d9361728a02289a867d3b526337efa5bd","compiler_version":"v0.77.5","strict":true,"agent_id":"claude","agent_model":"claude-haiku-4-5"} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"8e9d89dab758de99e6243ce0945a3766fb68afd3a62af834a7ba1b0af4f7b55a","body_hash":"65095a79bc26398081419b57f84a0121f5e4810d7eb25393ec28c95d47bf5a68","compiler_version":"v0.77.5","strict":true,"agent_id":"claude","agent_model":"claude-haiku-4-5"} # gh-aw-manifest: {"version":1,"secrets":["ANTHROPIC_API_KEY","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"34e114876b0b11c390a56381ad16ebd13914f8d5","version":"v4"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"3ea13c02d765410340d533515cb31a7eef2baaf0","version":"v0.77.5"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.58"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.58"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.58"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.22"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]} # ___ _ _ # / _ \ | | (_) @@ -177,26 +177,26 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_8aecc41c0f833fa2_EOF' + cat << 'GH_AW_PROMPT_98934d6844f92c22_EOF' - GH_AW_PROMPT_8aecc41c0f833fa2_EOF + GH_AW_PROMPT_98934d6844f92c22_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_8aecc41c0f833fa2_EOF' + cat << 'GH_AW_PROMPT_98934d6844f92c22_EOF' Tools: create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_8aecc41c0f833fa2_EOF + GH_AW_PROMPT_98934d6844f92c22_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_8aecc41c0f833fa2_EOF' + cat << 'GH_AW_PROMPT_98934d6844f92c22_EOF' - GH_AW_PROMPT_8aecc41c0f833fa2_EOF + GH_AW_PROMPT_98934d6844f92c22_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_8aecc41c0f833fa2_EOF' + cat << 'GH_AW_PROMPT_98934d6844f92c22_EOF' {{#runtime-import .github/workflows/doc-maintainer.md}} - GH_AW_PROMPT_8aecc41c0f833fa2_EOF + GH_AW_PROMPT_98934d6844f92c22_EOF } > "$GH_AW_PROMPT" - name: Substitute placeholders uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -321,7 +321,9 @@ jobs: EXPR_NEEDS_CHECK_RELEVANT_CHANGES_OUTPUTS_CHANGED_COUNT: ${{ needs.check_relevant_changes.outputs.changed_count }} id: context name: Build documentation maintainer context - run: "CONTEXT_DIR=/tmp/gh-aw/doc-maintainer-context\nmkdir -p \"$CONTEXT_DIR\"\nDOC_POOL=$(mktemp)\nTOKENS=$(mktemp)\nAFFECTED=$(mktemp)\nCOUNT=\"$EXPR_NEEDS_CHECK_RELEVANT_CHANGES_OUTPUTS_CHANGED_COUNT\"\n\n{\n find docs/ -name \"*.md\" 2>/dev/null\n find . -maxdepth 1 -name \"*.md\"\n} | sort > \"$DOC_POOL\"\n\ngit log --since=\"7 days ago\" --format=\"=== Commit %H: %s ===\" --patch --stat --unified=1 -- src/ containers/ scripts/ docs/ '*.md' | grep -v '^Binary' | head -100 > \"$CONTEXT_DIR/recent-diffs.txt\"\n\ngit log --since=\"7 days ago\" --format=\"%H\" -- src/ containers/ scripts/ | \\\n while read -r sha; do\n git show --name-only --format=\"\" \"$sha\" -- docs/ '*.md' 2>/dev/null\n done | grep -E '(^docs/.*\\.md$|^[^/]+\\.md$)' | sort -u | head -10 > \"$AFFECTED\" || true\n\nif [ ! -s \"$AFFECTED\" ]; then\n git log --since=\"7 days ago\" --name-only --format=\"\" -- src/ containers/ scripts/ | \\\n grep -v '^$' | sed -E 's|.*/||; s|\\.[^.]+$||' | \\\n tr '[:upper:]' '[:lower:]' | tr '[:punct:]' '\\n' | grep -E '^[a-z0-9]{3,}$' | sort -u > \"$TOKENS\" || true\n if [ -s \"$TOKENS\" ]; then\n grep -i -F -f \"$TOKENS\" \"$DOC_POOL\" | head -10 > \"$AFFECTED\" || true\n fi\nfi\n\nif [ ! -s \"$AFFECTED\" ]; then\n head -10 \"$DOC_POOL\" > \"$AFFECTED\"\nfi\n\ncp \"$AFFECTED\" \"$CONTEXT_DIR/affected-docs.txt\"\n{\n echo \"## Changes\"\n echo \"- changed_count: $COUNT\"\n echo \"- has_changes: true\"\n echo \"\"\n echo \"## Affected Documentation\"\n cat \"$CONTEXT_DIR/affected-docs.txt\"\n echo \"\"\n echo \"## Recent Git Diffs\"\n cat \"$CONTEXT_DIR/recent-diffs.txt\"\n} > \"$CONTEXT_DIR/context.md\"\n\nCONTEXT_SIZE=$(wc -c < \"$CONTEXT_DIR/context.md\" | tr -d ' ')\nDIFF_LINES=$(wc -l < \"$CONTEXT_DIR/recent-diffs.txt\" | tr -d ' ')\necho \"Context size: ${CONTEXT_SIZE} bytes\"\necho \"Diff lines: ${DIFF_LINES}\"\ncat \"$CONTEXT_DIR/affected-docs.txt\" || echo \"(empty)\"\nif [ \"$CONTEXT_SIZE\" -lt 100 ]; then\n echo \"::warning::Context file is empty or minimal ($CONTEXT_SIZE bytes). Skipping agent run.\"\n echo \"skip_agent=true\" >> \"$GITHUB_OUTPUT\"\nelse\n echo \"skip_agent=false\" >> \"$GITHUB_OUTPUT\"\nfi\n" + run: "CONTEXT_DIR=/tmp/gh-aw/doc-maintainer-context\nmkdir -p \"$CONTEXT_DIR\"\nDOC_POOL=$(mktemp)\nTOKENS=$(mktemp)\nAFFECTED=$(mktemp)\nCOUNT=\"$EXPR_NEEDS_CHECK_RELEVANT_CHANGES_OUTPUTS_CHANGED_COUNT\"\n\n{\n find docs/ -name \"*.md\" 2>/dev/null\n find . -maxdepth 1 -name \"*.md\"\n} | sort > \"$DOC_POOL\"\n\ngit log --since=\"7 days ago\" --format=\"=== Commit %H: %s ===\" --patch --stat --unified=1 -- src/ containers/ scripts/ docs/ '*.md' | grep -v '^Binary' | head -50 > \"$CONTEXT_DIR/recent-diffs.txt\"\n\ngit log --since=\"7 days ago\" --format=\"%H\" -- src/ containers/ scripts/ | \\\n while read -r sha; do\n git show --name-only --format=\"\" \"$sha\" -- docs/ '*.md' 2>/dev/null\n done | grep -E '(^docs/.*\\.md$|^[^/]+\\.md$)' | sort -u | head -3 > \"$AFFECTED\" || true\n\nif [ ! -s \"$AFFECTED\" ]; then\n git log --since=\"7 days ago\" --name-only --format=\"\" -- src/ containers/ scripts/ | \\\n grep -v '^$' | sed -E 's|.*/||; s|\\.[^.]+$||' | \\\n tr '[:upper:]' '[:lower:]' | tr '[:punct:]' '\\n' | grep -E '^[a-z0-9]{3,}$' | sort -u > \"$TOKENS\" || true\n if [ -s \"$TOKENS\" ]; then\n grep -i -F -f \"$TOKENS\" \"$DOC_POOL\" | head -3 > \"$AFFECTED\" || true\n fi\nfi\n\nif [ ! -s \"$AFFECTED\" ]; then\n head -3 \"$DOC_POOL\" > \"$AFFECTED\"\nfi\n\ncp \"$AFFECTED\" \"$CONTEXT_DIR/affected-docs.txt\"\n{\n echo \"## Changes\"\n echo \"- changed_count: $COUNT\"\n echo \"- has_changes: true\"\n echo \"\"\n echo \"## Affected Documentation\"\n cat \"$CONTEXT_DIR/affected-docs.txt\"\n echo \"\"\n echo \"## Recent Git Diffs\"\n cat \"$CONTEXT_DIR/recent-diffs.txt\"\n} > \"$CONTEXT_DIR/context.md\"\n\nCONTEXT_SIZE=$(wc -c < \"$CONTEXT_DIR/context.md\" | tr -d ' ')\nDIFF_LINES=$(wc -l < \"$CONTEXT_DIR/recent-diffs.txt\" | tr -d ' ')\necho \"Context size: ${CONTEXT_SIZE} bytes\"\necho \"Diff lines: ${DIFF_LINES}\"\ncat \"$CONTEXT_DIR/affected-docs.txt\" || echo \"(empty)\"\nif [ \"$CONTEXT_SIZE\" -lt 100 ]; then\n echo \"::warning::Context file is empty or minimal ($CONTEXT_SIZE bytes). Skipping agent run.\"\n echo \"skip_agent=true\" >> \"$GITHUB_OUTPUT\"\nelse\n echo \"skip_agent=false\" >> \"$GITHUB_OUTPUT\"\nfi\n" + - name: Pre-load affected documentation content + run: "CONTEXT_DIR=/tmp/gh-aw/doc-maintainer-context\nAFFECTED=\"$CONTEXT_DIR/affected-docs.txt\"\n\nif [ ! -s \"$AFFECTED\" ]; then\n echo \"No affected docs to pre-load\"\n exit 0\nfi\n\n{\n echo \"\"\n echo \"## Affected Documentation Content (pre-loaded — do not re-read these files)\"\n echo \"\"\n head -3 \"$AFFECTED\" | while read -r doc; do\n if [ -f \"$doc\" ]; then\n echo \"### File: $doc\"\n echo '```'\n head -200 \"$doc\"\n echo '```'\n echo \"\"\n fi\n done\n} >> \"$CONTEXT_DIR/context.md\"\n\nSIZE=$(wc -c < \"$CONTEXT_DIR/context.md\" | tr -d ' ')\necho \"Final context.md size: ${SIZE} bytes\"\n" - name: Configure Git credentials env: @@ -409,9 +411,9 @@ jobs: mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_699ba202ba893ca5_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_eec7e6280be3885f_EOF' {"create_pull_request":{"draft":false,"labels":["documentation","ai-generated"],"max":1,"max_patch_files":100,"max_patch_size":1024,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","CLAUDE.md","AGENTS.md"],"protected_files_policy":"request_review","reviewers":["copilot"],"title_prefix":"[docs] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_699ba202ba893ca5_EOF + GH_AW_SAFE_OUTPUTS_CONFIG_eec7e6280be3885f_EOF - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -620,7 +622,7 @@ jobs: export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.22' GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_3df07bad70a9508a_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_85c585c67827d353_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "safeoutputs": { @@ -638,7 +640,7 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_3df07bad70a9508a_EOF + GH_AW_MCP_CONFIG_85c585c67827d353_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -732,7 +734,7 @@ jobs: fi # shellcheck disable=SC1003 sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --tty --env-all --exclude-env ANTHROPIC_API_KEY --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --session-state-dir /tmp/gh-aw/sandbox/agent/session-state --enable-host-access --allow-host-ports 80,443,8080 --build-local \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/claude_harness.cjs claude --print --no-chrome --max-turns 5 --allowed-tools '\''Bash(cat),Bash(date),Bash(echo),Bash(git add:*),Bash(git branch:*),Bash(git checkout:*),Bash(git commit:*),Bash(git merge:*),Bash(git rm:*),Bash(git status),Bash(git switch:*),Bash(grep),Bash(head),Bash(ls),Bash(printf),Bash(pwd),Bash(safeoutputs:*),Bash(sort),Bash(tail),Bash(uniq),Bash(wc),Bash(yq),BashOutput,Edit,Edit(/tmp/*),Edit(/tmp/gh-aw/agent/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/*),MultiEdit(/tmp/gh-aw/agent/*),NotebookEdit,NotebookRead,Read,Read(/tmp/*),Read(/tmp/gh-aw/agent/*),Task,TodoWrite,Write,Write(/tmp/*),Write(/tmp/gh-aw/agent/*),mcp__safeoutputs'\'' --debug-file /tmp/gh-aw/agent-stdio.log --verbose --permission-mode acceptEdits --output-format stream-json --mcp-config "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/claude_harness.cjs claude --print --no-chrome --max-turns 8 --allowed-tools '\''Bash(cat),Bash(date),Bash(echo),Bash(git add:*),Bash(git branch:*),Bash(git checkout:*),Bash(git commit:*),Bash(git merge:*),Bash(git rm:*),Bash(git status),Bash(git switch:*),Bash(grep),Bash(head),Bash(ls),Bash(printf),Bash(pwd),Bash(safeoutputs:*),Bash(sort),Bash(tail),Bash(uniq),Bash(wc),Bash(yq),BashOutput,Edit,Edit(/tmp/*),Edit(/tmp/gh-aw/agent/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/*),MultiEdit(/tmp/gh-aw/agent/*),NotebookEdit,NotebookRead,Read,Read(/tmp/*),Read(/tmp/gh-aw/agent/*),Task,TodoWrite,Write,Write(/tmp/*),Write(/tmp/gh-aw/agent/*),mcp__safeoutputs'\'' --debug-file /tmp/gh-aw/agent-stdio.log --verbose --permission-mode acceptEdits --output-format stream-json --mcp-config "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} ANTHROPIC_MODEL: claude-haiku-4-5 @@ -742,7 +744,7 @@ jobs: DISABLE_BUG_COMMAND: 1 DISABLE_ERROR_REPORTING: 1 DISABLE_TELEMETRY: 1 - GH_AW_MAX_TURNS: 5 + GH_AW_MAX_TURNS: 8 GH_AW_MCP_CONFIG: ${{ runner.temp }}/gh-aw/mcp-config/mcp-servers.json GH_AW_PHASE: agent GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt @@ -935,7 +937,7 @@ jobs: run: | DIFF_PREVIEW=$(mktemp) COUNT=$(git log --since="7 days ago" --oneline -- src/ containers/ scripts/ | wc -l | tr -d ' ') - git log --since="7 days ago" --format="=== Commit %H: %s ===" --patch --stat --unified=1 -- src/ containers/ scripts/ docs/ '*.md' | grep -v '^Binary' | head -100 > "$DIFF_PREVIEW" + git log --since="7 days ago" --format="=== Commit %H: %s ===" --patch --stat --unified=1 -- src/ containers/ scripts/ docs/ '*.md' | grep -v '^Binary' | head -50 > "$DIFF_PREVIEW" DIFF_BYTES=$(wc -c < "$DIFF_PREVIEW" | tr -d ' ') HAS_CHANGES=false SKIP_AGENT=false @@ -1274,4 +1276,3 @@ jobs: /tmp/gh-aw/safe-output-items.jsonl /tmp/gh-aw/temporary-id-map.json if-no-files-found: ignore - diff --git a/.github/workflows/doc-maintainer.md b/.github/workflows/doc-maintainer.md index dfab5e9b3..25312ef92 100644 --- a/.github/workflows/doc-maintainer.md +++ b/.github/workflows/doc-maintainer.md @@ -33,7 +33,7 @@ jobs: run: | DIFF_PREVIEW=$(mktemp) COUNT=$(git log --since="7 days ago" --oneline -- src/ containers/ scripts/ | wc -l | tr -d ' ') - git log --since="7 days ago" --format="=== Commit %H: %s ===" --patch --stat --unified=1 -- src/ containers/ scripts/ docs/ '*.md' | grep -v '^Binary' | head -100 > "$DIFF_PREVIEW" + git log --since="7 days ago" --format="=== Commit %H: %s ===" --patch --stat --unified=1 -- src/ containers/ scripts/ docs/ '*.md' | grep -v '^Binary' | head -50 > "$DIFF_PREVIEW" DIFF_BYTES=$(wc -c < "$DIFF_PREVIEW" | tr -d ' ') HAS_CHANGES=false SKIP_AGENT=false @@ -52,7 +52,7 @@ jobs: engine: id: claude model: claude-haiku-4-5 - max-turns: 5 + max-turns: 8 tools: edit: bash: false @@ -89,24 +89,24 @@ steps: find . -maxdepth 1 -name "*.md" } | sort > "$DOC_POOL" - git log --since="7 days ago" --format="=== Commit %H: %s ===" --patch --stat --unified=1 -- src/ containers/ scripts/ docs/ '*.md' | grep -v '^Binary' | head -100 > "$CONTEXT_DIR/recent-diffs.txt" + git log --since="7 days ago" --format="=== Commit %H: %s ===" --patch --stat --unified=1 -- src/ containers/ scripts/ docs/ '*.md' | grep -v '^Binary' | head -50 > "$CONTEXT_DIR/recent-diffs.txt" git log --since="7 days ago" --format="%H" -- src/ containers/ scripts/ | \ while read -r sha; do git show --name-only --format="" "$sha" -- docs/ '*.md' 2>/dev/null - done | grep -E '(^docs/.*\.md$|^[^/]+\.md$)' | sort -u | head -10 > "$AFFECTED" || true + done | grep -E '(^docs/.*\.md$|^[^/]+\.md$)' | sort -u | head -3 > "$AFFECTED" || true if [ ! -s "$AFFECTED" ]; then git log --since="7 days ago" --name-only --format="" -- src/ containers/ scripts/ | \ grep -v '^$' | sed -E 's|.*/||; s|\.[^.]+$||' | \ tr '[:upper:]' '[:lower:]' | tr '[:punct:]' '\n' | grep -E '^[a-z0-9]{3,}$' | sort -u > "$TOKENS" || true if [ -s "$TOKENS" ]; then - grep -i -F -f "$TOKENS" "$DOC_POOL" | head -10 > "$AFFECTED" || true + grep -i -F -f "$TOKENS" "$DOC_POOL" | head -3 > "$AFFECTED" || true fi fi if [ ! -s "$AFFECTED" ]; then - head -10 "$DOC_POOL" > "$AFFECTED" + head -3 "$DOC_POOL" > "$AFFECTED" fi cp "$AFFECTED" "$CONTEXT_DIR/affected-docs.txt" @@ -133,6 +133,33 @@ steps: else echo "skip_agent=false" >> "$GITHUB_OUTPUT" fi + - name: Pre-load affected documentation content + run: | + CONTEXT_DIR=/tmp/gh-aw/doc-maintainer-context + AFFECTED="$CONTEXT_DIR/affected-docs.txt" + + if [ ! -s "$AFFECTED" ]; then + echo "No affected docs to pre-load" + exit 0 + fi + + { + echo "" + echo "## Affected Documentation Content (pre-loaded — do not re-read these files)" + echo "" + head -3 "$AFFECTED" | while read -r doc; do + if [ -f "$doc" ]; then + echo "### File: $doc" + echo '```' + head -200 "$doc" + echo '```' + echo "" + fi + done + } >> "$CONTEXT_DIR/context.md" + + SIZE=$(wc -c < "$CONTEXT_DIR/context.md" | tr -d ' ') + echo "Final context.md size: ${SIZE} bytes" --- # Documentation Maintainer @@ -161,7 +188,9 @@ Use the **Recent Git Diffs** section from that file as your **sole source** for ### 2. Identify Documentation Gaps -Review only the files listed under **Affected Documentation** in `/tmp/gh-aw/doc-maintainer-context/context.md` (max 10 files) and identify what needs to be updated. Do not proactively read additional files not in this list. +The full content of up to 3 affected documentation files is pre-loaded in `context.md` under **Affected Documentation Content**. Read from `context.md` directly and do not use the `edit` tool to re-read those files before making edits. + +Review only the files listed under **Affected Documentation** in `/tmp/gh-aw/doc-maintainer-context/context.md` (max 3 files) and identify what needs to be updated. Do not proactively read additional files not in this list. ### 3. Verify Code Examples @@ -192,5 +221,6 @@ After making updates, the safe-outputs system will automatically create a PR. In - Be conservative, accurate, minimal, and consistent with existing style. - Reference the commits that triggered your updates. +- Do not attempt to use bash commands or GitHub tools — they are unavailable in this environment. **Success**: Review 7-day commits, update out-of-sync docs, verify examples, and create a clear PR summary. diff --git a/scripts/ci/doc-maintainer-workflow.test.ts b/scripts/ci/doc-maintainer-workflow.test.ts index 13131f9c3..509b9ed5c 100644 --- a/scripts/ci/doc-maintainer-workflow.test.ts +++ b/scripts/ci/doc-maintainer-workflow.test.ts @@ -10,7 +10,7 @@ describe('doc maintainer workflow optimization config', () => { const source = fs.readFileSync(sourcePath, 'utf-8'); expect(source).toContain("if: needs.check_relevant_changes.outputs.has_changes == 'true' && needs.check_relevant_changes.outputs.skip_agent != 'true'"); - expect(source).toContain('max-turns: 5'); + expect(source).toContain('max-turns: 8'); expect(source).toContain('bash: false'); expect(source).toContain('github: false'); expect(source).toContain('Read `/tmp/gh-aw/doc-maintainer-context/context.md` first.'); @@ -20,14 +20,18 @@ describe('doc maintainer workflow optimization config', () => { expect(source).toContain('echo "## Changes"'); expect(source).toContain('echo "## Affected Documentation"'); expect(source).toContain('echo "## Recent Git Diffs"'); - expect(source).toContain("git log --since=\"7 days ago\" --format=\"=== Commit %H: %s ===\" --patch --stat --unified=1 -- src/ containers/ scripts/ docs/ '*.md' | grep -v '^Binary' | head -100"); + expect(source).toContain("git log --since=\"7 days ago\" --format=\"=== Commit %H: %s ===\" --patch --stat --unified=1 -- src/ containers/ scripts/ docs/ '*.md' | grep -v '^Binary' | head -50"); expect(source).toContain('skip_agent: ${{ steps.check.outputs.skip_agent }}'); expect(source).toContain('echo "::warning::Recent diffs are minimal ($DIFF_BYTES bytes). Skipping agent run."'); + expect(source).not.toContain('No markdown/docs changes in 7 days. Skipping documentation review.'); expect(source).toContain('echo "Context size: ${CONTEXT_SIZE} bytes"'); expect(source).toContain('echo "Diff lines: ${DIFF_LINES}"'); expect(source).toContain('echo "::warning::Context file is empty or minimal ($CONTEXT_SIZE bytes). Skipping agent run."'); expect(source).toContain('echo "skip_agent=true" >> "$GITHUB_OUTPUT"'); - expect(source).toContain("grep -i -F -f \"$TOKENS\" \"$DOC_POOL\" | head -10 > \"$AFFECTED\" || true"); + expect(source).toContain("grep -i -F -f \"$TOKENS\" \"$DOC_POOL\" | head -3 > \"$AFFECTED\" || true"); + expect(source).toContain('## Affected Documentation Content (pre-loaded — do not re-read these files)'); + expect(source).toContain('The full content of up to 3 affected documentation files is pre-loaded'); + expect(source).toContain('Do not attempt to use bash commands or GitHub tools — they are unavailable in this environment.'); expect(source).toContain( '**PR Description**: Summarize updated docs, reference the triggering code changes, and list what was verified.' ); @@ -51,13 +55,14 @@ describe('doc maintainer workflow optimization config', () => { it('compiles tool disabling into the lock workflow', () => { const lock = fs.readFileSync(lockPath, 'utf-8'); - expect(lock).toContain('--max-turns 5'); + expect(lock).toContain('--max-turns 8'); expect(lock).toContain("if: needs.check_relevant_changes.outputs.has_changes == 'true' && needs.check_relevant_changes.outputs.skip_agent != 'true'"); expect(lock).toContain('Build documentation maintainer context'); expect(lock).toContain('skip_agent: ${{ steps.check.outputs.skip_agent }}'); expect(lock).toContain('--patch --stat --unified=1'); - expect(lock).toContain('| grep -v \'^Binary\' | head -100 > \\"$CONTEXT_DIR/recent-diffs.txt\\"'); - expect(lock).toContain('head -10 > \\"$AFFECTED\\" || true'); + expect(lock).toContain('| grep -v \'^Binary\' | head -50 > \\"$CONTEXT_DIR/recent-diffs.txt\\"'); + expect(lock).toContain('head -3 > \\"$AFFECTED\\" || true'); + expect(lock).not.toContain('No markdown/docs changes in 7 days. Skipping documentation review.'); expect(lock).not.toContain('/tmp/gh-aw/doc-maintainer-context/has-changes.txt'); expect(lock).not.toContain('/tmp/gh-aw/doc-maintainer-context/changed-count.txt'); expect(lock).not.toContain('mcp__github');