Files
9df0cae78a MUL-7429: complete issues when every linked PR merges (#8758)
* feat(pr): complete issues when every linked PR merges (MUL-7429)

Title/branch identifiers link a PR; keywords and the body no longer matter.
Completion is evaluated only on a PR event for the issue (merge, link,
unlink), so settings changes and reopening never complete an issue.
Adds manual link/unlink with remembered exclusions and a per-issue
auto-complete switch.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>

* feat(pr): issue-page PR automation and single auto-complete setting (MUL-7429)

The issue's Pull requests section says what the merge rule will do next,
links a PR by URL, removes one per row, and turns auto-complete off for
that issue. The workspace switch lives under Issue statuses; the GitHub
page reports it. Agent skill and docs describe the title/branch rule.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>

* fix(pr): accept PR links pasted without a scheme (MUL-7429)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>

* test(skills): pin the PR auto-complete contract in the platform skill (MUL-7429)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>

* fix(pr): re-check linked PRs at the completion write; skip stale GitHub events (MUL-7429)

The status write now requires every linked PR to still be merged when it
runs, so a PR linked between the decision and the write keeps the issue
open. GitHub PR upserts ignore events older than the stored row, like the
self-hosted path, so a late delivery cannot roll a merged PR back to open
and turn a redelivered merge into a new one.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
2026-09-24 02:58:19 +08:00

41 lines
1.4 KiB
TypeScript

import { useMutation, useQueryClient } from "@tanstack/react-query";
import { api } from "../api";
import type { IssuePullRequestsResponse } from "../types";
import { githubKeys } from "./queries";
// Each endpoint answers with the issue's fresh PR list and auto-complete
// decision, so the cache is replaced with the server's answer rather than
// patched optimistically. A status change the action caused (auto-complete)
// arrives through the issue:updated realtime event.
function useWritePullRequests(issueId: string) {
const qc = useQueryClient();
return (data: IssuePullRequestsResponse) => {
qc.setQueryData(githubKeys.pullRequests(issueId), data);
};
}
export function useLinkIssuePullRequest(issueId: string) {
const write = useWritePullRequests(issueId);
return useMutation({
mutationFn: (body: { url: string } | { pull_request_id: string }) =>
api.linkIssuePullRequest(issueId, body),
onSuccess: write,
});
}
export function useUnlinkIssuePullRequest(issueId: string) {
const write = useWritePullRequests(issueId);
return useMutation({
mutationFn: (pullRequestId: string) => api.unlinkIssuePullRequest(issueId, pullRequestId),
onSuccess: write,
});
}
export function useSetIssuePRAutoComplete(issueId: string) {
const write = useWritePullRequests(issueId);
return useMutation({
mutationFn: (disabled: boolean) => api.setIssuePRAutoComplete(issueId, disabled),
onSuccess: write,
});
}