Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions plugins/github-orchestration/shared/hooks/utils/stacked-branches.ts
Original file line number Diff line number Diff line change
Expand Up @@ -543,12 +543,13 @@ export async function createPRWithAutoMerge(
body: string;
}
): Promise<{ success: boolean; prNumber?: number; prUrl?: string; error?: string }> {
// Create PR
const escapedTitle = options.title.replace(/"/g, '\\"');
const escapedBody = options.body.replace(/"/g, '\\"').replace(/\n/g, '\\n');

// Create PR using heredoc for proper body handling
// gh pr create outputs the PR URL on success
const createResult = await execCommand(
`gh pr create --head "${options.head}" --base "${options.base}" --title "${escapedTitle}" --body "${escapedBody}" --json number,url`,
`gh pr create --head "${options.head}" --base "${options.base}" --title "${options.title.replace(/"/g, '\\"')}" --body "$(cat <<'PRBODYEOF'
${options.body}
PRBODYEOF
)"`,
cwd,
60000
);
Expand All @@ -560,20 +561,20 @@ export async function createPRWithAutoMerge(
};
}

let prNumber: number;
let prUrl: string;
// Parse PR URL from stdout (gh pr create prints the URL)
const prUrl = createResult.stdout.trim();

try {
const prData = JSON.parse(createResult.stdout);
prNumber = prData.number;
prUrl = prData.url;
} catch {
// Extract PR number from URL (e.g., https://github.com/owner/repo/pull/123)
const prNumberMatch = prUrl.match(/\/pull\/(\d+)$/);
if (!prNumberMatch) {
return {
success: false,
error: 'Failed to parse PR creation response',
error: `Failed to parse PR number from URL: ${prUrl}`,
};
}

const prNumber = parseInt(prNumberMatch[1], 10);

// Enable auto-merge
const mergeResult = await execCommand(
`gh pr merge ${prNumber} --auto --squash`,
Expand Down
9 changes: 9 additions & 0 deletions plugins/github-orchestration/test-stacked-pr-v2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Stacked PR Test v2

Created at: 2026-01-24T07:00:00Z
Purpose: Test that SubagentStop hook creates PR after fix

Expected outcome:
- Branch created on SubagentStart
- File committed on SubagentStop
- PR created and linked
8 changes: 7 additions & 1 deletion plugins/project-context/shared/hooks/utils/task-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,13 @@ export async function getTaskEdits(
}

// Find parent session transcript
const dir = path.dirname(agentTranscriptPath);
// Agent transcripts are at: .../project/{sessionId}/subagents/agent-{agentId}.jsonl
// Parent transcripts are at: .../project/{sessionId}.jsonl
let dir = path.dirname(agentTranscriptPath); // .../sessionId/subagents/
if (path.basename(dir) === 'subagents') {
dir = path.dirname(dir); // .../sessionId/
}
dir = path.dirname(dir); // .../project/
const parentPath = path.join(dir, `${sessionId}.jsonl`);

try {
Expand Down