source dump of claude code
at main 158 lines 6.3 kB view raw
1import type { Command } from '../commands.js' 2import { 3 getAttributionTexts, 4 getEnhancedPRAttribution, 5} from '../utils/attribution.js' 6import { getDefaultBranch } from '../utils/git.js' 7import { executeShellCommandsInPrompt } from '../utils/promptShellExecution.js' 8import { getUndercoverInstructions, isUndercover } from '../utils/undercover.js' 9 10const ALLOWED_TOOLS = [ 11 'Bash(git checkout --branch:*)', 12 'Bash(git checkout -b:*)', 13 'Bash(git add:*)', 14 'Bash(git status:*)', 15 'Bash(git push:*)', 16 'Bash(git commit:*)', 17 'Bash(gh pr create:*)', 18 'Bash(gh pr edit:*)', 19 'Bash(gh pr view:*)', 20 'Bash(gh pr merge:*)', 21 'ToolSearch', 22 'mcp__slack__send_message', 23 'mcp__claude_ai_Slack__slack_send_message', 24] 25 26function getPromptContent( 27 defaultBranch: string, 28 prAttribution?: string, 29): string { 30 const { commit: commitAttribution, pr: defaultPrAttribution } = 31 getAttributionTexts() 32 // Use provided PR attribution or fall back to default 33 const effectivePrAttribution = prAttribution ?? defaultPrAttribution 34 const safeUser = process.env.SAFEUSER || '' 35 const username = process.env.USER || '' 36 37 let prefix = '' 38 let reviewerArg = ' and `--reviewer anthropics/claude-code`' 39 let addReviewerArg = ' (and add `--add-reviewer anthropics/claude-code`)' 40 let changelogSection = ` 41 42## Changelog 43<!-- CHANGELOG:START --> 44[If this PR contains user-facing changes, add a changelog entry here. Otherwise, remove this section.] 45<!-- CHANGELOG:END -->` 46 let slackStep = ` 47 485. After creating/updating the PR, check if the user's CLAUDE.md mentions posting to Slack channels. If it does, use ToolSearch to search for "slack send message" tools. If ToolSearch finds a Slack tool, ask the user if they'd like you to post the PR URL to the relevant Slack channel. Only post if the user confirms. If ToolSearch returns no results or errors, skip this step silently—do not mention the failure, do not attempt workarounds, and do not try alternative approaches.` 49 if (process.env.USER_TYPE === 'ant' && isUndercover()) { 50 prefix = getUndercoverInstructions() + '\n' 51 reviewerArg = '' 52 addReviewerArg = '' 53 changelogSection = '' 54 slackStep = '' 55 } 56 57 return `${prefix}## Context 58 59- \`SAFEUSER\`: ${safeUser} 60- \`whoami\`: ${username} 61- \`git status\`: !\`git status\` 62- \`git diff HEAD\`: !\`git diff HEAD\` 63- \`git branch --show-current\`: !\`git branch --show-current\` 64- \`git diff ${defaultBranch}...HEAD\`: !\`git diff ${defaultBranch}...HEAD\` 65- \`gh pr view --json number 2>/dev/null || true\`: !\`gh pr view --json number 2>/dev/null || true\` 66 67## Git Safety Protocol 68 69- NEVER update the git config 70- NEVER run destructive/irreversible git commands (like push --force, hard reset, etc) unless the user explicitly requests them 71- NEVER skip hooks (--no-verify, --no-gpg-sign, etc) unless the user explicitly requests it 72- NEVER run force push to main/master, warn the user if they request it 73- Do not commit files that likely contain secrets (.env, credentials.json, etc) 74- Never use git commands with the -i flag (like git rebase -i or git add -i) since they require interactive input which is not supported 75 76## Your task 77 78Analyze all changes that will be included in the pull request, making sure to look at all relevant commits (NOT just the latest commit, but ALL commits that will be included in the pull request from the git diff ${defaultBranch}...HEAD output above). 79 80Based on the above changes: 811. Create a new branch if on ${defaultBranch} (use SAFEUSER from context above for the branch name prefix, falling back to whoami if SAFEUSER is empty, e.g., \`username/feature-name\`) 822. Create a single commit with an appropriate message using heredoc syntax${commitAttribution ? `, ending with the attribution text shown in the example below` : ''}: 83\`\`\` 84git commit -m "$(cat <<'EOF' 85Commit message here.${commitAttribution ? `\n\n${commitAttribution}` : ''} 86EOF 87)" 88\`\`\` 893. Push the branch to origin 904. If a PR already exists for this branch (check the gh pr view output above), update the PR title and body using \`gh pr edit\` to reflect the current diff${addReviewerArg}. Otherwise, create a pull request using \`gh pr create\` with heredoc syntax for the body${reviewerArg}. 91 - IMPORTANT: Keep PR titles short (under 70 characters). Use the body for details. 92\`\`\` 93gh pr create --title "Short, descriptive title" --body "$(cat <<'EOF' 94## Summary 95<1-3 bullet points> 96 97## Test plan 98[Bulleted markdown checklist of TODOs for testing the pull request...]${changelogSection}${effectivePrAttribution ? `\n\n${effectivePrAttribution}` : ''} 99EOF 100)" 101\`\`\` 102 103You have the capability to call multiple tools in a single response. You MUST do all of the above in a single message.${slackStep} 104 105Return the PR URL when you're done, so the user can see it.` 106} 107 108const command = { 109 type: 'prompt', 110 name: 'commit-push-pr', 111 description: 'Commit, push, and open a PR', 112 allowedTools: ALLOWED_TOOLS, 113 get contentLength() { 114 // Use 'main' as estimate for content length calculation 115 return getPromptContent('main').length 116 }, 117 progressMessage: 'creating commit and PR', 118 source: 'builtin', 119 async getPromptForCommand(args, context) { 120 // Get default branch and enhanced PR attribution 121 const [defaultBranch, prAttribution] = await Promise.all([ 122 getDefaultBranch(), 123 getEnhancedPRAttribution(context.getAppState), 124 ]) 125 let promptContent = getPromptContent(defaultBranch, prAttribution) 126 127 // Append user instructions if args provided 128 const trimmedArgs = args?.trim() 129 if (trimmedArgs) { 130 promptContent += `\n\n## Additional instructions from user\n\n${trimmedArgs}` 131 } 132 133 const finalContent = await executeShellCommandsInPrompt( 134 promptContent, 135 { 136 ...context, 137 getAppState() { 138 const appState = context.getAppState() 139 return { 140 ...appState, 141 toolPermissionContext: { 142 ...appState.toolPermissionContext, 143 alwaysAllowRules: { 144 ...appState.toolPermissionContext.alwaysAllowRules, 145 command: ALLOWED_TOOLS, 146 }, 147 }, 148 } 149 }, 150 }, 151 '/commit-push-pr', 152 ) 153 154 return [{ type: 'text', text: finalContent }] 155 }, 156} satisfies Command 157 158export default command