MCPcopy Create free account
hub / github.com/QodeXcli/QodeX / execute

Method execute

src/tools/git/create-pr.ts:42–114  ·  view source on GitHub ↗
(args: z.infer<typeof GitCreatePrArgs>, ctx: ToolContext)

Source from the content-addressed store, hash-verified

40 argsSchema = GitCreatePrArgs;
41
42 async execute(args: z.infer<typeof GitCreatePrArgs>, ctx: ToolContext): Promise<ToolResult> {
43 if (!await isGitRepo(ctx.cwd, ctx.signal)) {
44 return { content: '[NOT_A_GIT_REPO] Current directory is not inside a git working tree.', isError: true };
45 }
46
47 // Verify gh is available
48 const ghAvail = await runOnce('gh', ['--version'], ctx.cwd, ctx.signal);
49 if (ghAvail.exitCode !== 0) {
50 return {
51 content: '[GH_NOT_INSTALLED] The GitHub CLI (`gh`) is not installed or not in PATH. ' +
52 'Install it from https://cli.github.com/, then run `gh auth login`. ' +
53 'For non-GitHub remotes (GitLab, Gitea, etc.), use `bash` directly with the relevant tool.',
54 isError: true,
55 };
56 }
57
58 // Verify gh is authenticated
59 const authR = await runOnce('gh', ['auth', 'status'], ctx.cwd, ctx.signal);
60 if (authR.exitCode !== 0) {
61 return {
62 content: '[GH_NOT_AUTHENTICATED] `gh` is installed but not authenticated. Run `gh auth login` first.\n' +
63 (authR.stderr.trim() || authR.stdout.trim()),
64 isError: true,
65 };
66 }
67
68 // Get current branch
69 const branchR = await git(['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: ctx.cwd, signal: ctx.signal });
70 if (branchR.exitCode !== 0 || branchR.stdout.trim() === 'HEAD') {
71 return {
72 content: '[DETACHED_HEAD] Cannot create a PR from a detached HEAD. Check out a branch first.',
73 isError: true,
74 };
75 }
76 const branch = branchR.stdout.trim();
77
78 // Push if requested and no upstream is set
79 const doPush = args.push !== false;
80 if (doPush) {
81 const upstreamR = await git(['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'], { cwd: ctx.cwd, signal: ctx.signal });
82 const hasUpstream = upstreamR.exitCode === 0 && upstreamR.stdout.trim() !== '';
83 const pushArgs = hasUpstream ? ['push'] : ['push', '--set-upstream', 'origin', branch];
84 const pushR = await git(pushArgs, { cwd: ctx.cwd, signal: ctx.signal, timeoutMs: 120_000 });
85 if (pushR.exitCode !== 0) {
86 return {
87 content: `[PUSH_FAILED] Could not push branch '${branch}'.\n${pushR.stderr.trim()}`,
88 isError: true,
89 };
90 }
91 }
92
93 // Build gh pr create command
94 const prArgs = ['pr', 'create', '--title', args.title, '--body', args.body ?? ''];
95 if (args.base) prArgs.push('--base', args.base);
96 if (args.draft) prArgs.push('--draft');
97 if (args.reviewers) for (const r of args.reviewers) prArgs.push('--reviewer', r);
98 if (args.labels) for (const l of args.labels) prArgs.push('--label', l);
99

Callers

nothing calls this directly

Calls 4

isGitRepoFunction · 0.85
runOnceFunction · 0.70
gitFunction · 0.70
pushMethod · 0.45

Tested by

no test coverage detected