@aviaratech/ai-delivery 0.3.23 → 0.3.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +166 -16
- package/README.md +75 -446
- package/dist/agent.d.ts +5 -11
- package/dist/agent.js +4 -8
- package/dist/agent.js.map +1 -1
- package/dist/agentReadiness.test.d.ts +1 -0
- package/dist/agentReadiness.test.js +139 -0
- package/dist/agentReadiness.test.js.map +1 -0
- package/dist/cli.js +27 -111
- package/dist/cli.js.map +1 -1
- package/dist/config/deliveryConfig.d.ts +44 -55
- package/dist/config/deliveryConfig.js +85 -88
- package/dist/config/deliveryConfig.js.map +1 -1
- package/dist/config/deliveryConfig.test.js +13 -5
- package/dist/config/deliveryConfig.test.js.map +1 -1
- package/dist/contributorChecks.test.d.ts +1 -0
- package/dist/contributorChecks.test.js +1010 -0
- package/dist/contributorChecks.test.js.map +1 -0
- package/dist/currentConsumer.test.d.ts +1 -0
- package/dist/currentConsumer.test.js +832 -0
- package/dist/currentConsumer.test.js.map +1 -0
- package/dist/delivery/common.js +7 -2
- package/dist/delivery/common.js.map +1 -1
- package/dist/delivery/delivery.test.js +2 -3
- package/dist/delivery/delivery.test.js.map +1 -1
- package/dist/delivery/index.d.ts +0 -6
- package/dist/delivery/index.js +0 -3
- package/dist/delivery/index.js.map +1 -1
- package/dist/delivery/legacy.d.ts +8 -0
- package/dist/delivery/legacy.js +5 -0
- package/dist/delivery/legacy.js.map +1 -0
- package/dist/delivery/policy.js +2 -13
- package/dist/delivery/policy.js.map +1 -1
- package/dist/dependencyCompatibility.test.d.ts +1 -0
- package/dist/dependencyCompatibility.test.js +175 -0
- package/dist/dependencyCompatibility.test.js.map +1 -0
- package/dist/directoryIndependent.test.d.ts +1 -0
- package/dist/directoryIndependent.test.js +352 -0
- package/dist/directoryIndependent.test.js.map +1 -0
- package/dist/dispatch.d.ts +29 -3
- package/dist/dispatch.js +166 -457
- package/dist/dispatch.js.map +1 -1
- package/dist/genericCompatibility.test.js +0 -35
- package/dist/genericCompatibility.test.js.map +1 -1
- package/dist/git.js +10 -3
- package/dist/git.js.map +1 -1
- package/dist/gitProcess.d.ts +6 -0
- package/dist/gitProcess.js +56 -0
- package/dist/gitProcess.js.map +1 -0
- package/dist/github/discovery.d.ts +1 -0
- package/dist/github/discovery.js +1 -1
- package/dist/github/discovery.js.map +1 -1
- package/dist/github/discovery.test.js +25 -20
- package/dist/github/discovery.test.js.map +1 -1
- package/dist/github/nativeIssueMetadata.d.ts +2 -2
- package/dist/github/nativeIssueMetadata.js.map +1 -1
- package/dist/github/projectDelivery.d.ts +1 -1
- package/dist/github/projectDelivery.js.map +1 -1
- package/dist/github/repo.d.ts +7 -1
- package/dist/github/repo.js +58 -2
- package/dist/github/repo.js.map +1 -1
- package/dist/issue.d.ts +18 -6
- package/dist/issue.js +136 -319
- package/dist/issue.js.map +1 -1
- package/dist/issueJournal.d.ts +1 -1
- package/dist/issueJournal.test.js +88 -6
- package/dist/issueJournal.test.js.map +1 -1
- package/dist/lifecycle.test.js +40 -7371
- package/dist/lifecycle.test.js.map +1 -1
- package/dist/logger.js +4 -4
- package/dist/logger.js.map +1 -1
- package/dist/mcp/tools.d.ts +32 -42
- package/dist/mcp/tools.js +51 -42
- package/dist/mcp/tools.js.map +1 -1
- package/dist/pluginInstaller.d.ts +1 -1
- package/dist/pluginInstaller.js +8 -2
- package/dist/pluginInstaller.js.map +1 -1
- package/dist/pluginInstaller.test.js +213 -2
- package/dist/pluginInstaller.test.js.map +1 -1
- package/dist/pluginPackaging.test.js +225 -2
- package/dist/pluginPackaging.test.js.map +1 -1
- package/dist/pr.d.ts +73 -114
- package/dist/pr.js +837 -1085
- package/dist/pr.js.map +1 -1
- package/dist/pr.test.js +453 -236
- package/dist/pr.test.js.map +1 -1
- package/dist/prAssociation.test.d.ts +1 -0
- package/dist/prAssociation.test.js +1336 -0
- package/dist/prAssociation.test.js.map +1 -0
- package/dist/prDispatch.test.d.ts +1 -0
- package/dist/prDispatch.test.js +96 -0
- package/dist/prDispatch.test.js.map +1 -0
- package/dist/releaseReconciliation.test.d.ts +1 -0
- package/dist/releaseReconciliation.test.js +318 -0
- package/dist/releaseReconciliation.test.js.map +1 -0
- package/dist/releaseWorkflow.test.d.ts +1 -0
- package/dist/releaseWorkflow.test.js +447 -0
- package/dist/releaseWorkflow.test.js.map +1 -0
- package/dist/review.d.ts +37 -7
- package/dist/review.js +106 -45
- package/dist/review.js.map +1 -1
- package/dist/review.test.js +30 -71
- package/dist/review.test.js.map +1 -1
- package/dist/services/agentReadinessService.d.ts +1 -1
- package/dist/services/agentReadinessService.js +4 -1
- package/dist/services/agentReadinessService.js.map +1 -1
- package/dist/services/deliveryAdmission.d.ts +4 -4
- package/dist/services/deliveryAdmission.js.map +1 -1
- package/dist/setup.test.js +10 -5
- package/dist/setup.test.js.map +1 -1
- package/dist/stagedChecks.test.d.ts +1 -0
- package/dist/stagedChecks.test.js +228 -0
- package/dist/stagedChecks.test.js.map +1 -0
- package/dist/start.test.d.ts +1 -0
- package/dist/start.test.js +72 -0
- package/dist/start.test.js.map +1 -0
- package/dist/stdoutRegression.test.d.ts +1 -0
- package/dist/stdoutRegression.test.js +326 -0
- package/dist/stdoutRegression.test.js.map +1 -0
- package/dist/verification.d.ts +1 -27
- package/dist/verification.js +5 -1332
- package/dist/verification.js.map +1 -1
- package/dist/worktree.d.ts +1 -31
- package/dist/worktree.js +5 -200
- package/dist/worktree.js.map +1 -1
- package/dist/worktreeTransition.d.ts +1 -1
- package/dist/worktreeTransition.js +10 -5
- package/dist/worktreeTransition.js.map +1 -1
- package/dist/worktreeTransition.test.js +2 -3
- package/dist/worktreeTransition.test.js.map +1 -1
- package/package.json +9 -6
- package/plugins/ai-delivery/.claude-plugin/plugin.json +2 -2
- package/plugins/ai-delivery/README.md +3 -3
- package/plugins/ai-delivery/plugin.json +1 -1
- package/plugins/ai-delivery/runtime/dist/THIRD-PARTY-NOTICES.md +1 -1
- package/plugins/ai-delivery/runtime/dist/cli.js +50 -59
- package/plugins/ai-delivery/runtime/package.json +1 -1
- package/plugins/ai-delivery/skills/intake-create/SKILL.md +1 -1
- package/plugins/ai-delivery/skills/pr-handoff/SKILL.md +14 -21
- package/plugins/ai-delivery/skills/worktree-lifecycle/SKILL.md +12 -23
- package/dist/services/deliveryRecordService.d.ts +0 -47
- package/dist/services/deliveryRecordService.js +0 -199
- package/dist/services/deliveryRecordService.js.map +0 -1
package/dist/dispatch.js
CHANGED
|
@@ -1,37 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { resolveRepoFromRemote } from './github/repo.js';
|
|
4
|
-
import { assertRepositoryClassificationCurrent } from './delivery/index.js';
|
|
1
|
+
import { loadDeliverySettings } from './config/deliveryConfig.js';
|
|
2
|
+
import { resolveCheckout, resolveRepoFromRemote } from './github/repo.js';
|
|
5
3
|
import { DeliveryError } from './errors.js';
|
|
6
|
-
import {
|
|
7
|
-
import { createDeliveryGitHubClients } from './github/client.js';
|
|
4
|
+
import { digestValue } from './delivery/common.js';
|
|
8
5
|
import { evaluateCommandIdentityPolicy } from './github/commandIdentityPolicy.js';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { finishIssue, mergePr, preflightReviewRoute, prInfo, publishPr, submitFormalReview } from './pr.js';
|
|
12
|
-
import { parseReviewArtifact, reviewArtifactApproval, savePrepublicationArtifact } from './review.js';
|
|
13
|
-
import { evaluateAgentReadiness } from './services/agentReadinessService.js';
|
|
14
|
-
import { assertDeliveryRuntimeAdmitted } from './services/deliveryAdmission.js';
|
|
15
|
-
import { assertIssueWorktreeTransitionAdmission, getIssueWorktreeStrict, listWorktreesStrict, } from './services/worktreeRegistry.js';
|
|
6
|
+
import { CreatedTrackingIssueError, createIssue, commentIssue, issueInfo, listIssues, journalIssueStart, loadDeliveryContext, readyCheck, resumeCreatedIssue, startIssueBranch, updateIssue, } from './issue.js';
|
|
7
|
+
import { finishIssue, mergePr, prInfo, publishPr, submitFormalReview } from './pr.js';
|
|
16
8
|
import { applyWorktreeTransition, inspectWorktreeTransition, } from './worktreeTransition.js';
|
|
17
|
-
import { createIssuePhaseEvidence, loadVerifiedRun, verifyIssue, } from './verification.js';
|
|
18
9
|
import { stageRuntime, admitRuntime } from './setup.js';
|
|
19
|
-
import { prepareStandaloneWorktree } from './worktree.js';
|
|
20
10
|
import { getAiDeliveryMcpTool } from './mcp/tools.js';
|
|
21
|
-
const MUTATING_TOOLS = new Set([
|
|
22
|
-
'issue_comment',
|
|
23
|
-
'issue_create',
|
|
24
|
-
'issue_start',
|
|
25
|
-
'issue_update',
|
|
26
|
-
'issue_develop',
|
|
27
|
-
'issue_verify',
|
|
28
|
-
'issue_pr_create',
|
|
29
|
-
'issue_pr_review',
|
|
30
|
-
'issue_pr_merge',
|
|
31
|
-
'issue_finish',
|
|
32
|
-
'issue_worktree_create',
|
|
33
|
-
'issue_worktree_transition_apply',
|
|
34
|
-
]);
|
|
35
11
|
function requiredNumber(input, key) {
|
|
36
12
|
const value = input[key];
|
|
37
13
|
if (typeof value !== 'number' || !Number.isSafeInteger(value) || value <= 0)
|
|
@@ -47,502 +23,235 @@ function requireString(input, key) {
|
|
|
47
23
|
throw new DeliveryError(`${key} is required.`);
|
|
48
24
|
return value;
|
|
49
25
|
}
|
|
50
|
-
/**
|
|
26
|
+
/** Preserve every accepted tracking field when completing a partially created issue. */
|
|
51
27
|
export function resumedIssueUpdate(input) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
...(input.body === undefined ? {} : { body: requireString(input, 'body') }),
|
|
55
|
-
...(input.issueType === undefined ? {} : { issueType: requireString(input, 'issueType') }),
|
|
56
|
-
...(input.points === undefined ? {} : { points: Number(input.points) }),
|
|
57
|
-
...(input.priority === undefined ? {} : { priority: requireString(input, 'priority') }),
|
|
58
|
-
...(input.title === undefined ? {} : { title: requireString(input, 'title') }),
|
|
59
|
-
...(input.labels === undefined ? {} : { labels: input.labels }),
|
|
60
|
-
...(input.milestone === undefined ? {} : { milestone: Number(input.milestone) }),
|
|
61
|
-
...(input.parentIssueNumber === undefined ? {} : { parentIssueNumber: Number(input.parentIssueNumber) }),
|
|
62
|
-
...(input.blockedBy === undefined ? {} : { blockedBy: input.blockedBy }),
|
|
63
|
-
};
|
|
28
|
+
const { issueNumber, request: _request, requestId: _requestId, repo: _repo, resumeCreated: _resume, branch: _branch, ...fields } = input;
|
|
29
|
+
return { ...fields, issueNumber: requiredNumber({ issueNumber }, 'issueNumber') };
|
|
64
30
|
}
|
|
65
|
-
async function
|
|
66
|
-
const
|
|
67
|
-
const identity = input.identity ??
|
|
31
|
+
export async function contextFor(input, commandName, role = 'author') {
|
|
32
|
+
const settings = await loadDeliverySettings();
|
|
33
|
+
const identity = input.identity ?? settings.roles[role].identity;
|
|
68
34
|
const policy = evaluateCommandIdentityPolicy({
|
|
69
35
|
commandName,
|
|
70
|
-
deliveryConfig:
|
|
36
|
+
deliveryConfig: settings,
|
|
71
37
|
identity,
|
|
72
38
|
...(input.personalAuth === undefined ? {} : { personalAuth: input.personalAuth }),
|
|
73
39
|
});
|
|
74
40
|
if (policy.error)
|
|
75
41
|
throw new DeliveryError(policy.error);
|
|
76
|
-
return identity || config.roles.author.identity;
|
|
77
|
-
}
|
|
78
|
-
function assertRepositorySelector(input, execution) {
|
|
79
|
-
const selector = input.repo ?? execution.repo;
|
|
80
|
-
if (selector === undefined)
|
|
81
|
-
return;
|
|
82
|
-
const root = gitRoot(execution.repoRoot);
|
|
83
|
-
const selected = resolveRepoFromRemote(root, readDeliveryOverrides(root).overrides.remote);
|
|
84
|
-
const configured = `${selected.owner}/${selected.repo}`;
|
|
85
|
-
if (typeof selector !== 'string' || selector.toLowerCase() !== configured.toLowerCase()) {
|
|
86
|
-
throw new DeliveryError('Repository selector must match the configured repository for this Git checkout.');
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
export async function contextFor(input, commandName, role = 'author') {
|
|
90
|
-
assertRepositorySelector({}, input);
|
|
91
|
-
const identity = await identityFor(input, commandName);
|
|
92
42
|
return loadDeliveryContext({
|
|
93
43
|
identity,
|
|
94
|
-
...(input.personalAuth === undefined ? {} : { personalAuth: input.personalAuth }),
|
|
95
44
|
repoRoot: input.repoRoot,
|
|
96
45
|
role,
|
|
46
|
+
...(input.repo === undefined ? {} : { repository: input.repo }),
|
|
47
|
+
...(input.personalAuth === undefined ? {} : { personalAuth: input.personalAuth }),
|
|
48
|
+
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
97
49
|
});
|
|
98
50
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
name !== 'issue_finish' &&
|
|
105
|
-
!(name === 'issue_pr_info' && input.issueNumber !== undefined))
|
|
106
|
-
return undefined;
|
|
107
|
-
const primary = primaryGitRoot(execution.repoRoot);
|
|
108
|
-
const requested = gitRoot(execution.repoRoot);
|
|
109
|
-
const issueNumber = requiredNumber(input, 'issueNumber');
|
|
110
|
-
if (name === 'issue_finish' &&
|
|
111
|
-
!listWorktreesStrict(primary).some((row) => row.type === 'issue' && row.issueNumber === issueNumber))
|
|
112
|
-
return primary;
|
|
113
|
-
const row = getIssueWorktreeStrict(issueNumber, primary);
|
|
114
|
-
if (requested !== primary && requested !== row.path) {
|
|
115
|
-
throw new DeliveryError('Source-bound operations require the primary or exact registered issue checkout.');
|
|
116
|
-
}
|
|
117
|
-
// Terminal owners validate retained immutable receipts and the remote result.
|
|
118
|
-
// A removed merged checkout must not be imported or reconstructed here.
|
|
119
|
-
if ((name === 'issue_finish' || name === 'issue_pr_merge') && row.status === 'merged' && !existsSync(row.path)) {
|
|
120
|
-
return primary;
|
|
121
|
-
}
|
|
122
|
-
if (gitCommonDir(row.path) !== gitCommonDir(primary)) {
|
|
123
|
-
throw new DeliveryError('Registered issue source must belong to the primary Git repository.');
|
|
124
|
-
}
|
|
125
|
-
assertClean(row.path);
|
|
126
|
-
return row.path;
|
|
127
|
-
}
|
|
128
|
-
/** @internal Keep CLI and MCP start routing on the same native lifecycle owner. */
|
|
129
|
-
export async function startTrackedIssue(context, input, runtimeEntryPath) {
|
|
130
|
-
const knownIssue = input.issueNumber === undefined ? undefined : requiredNumber(input, 'issueNumber');
|
|
131
|
-
if (input.resumeCreated === true && (knownIssue === undefined || typeof input.develop !== 'boolean')) {
|
|
132
|
-
throw new DeliveryError('Resume of a known created issue requires issueNumber and an explicit develop boolean.');
|
|
133
|
-
}
|
|
134
|
-
if (knownIssue !== undefined && input.resumeCreated !== true) {
|
|
135
|
-
const row = await developIssue(context, knownIssue, runtimeEntryPath);
|
|
136
|
-
const title = (await issueInfo(context, knownIssue)).title;
|
|
137
|
-
return {
|
|
138
|
-
issueNumber: knownIssue,
|
|
139
|
-
mode: 'existing-issue',
|
|
140
|
-
title,
|
|
141
|
-
branch: row.branch,
|
|
142
|
-
path: row.path,
|
|
143
|
-
worktreePath: row.path,
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
const request = optionalString(input, 'request');
|
|
147
|
-
const title = optionalString(input, 'title') ?? requireString(input, 'request');
|
|
148
|
-
const points = input.points === undefined ? 2 : requiredNumber(input, 'points');
|
|
149
|
-
const tracking = {
|
|
150
|
-
body: optionalString(input, 'body') ?? request ?? title,
|
|
151
|
-
title,
|
|
152
|
-
points,
|
|
153
|
-
...(input.issueType === undefined ? {} : { issueType: requireString(input, 'issueType') }),
|
|
154
|
-
...(input.priority === undefined ? {} : { priority: requireString(input, 'priority') }),
|
|
155
|
-
...(input.blockedBy === undefined ? {} : { blockedBy: input.blockedBy }),
|
|
156
|
-
...(input.labels === undefined ? {} : { labels: input.labels }),
|
|
157
|
-
...(input.milestone === undefined ? {} : { milestone: Number(input.milestone) }),
|
|
158
|
-
...(input.parentIssueNumber === undefined ? {} : { parentIssueNumber: Number(input.parentIssueNumber) }),
|
|
159
|
-
};
|
|
160
|
-
if (input.develop === true)
|
|
161
|
-
await preflightStartDevelopment(context, tracking);
|
|
162
|
-
const repository = `${context.repo.owner}/${context.repo.repo}`;
|
|
163
|
-
const createdNotStarted = (createdIssue, phase, error) => ({
|
|
164
|
-
schemaVersion: 'ai-delivery.issue-start-registration@1',
|
|
51
|
+
/** GitHub owns branch linkage; hosts own worktree preparation. */
|
|
52
|
+
export async function startTrackedIssue(context, input) {
|
|
53
|
+
let number = input.issueNumber === undefined ? undefined : requiredNumber(input, 'issueNumber');
|
|
54
|
+
let created;
|
|
55
|
+
const registration = (phase, error) => ({
|
|
165
56
|
status: 'created-not-started',
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
identity: context.config.roles.author.identity,
|
|
169
|
-
createdIssue,
|
|
57
|
+
repository: context.config.repository,
|
|
58
|
+
createdIssue: created,
|
|
170
59
|
failure: { phase, message: error instanceof Error ? error.message : String(error) },
|
|
171
60
|
safeResume: {
|
|
172
61
|
tool: 'issue_start',
|
|
173
|
-
arguments: {
|
|
174
|
-
...tracking,
|
|
175
|
-
...(input.repo === undefined ? {} : { repo: input.repo }),
|
|
176
|
-
issueNumber: createdIssue.number,
|
|
177
|
-
develop: input.develop === true,
|
|
178
|
-
resumeCreated: true,
|
|
179
|
-
},
|
|
62
|
+
arguments: { ...input, repo: context.config.repository, issueNumber: number, resumeCreated: true },
|
|
180
63
|
},
|
|
181
64
|
});
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
65
|
+
if (number === undefined) {
|
|
66
|
+
const title = optionalString(input, 'title') ?? requireString(input, 'request');
|
|
67
|
+
const tracking = {
|
|
68
|
+
...input,
|
|
69
|
+
title,
|
|
70
|
+
body: optionalString(input, 'body') ?? optionalString(input, 'request') ?? title,
|
|
71
|
+
};
|
|
72
|
+
const intent = digestValue(Object.fromEntries(Object.entries({
|
|
73
|
+
title,
|
|
74
|
+
body: tracking.body,
|
|
75
|
+
issueType: tracking.issueType,
|
|
76
|
+
points: tracking.points,
|
|
77
|
+
priority: tracking.priority,
|
|
78
|
+
labels: tracking.labels,
|
|
79
|
+
blockedBy: tracking.blockedBy,
|
|
80
|
+
parentIssueNumber: tracking.parentIssueNumber,
|
|
81
|
+
milestone: tracking.milestone,
|
|
82
|
+
branch: input.branch,
|
|
83
|
+
}).filter(([, value]) => value !== undefined)));
|
|
84
|
+
const requestKey = optionalString(input, 'requestId') ?? intent;
|
|
85
|
+
const marker = `<!-- ai-delivery-start: ${digestValue({ repository: context.config.repository.toLowerCase(), requestKey })} -->`;
|
|
86
|
+
tracking.body = `${tracking.body}\n\n<!-- ai-delivery-start-intent: ${intent} -->\n${marker}`;
|
|
87
|
+
let completed = false;
|
|
88
|
+
const matches = [];
|
|
89
|
+
for (let page = 1; page <= 20; page++) {
|
|
90
|
+
const batch = (await context.clients.rest.issues.listForRepo({ ...context.repo, state: 'all', page, per_page: 100 })).data;
|
|
91
|
+
matches.push(...batch.filter((value) => !('pull_request' in value) && value.body?.includes(marker)));
|
|
92
|
+
if (batch.length < 100) {
|
|
93
|
+
completed = true;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
194
96
|
}
|
|
195
|
-
|
|
196
|
-
|
|
97
|
+
if (!completed)
|
|
98
|
+
throw new DeliveryError('Issue-start retry search exceeds the bounded readback window; select a known issue number.');
|
|
99
|
+
if (matches.length > 1)
|
|
100
|
+
throw new DeliveryError('Conflicting issues claim the same start request.');
|
|
101
|
+
const prior = matches[0];
|
|
102
|
+
if (prior && (prior.title !== title || prior.body !== tracking.body || prior.state !== 'open'))
|
|
103
|
+
throw new DeliveryError('Prior issue-start request conflicts with the requested intent or state.');
|
|
197
104
|
try {
|
|
198
|
-
|
|
105
|
+
if (prior) {
|
|
106
|
+
created = { number: prior.number, title: prior.title, url: prior.html_url };
|
|
107
|
+
number = prior.number;
|
|
108
|
+
await resumeCreatedIssue(context, { ...tracking, issueNumber: number });
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
created = (await createIssue(context, tracking)).created;
|
|
112
|
+
number = created.number;
|
|
113
|
+
}
|
|
199
114
|
}
|
|
200
115
|
catch (error) {
|
|
201
|
-
if (
|
|
202
|
-
|
|
116
|
+
if (error instanceof CreatedTrackingIssueError) {
|
|
117
|
+
created = error.created;
|
|
118
|
+
number = created.number;
|
|
203
119
|
}
|
|
204
|
-
|
|
120
|
+
else if (!created)
|
|
121
|
+
throw error;
|
|
122
|
+
return registration('tracking', error);
|
|
205
123
|
}
|
|
206
124
|
}
|
|
207
|
-
if (input.
|
|
125
|
+
else if (input.resumeCreated === true) {
|
|
126
|
+
const issue = (await context.clients.rest.issues.get({ ...context.repo, issue_number: number })).data;
|
|
127
|
+
if (issue.number !== number || 'pull_request' in issue)
|
|
128
|
+
throw new DeliveryError('Known-created issue readback disagrees.');
|
|
129
|
+
created = { number, title: issue.title, url: issue.html_url };
|
|
208
130
|
try {
|
|
209
|
-
|
|
210
|
-
return {
|
|
211
|
-
schemaVersion: 'ai-delivery.issue-start-registration@1',
|
|
212
|
-
status: 'started',
|
|
213
|
-
provider: 'github',
|
|
214
|
-
repository,
|
|
215
|
-
identity: context.config.roles.author.identity,
|
|
216
|
-
issue: created,
|
|
217
|
-
branch: row.branch,
|
|
218
|
-
worktreePath: row.path,
|
|
219
|
-
};
|
|
131
|
+
await resumeCreatedIssue(context, resumedIssueUpdate(input));
|
|
220
132
|
}
|
|
221
133
|
catch (error) {
|
|
222
|
-
return
|
|
134
|
+
return registration('tracking', error);
|
|
223
135
|
}
|
|
224
136
|
}
|
|
225
137
|
try {
|
|
226
|
-
await
|
|
138
|
+
const branch = await startIssueBranch(context, number, optionalString(input, 'branch'));
|
|
139
|
+
await journalIssueStart(context, number);
|
|
140
|
+
return {
|
|
141
|
+
issueNumber: number,
|
|
142
|
+
repository: context.config.repository,
|
|
143
|
+
branch: branch.branch,
|
|
144
|
+
headSha: branch.headSha,
|
|
145
|
+
reused: branch.reused,
|
|
146
|
+
};
|
|
227
147
|
}
|
|
228
148
|
catch (error) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
233
|
-
async function preflightStartDevelopment(context, tracking) {
|
|
234
|
-
const targets = await resolveNativeRelationshipTargets({
|
|
235
|
-
blockers: tracking.blockedBy ?? [],
|
|
236
|
-
...(tracking.parentIssueNumber === undefined ? {} : { parentIssueNumber: tracking.parentIssueNumber }),
|
|
237
|
-
repo: context.repo,
|
|
238
|
-
rest: context.clients.rest,
|
|
239
|
-
});
|
|
240
|
-
const readiness = evaluateAgentReadiness({
|
|
241
|
-
blockedBy: targets.unresolvedBlockers,
|
|
242
|
-
body: tracking.body ?? '',
|
|
243
|
-
...(tracking.points === undefined ? {} : { points: tracking.points }),
|
|
244
|
-
repoRoot: context.root,
|
|
245
|
-
title: tracking.title,
|
|
246
|
-
});
|
|
247
|
-
if (!readiness.ready) {
|
|
248
|
-
throw new DeliveryError(`New issue is not ready: ${readiness.failures.map((failure) => failure.message).join('; ')}`);
|
|
249
|
-
}
|
|
250
|
-
listWorktreesStrict(context.root);
|
|
251
|
-
if (gitExitCode(context.root, 'rev-parse', '--verify', defaultBaseRef(context.root, context.configuration?.remote)) !==
|
|
252
|
-
0) {
|
|
253
|
-
throw new DeliveryError('Default base ref is missing before tracked issue creation.');
|
|
149
|
+
if (created)
|
|
150
|
+
return registration('branch-or-journal', error);
|
|
151
|
+
throw error;
|
|
254
152
|
}
|
|
255
|
-
await preflightReviewRoute(context, undefined, undefined, 'development');
|
|
256
|
-
}
|
|
257
|
-
function scratchStart(input, execution, identity, remote) {
|
|
258
|
-
const title = (optionalString(input, 'title') ?? requireString(input, 'request'))
|
|
259
|
-
.replace(/\s+/gu, ' ')
|
|
260
|
-
.trim()
|
|
261
|
-
.slice(0, 90)
|
|
262
|
-
.trim();
|
|
263
|
-
const branchOverride = optionalString(input, 'branch');
|
|
264
|
-
const source = (branchOverride ?? optionalString(input, 'request') ?? title).replace(/\//gu, '-');
|
|
265
|
-
const slug = source
|
|
266
|
-
.trim()
|
|
267
|
-
.toLowerCase()
|
|
268
|
-
.replace(/[^a-z0-9]+/gu, '-')
|
|
269
|
-
.replace(/^-+|-+$/gu, '')
|
|
270
|
-
.slice(0, 56)
|
|
271
|
-
.replace(/-+$/gu, '') || 'scratch';
|
|
272
|
-
const branch = branchOverride ?? `scratch/${slug}`;
|
|
273
|
-
const name = `scratch-${slug}`;
|
|
274
|
-
return prepareStandaloneWorktree({
|
|
275
|
-
branch,
|
|
276
|
-
identity,
|
|
277
|
-
name,
|
|
278
|
-
repoRoot: execution.repoRoot,
|
|
279
|
-
...(remote ? { remote } : {}),
|
|
280
|
-
}).then((row) => ({
|
|
281
|
-
mode: 'scratch',
|
|
282
|
-
title,
|
|
283
|
-
branch: row.branch,
|
|
284
|
-
worktreePath: row.path,
|
|
285
|
-
}));
|
|
286
153
|
}
|
|
287
154
|
export async function executeTool(name, raw, execution) {
|
|
288
155
|
const definition = getAiDeliveryMcpTool(name);
|
|
289
156
|
if (!definition)
|
|
290
157
|
throw new DeliveryError(`Unknown ai-delivery tool ${name}.`);
|
|
291
|
-
const input = definition.inputSchema.parse(raw);
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
issue_verify: 'verify',
|
|
320
|
-
issue_pr_create: 'pr:create',
|
|
321
|
-
issue_pr_info: 'pr:info',
|
|
322
|
-
issue_pr_review: 'pr:review',
|
|
323
|
-
issue_pr_merge: 'pr:merge',
|
|
324
|
-
issue_finish: 'finish',
|
|
325
|
-
issue_worktree_create: 'worktree:create',
|
|
326
|
-
issue_worktree_transition_inspect: 'worktree:transition:inspect',
|
|
327
|
-
issue_worktree_transition_apply: 'worktree:transition:apply',
|
|
328
|
-
};
|
|
329
|
-
const requestedIdentity = name === 'issue_pr_review' ? optionalString(input, 'identity') : undefined;
|
|
330
|
-
const selectedExecution = requestedIdentity === undefined ? execution : { ...execution, identity: requestedIdentity };
|
|
331
|
-
const sourceRoot = sourceRootFor(name, input, execution);
|
|
332
|
-
const context = await contextFor(sourceRoot === undefined ? selectedExecution : { ...selectedExecution, repoRoot: sourceRoot }, commands[name], name === 'issue_pr_review' ? 'reviewer' : 'author');
|
|
333
|
-
let controllerConfiguration = context.configuration;
|
|
334
|
-
if (sourceRoot !== undefined) {
|
|
335
|
-
const primary = primaryGitRoot(execution.repoRoot);
|
|
336
|
-
const settings = await loadDeliverySettings(primary);
|
|
337
|
-
if (settings.repository.toLowerCase() !== context.config.repository.toLowerCase()) {
|
|
338
|
-
throw new DeliveryError('Registered issue source and primary controller must select the same repository.');
|
|
158
|
+
const { repo: selected, ...input } = definition.inputSchema.parse(raw);
|
|
159
|
+
if (name === 'issue_finish' && input.nonClosing === true)
|
|
160
|
+
throw new DeliveryError('Non-closing delivery cannot finish or close its retained issue.');
|
|
161
|
+
if (selected !== undefined && execution.repo !== undefined && selected !== execution.repo)
|
|
162
|
+
throw new DeliveryError('Tool and execution repository selectors disagree.');
|
|
163
|
+
const repo = typeof selected === 'string' ? selected : execution.repo;
|
|
164
|
+
const selectedExecution = { ...execution, ...(repo === undefined ? {} : { repo }) };
|
|
165
|
+
const local = name === 'runtime_stage' || name === 'runtime_admit' || name.startsWith('issue_worktree_transition_');
|
|
166
|
+
let root = execution.repoRoot;
|
|
167
|
+
if (local) {
|
|
168
|
+
const settings = await loadDeliverySettings();
|
|
169
|
+
const coordinates = repo ??
|
|
170
|
+
(() => {
|
|
171
|
+
const r = resolveRepoFromRemote(root, 'origin');
|
|
172
|
+
return `${r.owner}/${r.repo}`;
|
|
173
|
+
})();
|
|
174
|
+
root = resolveCheckout({ repository: coordinates, launchDirectory: root, checkoutRoots: settings.checkoutRoots });
|
|
175
|
+
if (name === 'runtime_stage' || name === 'runtime_admit') {
|
|
176
|
+
const setup = {
|
|
177
|
+
...input,
|
|
178
|
+
repoRoot: root,
|
|
179
|
+
identity: optionalString(input, 'identity') ?? execution.identity ?? settings.roles.author.identity,
|
|
180
|
+
...(execution.personalAuth === undefined ? {} : { personalAuth: execution.personalAuth }),
|
|
181
|
+
...(execution.signal === undefined ? {} : { signal: execution.signal }),
|
|
182
|
+
};
|
|
183
|
+
return name === 'runtime_stage'
|
|
184
|
+
? stageRuntime(setup)
|
|
185
|
+
: admitRuntime(setup);
|
|
339
186
|
}
|
|
340
|
-
const authorClients = name === 'issue_pr_review'
|
|
341
|
-
? await createDeliveryGitHubClients({
|
|
342
|
-
config: context.config,
|
|
343
|
-
identity: context.config.roles.author.identity,
|
|
344
|
-
...(execution.personalAuth ? { personalAuth: { enabled: true } } : {}),
|
|
345
|
-
role: 'author',
|
|
346
|
-
})
|
|
347
|
-
: context.clients;
|
|
348
|
-
// Discover the controller's metadata through the configured source author,
|
|
349
|
-
// while retaining the controller's policy, settings and admission digest.
|
|
350
|
-
controllerConfiguration = await loadDeliveryConfig(primary, { clients: authorClients });
|
|
351
|
-
}
|
|
352
|
-
if (MUTATING_TOOLS.has(name) && input.dryRun !== true) {
|
|
353
|
-
if (name !== 'issue_worktree_transition_apply' && typeof input.issueNumber === 'number')
|
|
354
|
-
assertIssueWorktreeTransitionAdmission(input.issueNumber, primaryGitRoot(execution.repoRoot), name === 'issue_develop' || (name === 'issue_start' && input.resumeCreated !== true));
|
|
355
|
-
await assertDeliveryRuntimeAdmitted({
|
|
356
|
-
...execution,
|
|
357
|
-
repoRoot: sourceRoot === undefined ? execution.repoRoot : primaryGitRoot(execution.repoRoot),
|
|
358
|
-
...(controllerConfiguration === undefined ? {} : { configuration: controllerConfiguration }),
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
if (sourceRoot !== undefined && (name === 'issue_pr_create' || name === 'issue_pr_review')) {
|
|
362
|
-
if (context.configuration === undefined)
|
|
363
|
-
throw new DeliveryError('Source-bound operation requires discovered candidate configuration.');
|
|
364
|
-
const run = loadVerifiedRun(sourceRoot, requiredNumber(input, 'issueNumber'));
|
|
365
|
-
assertRepositoryClassificationCurrent({
|
|
366
|
-
classification: run.classification,
|
|
367
|
-
configDigest: context.configuration.configDigest,
|
|
368
|
-
policySourcePath: context.config.policy.module,
|
|
369
|
-
repoRoot: sourceRoot,
|
|
370
|
-
});
|
|
371
187
|
}
|
|
188
|
+
const requestedIdentity = name === 'issue_pr_review' ? optionalString(input, 'identity') : undefined;
|
|
189
|
+
const context = await contextFor({ ...selectedExecution, ...(requestedIdentity === undefined ? {} : { identity: requestedIdentity }) }, definition.commandName, name === 'issue_pr_review' ? 'reviewer' : 'author');
|
|
190
|
+
if (local)
|
|
191
|
+
context.root = root;
|
|
372
192
|
switch (name) {
|
|
373
193
|
case 'issue_comment':
|
|
374
194
|
return commentIssue(context, input);
|
|
375
|
-
case '
|
|
376
|
-
return inspectWorktreeTransition(context, {
|
|
377
|
-
...input,
|
|
378
|
-
...(execution.runtimeEntryPath === undefined ? {} : { runtimeEntryPath: execution.runtimeEntryPath }),
|
|
379
|
-
});
|
|
380
|
-
case 'issue_worktree_transition_apply':
|
|
381
|
-
return applyWorktreeTransition(context, {
|
|
382
|
-
authority: 'worktree:transition',
|
|
383
|
-
planPath: requireString(input, 'planPath'),
|
|
384
|
-
expectedPlanId: requireString(input, 'expectedPlanId'),
|
|
385
|
-
relinquishmentCommentId: requiredNumber(input, 'relinquishmentCommentId'),
|
|
386
|
-
acceptanceCommentId: requiredNumber(input, 'acceptanceCommentId'),
|
|
387
|
-
...(execution.runtimeEntryPath === undefined ? {} : { runtimeEntryPath: execution.runtimeEntryPath }),
|
|
388
|
-
});
|
|
389
|
-
case 'issue_create': {
|
|
195
|
+
case 'issue_create':
|
|
390
196
|
return createIssue(context, input);
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
if (input.resumeCreated === true && (input.issueNumber === undefined || typeof input.develop !== 'boolean')) {
|
|
395
|
-
throw new DeliveryError('Resume of a known created issue requires issueNumber and an explicit develop boolean.');
|
|
396
|
-
}
|
|
397
|
-
if (input.scratch === true) {
|
|
398
|
-
if (input.issueNumber !== undefined || input.develop === true || input.resumeCreated === true) {
|
|
399
|
-
throw new DeliveryError('Scratch worktree cannot claim a tracked issue.');
|
|
400
|
-
}
|
|
401
|
-
await preflightReviewRoute(context, undefined, undefined, 'development');
|
|
402
|
-
return scratchStart(input, execution, identity, context.configuration?.remote);
|
|
403
|
-
}
|
|
404
|
-
return startTrackedIssue(context, input, execution.runtimeEntryPath);
|
|
405
|
-
}
|
|
406
|
-
case 'issue_update': {
|
|
197
|
+
case 'issue_start':
|
|
198
|
+
return startTrackedIssue(context, input);
|
|
199
|
+
case 'issue_update':
|
|
407
200
|
return updateIssue(context, input);
|
|
408
|
-
}
|
|
409
201
|
case 'issue_list':
|
|
410
202
|
case 'issue_search':
|
|
411
203
|
return listIssues(context, input);
|
|
412
|
-
case 'issue_info':
|
|
413
|
-
if (input.cached === true)
|
|
414
|
-
return cachedIssueInfo(execution.repoRoot, requiredNumber(input, 'issueNumber'));
|
|
204
|
+
case 'issue_info':
|
|
415
205
|
return issueInfo(context, requiredNumber(input, 'issueNumber'));
|
|
416
|
-
|
|
417
|
-
case 'issue_ready_check': {
|
|
206
|
+
case 'issue_ready_check':
|
|
418
207
|
return readyCheck(context, requiredNumber(input, 'issueNumber'));
|
|
419
|
-
|
|
420
|
-
case 'issue_develop': {
|
|
421
|
-
const issueNumber = requiredNumber(input, 'issueNumber');
|
|
422
|
-
const result = await developIssue(context, issueNumber, execution.runtimeEntryPath);
|
|
423
|
-
if (input.assignee !== undefined)
|
|
424
|
-
await context.clients.rest.issues.addAssignees({
|
|
425
|
-
...context.repo,
|
|
426
|
-
issue_number: issueNumber,
|
|
427
|
-
assignees: [requireString(input, 'assignee')],
|
|
428
|
-
});
|
|
429
|
-
return result;
|
|
430
|
-
}
|
|
431
|
-
case 'issue_verify': {
|
|
432
|
-
const issueNumber = requiredNumber(input, 'issueNumber');
|
|
433
|
-
const root = primaryGitRoot(execution.repoRoot);
|
|
434
|
-
const row = getIssueWorktreeStrict(issueNumber, root);
|
|
435
|
-
const run = await verifyIssue({
|
|
436
|
-
personalAuth: context.clients.authSource === 'personal' && context.config.roles.author.authSource !== 'personal',
|
|
437
|
-
issueNumber,
|
|
438
|
-
repoRoot: row.path,
|
|
439
|
-
...(execution.signal === undefined ? {} : { signal: execution.signal }),
|
|
440
|
-
...(input.resourceBounds === undefined
|
|
441
|
-
? {}
|
|
442
|
-
: { resourceBounds: input.resourceBounds }),
|
|
443
|
-
...(input.admit === undefined
|
|
444
|
-
? {}
|
|
445
|
-
: { admittedResourceClasses: ['source_only', ...input.admit] }),
|
|
446
|
-
});
|
|
447
|
-
let approval;
|
|
448
|
-
if (input.prepublicationReview !== undefined) {
|
|
449
|
-
const artifact = parseReviewArtifact(readFileSync(requireString(input, 'prepublicationReview'), 'utf8'));
|
|
450
|
-
const config = (await loadDeliveryConfig(row.path, execution.personalAuth === undefined ? {} : { personalAuth: execution.personalAuth })).config;
|
|
451
|
-
savePrepublicationArtifact({
|
|
452
|
-
artifact,
|
|
453
|
-
classification: run.classification,
|
|
454
|
-
config,
|
|
455
|
-
issueNumber,
|
|
456
|
-
repoRoot: row.path,
|
|
457
|
-
});
|
|
458
|
-
approval = reviewArtifactApproval({ artifact, classification: run.classification, config, issueNumber });
|
|
459
|
-
}
|
|
460
|
-
const evidence = await createIssuePhaseEvidence({
|
|
461
|
-
personalAuth: context.clients.authSource === 'personal' && context.config.roles.author.authSource !== 'personal',
|
|
462
|
-
...(approval === undefined ? {} : { approval }),
|
|
463
|
-
issueNumber,
|
|
464
|
-
phase: 'verify',
|
|
465
|
-
repoRoot: row.path,
|
|
466
|
-
});
|
|
467
|
-
return {
|
|
468
|
-
classificationReceiptId: run.classification.receiptId,
|
|
469
|
-
aggregateId: run.aggregate.aggregateId,
|
|
470
|
-
evidenceId: evidence.evidenceId,
|
|
471
|
-
manifestId: run.manifestId,
|
|
472
|
-
...(run.resources === undefined ? {} : { resources: run.resources }),
|
|
473
|
-
};
|
|
474
|
-
}
|
|
475
|
-
case 'issue_pr_create': {
|
|
476
|
-
const issueNumber = requiredNumber(input, 'issueNumber');
|
|
477
|
-
if (input.dryRun === true) {
|
|
478
|
-
const row = getIssueWorktreeStrict(issueNumber, context.root);
|
|
479
|
-
const run = loadVerifiedRun(row.path, issueNumber);
|
|
480
|
-
return {
|
|
481
|
-
dryRun: true,
|
|
482
|
-
headSha: run.classification.head.sha,
|
|
483
|
-
risk: run.classification.risk,
|
|
484
|
-
reviewRoute: await preflightReviewRoute(context),
|
|
485
|
-
};
|
|
486
|
-
}
|
|
208
|
+
case 'issue_pr_create':
|
|
487
209
|
return publishPr(context, {
|
|
488
|
-
|
|
210
|
+
...(input.prNumber === undefined ? {} : { prNumber: requiredNumber(input, 'prNumber') }),
|
|
211
|
+
issueNumber: requiredNumber(input, 'issueNumber'),
|
|
212
|
+
...(input.nonClosing === undefined ? {} : { nonClosing: input.nonClosing === true }),
|
|
489
213
|
...(input.body === undefined ? {} : { body: requireString(input, 'body') }),
|
|
490
214
|
...(input.title === undefined ? {} : { title: requireString(input, 'title') }),
|
|
215
|
+
...(input.headBranch === undefined ? {} : { headBranch: requireString(input, 'headBranch') }),
|
|
491
216
|
draft: input.draft !== false,
|
|
217
|
+
dryRun: input.dryRun === true,
|
|
492
218
|
});
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
...(input.issueNumber === undefined ? {} : { issueNumber: Number(input.issueNumber) }),
|
|
497
|
-
...(input.prNumber === undefined ? {} : { prNumber: Number(input.prNumber) }),
|
|
498
|
-
});
|
|
499
|
-
}
|
|
500
|
-
case 'issue_pr_review': {
|
|
501
|
-
if (input.dryRun === true) {
|
|
502
|
-
const issueNumber = requiredNumber(input, 'issueNumber');
|
|
503
|
-
const row = getIssueWorktreeStrict(issueNumber, context.root);
|
|
504
|
-
const run = loadVerifiedRun(row.path, issueNumber);
|
|
505
|
-
const artifact = parseReviewArtifact(requireString(input, 'artifact'));
|
|
506
|
-
reviewArtifactApproval({
|
|
507
|
-
artifact,
|
|
508
|
-
classification: run.classification,
|
|
509
|
-
config: context.config,
|
|
510
|
-
issueNumber,
|
|
511
|
-
prNumber: requiredNumber(input, 'prNumber'),
|
|
512
|
-
});
|
|
513
|
-
return { dryRun: true, artifactId: artifact.artifactId };
|
|
514
|
-
}
|
|
219
|
+
case 'issue_pr_info':
|
|
220
|
+
return prInfo(context, input);
|
|
221
|
+
case 'issue_pr_review':
|
|
515
222
|
return submitFormalReview(context, {
|
|
516
223
|
artifact: requireString(input, 'artifact'),
|
|
517
224
|
issueNumber: requiredNumber(input, 'issueNumber'),
|
|
225
|
+
...(input.nonClosing === undefined ? {} : { nonClosing: input.nonClosing === true }),
|
|
518
226
|
prNumber: requiredNumber(input, 'prNumber'),
|
|
227
|
+
dryRun: input.dryRun === true,
|
|
519
228
|
});
|
|
520
|
-
}
|
|
521
229
|
case 'issue_pr_merge':
|
|
522
230
|
case 'issue_finish': {
|
|
523
|
-
const
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
return name === 'issue_finish'
|
|
532
|
-
? finishIssue(context, { issueNumber, prNumber, ...(strategy === undefined ? {} : { strategy }) })
|
|
533
|
-
: mergePr(context, { issueNumber, prNumber, ...(strategy === undefined ? {} : { strategy }) });
|
|
231
|
+
const merge = {
|
|
232
|
+
issueNumber: requiredNumber(input, 'issueNumber'),
|
|
233
|
+
...(input.nonClosing === undefined ? {} : { nonClosing: input.nonClosing === true }),
|
|
234
|
+
prNumber: requiredNumber(input, 'prNumber'),
|
|
235
|
+
...(input.strategy === undefined ? {} : { strategy: input.strategy }),
|
|
236
|
+
...(input.reviewedHeadSha === undefined ? {} : { reviewedHeadSha: requireString(input, 'reviewedHeadSha') }),
|
|
237
|
+
dryRun: input.dryRun === true,
|
|
238
|
+
};
|
|
239
|
+
return name === 'issue_finish' ? finishIssue(context, merge) : mergePr(context, merge);
|
|
534
240
|
}
|
|
535
|
-
case '
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
241
|
+
case 'issue_worktree_transition_inspect':
|
|
242
|
+
return inspectWorktreeTransition(context, {
|
|
243
|
+
...input,
|
|
244
|
+
...(execution.runtimeEntryPath === undefined ? {} : { runtimeEntryPath: execution.runtimeEntryPath }),
|
|
245
|
+
});
|
|
246
|
+
case 'issue_worktree_transition_apply':
|
|
247
|
+
return applyWorktreeTransition(context, {
|
|
248
|
+
authority: 'worktree:transition',
|
|
249
|
+
planPath: requireString(input, 'planPath'),
|
|
250
|
+
expectedPlanId: requireString(input, 'expectedPlanId'),
|
|
251
|
+
relinquishmentCommentId: requiredNumber(input, 'relinquishmentCommentId'),
|
|
252
|
+
acceptanceCommentId: requiredNumber(input, 'acceptanceCommentId'),
|
|
253
|
+
...(execution.runtimeEntryPath === undefined ? {} : { runtimeEntryPath: execution.runtimeEntryPath }),
|
|
544
254
|
});
|
|
545
|
-
}
|
|
546
255
|
}
|
|
547
256
|
}
|
|
548
257
|
//# sourceMappingURL=dispatch.js.map
|