@aviaratech/ai-delivery 0.1.0

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.
Files changed (140) hide show
  1. package/CONTRIBUTING.md +47 -0
  2. package/LICENSE +21 -0
  3. package/README.md +84 -0
  4. package/dist/agent.d.ts +17 -0
  5. package/dist/agent.js +16 -0
  6. package/dist/agent.js.map +1 -0
  7. package/dist/cli.d.ts +2 -0
  8. package/dist/cli.js +314 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/cliResult.d.ts +2 -0
  11. package/dist/cliResult.js +12 -0
  12. package/dist/cliResult.js.map +1 -0
  13. package/dist/cliResult.test.d.ts +1 -0
  14. package/dist/cliResult.test.js +30 -0
  15. package/dist/cliResult.test.js.map +1 -0
  16. package/dist/config/deliveryConfig.d.ts +113 -0
  17. package/dist/config/deliveryConfig.js +261 -0
  18. package/dist/config/deliveryConfig.js.map +1 -0
  19. package/dist/config/deliveryConfig.test.d.ts +1 -0
  20. package/dist/config/deliveryConfig.test.js +355 -0
  21. package/dist/config/deliveryConfig.test.js.map +1 -0
  22. package/dist/delivery/common.d.ts +28 -0
  23. package/dist/delivery/common.js +117 -0
  24. package/dist/delivery/common.js.map +1 -0
  25. package/dist/delivery/delivery.test.d.ts +1 -0
  26. package/dist/delivery/delivery.test.js +234 -0
  27. package/dist/delivery/delivery.test.js.map +1 -0
  28. package/dist/delivery/evidence.d.ts +92 -0
  29. package/dist/delivery/evidence.js +126 -0
  30. package/dist/delivery/evidence.js.map +1 -0
  31. package/dist/delivery/index.d.ts +8 -0
  32. package/dist/delivery/index.js +5 -0
  33. package/dist/delivery/index.js.map +1 -0
  34. package/dist/delivery/policy.d.ts +237 -0
  35. package/dist/delivery/policy.js +246 -0
  36. package/dist/delivery/policy.js.map +1 -0
  37. package/dist/delivery/stage.d.ts +125 -0
  38. package/dist/delivery/stage.js +218 -0
  39. package/dist/delivery/stage.js.map +1 -0
  40. package/dist/dispatch.d.ts +15 -0
  41. package/dist/dispatch.js +397 -0
  42. package/dist/dispatch.js.map +1 -0
  43. package/dist/errors.d.ts +4 -0
  44. package/dist/errors.js +9 -0
  45. package/dist/errors.js.map +1 -0
  46. package/dist/genericCompatibility.test.d.ts +1 -0
  47. package/dist/genericCompatibility.test.js +92 -0
  48. package/dist/genericCompatibility.test.js.map +1 -0
  49. package/dist/git.d.ts +13 -0
  50. package/dist/git.js +65 -0
  51. package/dist/git.js.map +1 -0
  52. package/dist/github/client.d.ts +34 -0
  53. package/dist/github/client.js +143 -0
  54. package/dist/github/client.js.map +1 -0
  55. package/dist/github/commandIdentityPolicy.d.ts +13 -0
  56. package/dist/github/commandIdentityPolicy.js +46 -0
  57. package/dist/github/commandIdentityPolicy.js.map +1 -0
  58. package/dist/github/nativeIssueMetadata.d.ts +78 -0
  59. package/dist/github/nativeIssueMetadata.js +249 -0
  60. package/dist/github/nativeIssueMetadata.js.map +1 -0
  61. package/dist/github/projectDelivery.d.ts +68 -0
  62. package/dist/github/projectDelivery.js +540 -0
  63. package/dist/github/projectDelivery.js.map +1 -0
  64. package/dist/github/relationships.d.ts +69 -0
  65. package/dist/github/relationships.js +395 -0
  66. package/dist/github/relationships.js.map +1 -0
  67. package/dist/github/repo.d.ts +8 -0
  68. package/dist/github/repo.js +34 -0
  69. package/dist/github/repo.js.map +1 -0
  70. package/dist/index.d.ts +2 -0
  71. package/dist/index.js +3 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/issue.d.ts +86 -0
  74. package/dist/issue.js +347 -0
  75. package/dist/issue.js.map +1 -0
  76. package/dist/lifecycle.test.d.ts +1 -0
  77. package/dist/lifecycle.test.js +1118 -0
  78. package/dist/lifecycle.test.js.map +1 -0
  79. package/dist/logger.d.ts +21 -0
  80. package/dist/logger.js +86 -0
  81. package/dist/logger.js.map +1 -0
  82. package/dist/mcp/index.d.ts +5 -0
  83. package/dist/mcp/index.js +46 -0
  84. package/dist/mcp/index.js.map +1 -0
  85. package/dist/mcp/tools.d.ts +162 -0
  86. package/dist/mcp/tools.js +154 -0
  87. package/dist/mcp/tools.js.map +1 -0
  88. package/dist/pr.d.ts +146 -0
  89. package/dist/pr.js +972 -0
  90. package/dist/pr.js.map +1 -0
  91. package/dist/pr.test.d.ts +1 -0
  92. package/dist/pr.test.js +252 -0
  93. package/dist/pr.test.js.map +1 -0
  94. package/dist/review.d.ts +104 -0
  95. package/dist/review.js +228 -0
  96. package/dist/review.js.map +1 -0
  97. package/dist/review.test.d.ts +1 -0
  98. package/dist/review.test.js +327 -0
  99. package/dist/review.test.js.map +1 -0
  100. package/dist/services/agentReadinessService.d.ts +17 -0
  101. package/dist/services/agentReadinessService.js +225 -0
  102. package/dist/services/agentReadinessService.js.map +1 -0
  103. package/dist/services/deliveryAdmission.d.ts +33 -0
  104. package/dist/services/deliveryAdmission.js +122 -0
  105. package/dist/services/deliveryAdmission.js.map +1 -0
  106. package/dist/services/deliveryRecordService.d.ts +47 -0
  107. package/dist/services/deliveryRecordService.js +199 -0
  108. package/dist/services/deliveryRecordService.js.map +1 -0
  109. package/dist/services/legacyIssueMigration.d.ts +46 -0
  110. package/dist/services/legacyIssueMigration.js +313 -0
  111. package/dist/services/legacyIssueMigration.js.map +1 -0
  112. package/dist/services/worktreeRegistry.d.ts +67 -0
  113. package/dist/services/worktreeRegistry.js +545 -0
  114. package/dist/services/worktreeRegistry.js.map +1 -0
  115. package/dist/terminalMessages.d.ts +13 -0
  116. package/dist/terminalMessages.js +43 -0
  117. package/dist/terminalMessages.js.map +1 -0
  118. package/dist/utils/atomicJson.d.ts +6 -0
  119. package/dist/utils/atomicJson.js +78 -0
  120. package/dist/utils/atomicJson.js.map +1 -0
  121. package/dist/utils/filesystem.d.ts +9 -0
  122. package/dist/utils/filesystem.js +19 -0
  123. package/dist/utils/filesystem.js.map +1 -0
  124. package/dist/utils/lockfile.d.ts +12 -0
  125. package/dist/utils/lockfile.js +78 -0
  126. package/dist/utils/lockfile.js.map +1 -0
  127. package/dist/verification.d.ts +24 -0
  128. package/dist/verification.js +227 -0
  129. package/dist/verification.js.map +1 -0
  130. package/dist/worktree.d.ts +44 -0
  131. package/dist/worktree.js +255 -0
  132. package/dist/worktree.js.map +1 -0
  133. package/package.json +82 -0
  134. package/plugins/ai-delivery/.claude-plugin/plugin.json +6 -0
  135. package/plugins/ai-delivery/.mcp.json +8 -0
  136. package/plugins/ai-delivery/README.md +5 -0
  137. package/plugins/ai-delivery/dist/mcp-launcher.js +22 -0
  138. package/plugins/ai-delivery/skills/intake-create/SKILL.md +26 -0
  139. package/plugins/ai-delivery/skills/pr-handoff/SKILL.md +28 -0
  140. package/plugins/ai-delivery/skills/worktree-lifecycle/SKILL.md +24 -0
@@ -0,0 +1,218 @@
1
+ import { join } from 'node:path';
2
+ import { z } from 'zod';
3
+ import { assertArtifact, assertPrivateFile, DigestSchema, digestBytes, digestValue, isUniqueSorted, stableJson, StageIdSchema, writeCreateOnly, } from './common.js';
4
+ import { assertRepositoryClassificationCurrent, RepositoryClassificationReceiptSchema } from './policy.js';
5
+ const SemanticInputSchema = z.object({ digest: DigestSchema, key: z.string().min(1) }).strict();
6
+ const UpstreamSchema = z.object({ receiptId: DigestSchema, stageId: StageIdSchema }).strict();
7
+ export const RepositoryStageInputSchema = z
8
+ .object({
9
+ classificationReceiptId: DigestSchema,
10
+ definitionHash: DigestSchema,
11
+ environmentDigest: DigestSchema,
12
+ inputId: DigestSchema,
13
+ policyDigest: DigestSchema,
14
+ schemaVersion: z.literal('ai-delivery.stage-input@1'),
15
+ semanticInputs: z.array(SemanticInputSchema).min(1),
16
+ stageId: StageIdSchema,
17
+ upstream: z.array(UpstreamSchema),
18
+ })
19
+ .strict()
20
+ .superRefine((value, ctx) => {
21
+ const { inputId, ...content } = value;
22
+ if (inputId !== digestValue(content) ||
23
+ !isUniqueSorted(value.semanticInputs.map((x) => x.key)) ||
24
+ !isUniqueSorted(value.upstream.map((x) => x.stageId)))
25
+ ctx.addIssue({ code: 'custom', message: 'Stage input identity or inventory is invalid.' });
26
+ });
27
+ export const RepositoryStageReceiptSchema = z
28
+ .object({
29
+ artifacts: z.array(z.object({ digest: DigestSchema, path: z.string().min(1) }).strict()),
30
+ commands: z.array(z
31
+ .object({ exitCode: z.number().int().nonnegative(), label: z.string().min(1), outputDigest: DigestSchema })
32
+ .strict()),
33
+ completedAt: z.iso.datetime(),
34
+ input: RepositoryStageInputSchema,
35
+ receiptId: DigestSchema,
36
+ result: z.literal('passed'),
37
+ schemaVersion: z.literal('ai-delivery.stage-receipt@1'),
38
+ startedAt: z.iso.datetime(),
39
+ })
40
+ .strict()
41
+ .superRefine((value, ctx) => {
42
+ const { receiptId, ...content } = value;
43
+ if (receiptId !== digestValue(content) ||
44
+ Date.parse(value.completedAt) < Date.parse(value.startedAt) ||
45
+ value.commands.some((command) => command.exitCode !== 0) ||
46
+ !isUniqueSorted(value.artifacts.map((a) => a.path)))
47
+ ctx.addIssue({ code: 'custom', message: 'Stage receipt has incomplete or corrupt proof.' });
48
+ });
49
+ export const RepositoryStageAggregateSchema = z
50
+ .object({
51
+ aggregateId: DigestSchema,
52
+ classificationReceiptId: DigestSchema,
53
+ policyDigest: DigestSchema,
54
+ result: z.literal('passed'),
55
+ schemaVersion: z.literal('ai-delivery.stage-aggregate@1'),
56
+ stages: z
57
+ .array(z.object({ inputId: DigestSchema, receiptId: DigestSchema, stageId: StageIdSchema }).strict())
58
+ .min(1),
59
+ })
60
+ .strict()
61
+ .superRefine((value, ctx) => {
62
+ const { aggregateId, ...content } = value;
63
+ if (aggregateId !== digestValue(content) ||
64
+ new Set(value.stages.map((x) => x.stageId)).size !== value.stages.length)
65
+ ctx.addIssue({ code: 'custom', message: 'Stage aggregate identity or inventory is invalid.' });
66
+ });
67
+ export function createRepositoryStageInput(input) {
68
+ const classification = RepositoryClassificationReceiptSchema.parse(input.classification);
69
+ const definition = classification.requiredStages.find((stage) => stage.id === input.stageId);
70
+ if (definition === undefined)
71
+ throw new Error('Stage is absent from selected policy.');
72
+ const semanticInputs = [...input.semanticInputs]
73
+ .sort((a, b) => a.key.localeCompare(b.key))
74
+ .map((x) => SemanticInputSchema.parse(x));
75
+ const upstream = [...input.upstream]
76
+ .sort((a, b) => a.stageId.localeCompare(b.stageId))
77
+ .map((x) => UpstreamSchema.parse(x));
78
+ if (stableJson(semanticInputs.map((x) => x.key)) !== stableJson(definition.semanticInputKeys) ||
79
+ stableJson(upstream.map((x) => x.stageId)) !== stableJson([...definition.dependsOn].sort()))
80
+ throw new Error('Stage input lacks required semantic or upstream proof.');
81
+ const content = {
82
+ classificationReceiptId: classification.receiptId,
83
+ definitionHash: digestValue(definition),
84
+ environmentDigest: DigestSchema.parse(input.environmentDigest),
85
+ policyDigest: classification.policyDigest,
86
+ schemaVersion: 'ai-delivery.stage-input@1',
87
+ semanticInputs,
88
+ stageId: definition.id,
89
+ upstream,
90
+ };
91
+ return RepositoryStageInputSchema.parse({ ...content, inputId: digestValue(content) });
92
+ }
93
+ export function createRepositoryStageReceipt(input) {
94
+ const classification = RepositoryClassificationReceiptSchema.parse(input.classification);
95
+ const stageInput = RepositoryStageInputSchema.parse(input.stageInput);
96
+ const definition = classification.requiredStages.find((stage) => stage.id === stageInput.stageId);
97
+ if (definition === undefined ||
98
+ stageInput.classificationReceiptId !== classification.receiptId ||
99
+ stageInput.policyDigest !== classification.policyDigest ||
100
+ stageInput.definitionHash !== digestValue(definition) ||
101
+ stableJson(stageInput.semanticInputs.map((x) => x.key)) !== stableJson(definition.semanticInputKeys) ||
102
+ stableJson(stageInput.upstream.map((x) => x.stageId)) !== stableJson([...definition.dependsOn].sort()) ||
103
+ input.commands.length !== definition.commands.length ||
104
+ input.commands.some((command, index) => command.label !== definition.commands[index]?.label || command.exitCode !== 0) ||
105
+ (definition.attestationKey !== undefined && input.artifacts.length === 0))
106
+ throw new Error('Stage receipt does not prove selected definition.');
107
+ const content = {
108
+ artifacts: [...input.artifacts].sort((a, b) => a.path.localeCompare(b.path)),
109
+ commands: input.commands.map((x) => ({ ...x })),
110
+ completedAt: input.completedAt,
111
+ input: stageInput,
112
+ result: 'passed',
113
+ schemaVersion: 'ai-delivery.stage-receipt@1',
114
+ startedAt: input.startedAt,
115
+ };
116
+ return RepositoryStageReceiptSchema.parse({ ...content, receiptId: digestValue(content) });
117
+ }
118
+ export function createRepositoryStageAggregate(input) {
119
+ const classification = RepositoryClassificationReceiptSchema.parse(input.classification);
120
+ if (input.receipts.length !== classification.requiredStages.length)
121
+ throw new Error('Aggregate requires every selected stage.');
122
+ const receipts = input.receipts.map((receipt) => RepositoryStageReceiptSchema.parse(receipt));
123
+ const byStage = new Map(receipts.map((receipt) => [receipt.input.stageId, receipt]));
124
+ if (byStage.size !== receipts.length)
125
+ throw new Error('Aggregate contains duplicate stages.');
126
+ for (const definition of classification.requiredStages) {
127
+ const receipt = byStage.get(definition.id);
128
+ if (receipt === undefined ||
129
+ receipt.input.classificationReceiptId !== classification.receiptId ||
130
+ receipt.input.policyDigest !== classification.policyDigest ||
131
+ receipt.input.definitionHash !== digestValue(definition) ||
132
+ stableJson(receipt.input.upstream) !==
133
+ stableJson(definition.dependsOn
134
+ .map((stageId) => ({ stageId, receiptId: byStage.get(stageId)?.receiptId }))
135
+ .sort((a, b) => a.stageId.localeCompare(b.stageId))) ||
136
+ createRepositoryStageReceipt({
137
+ artifacts: receipt.artifacts,
138
+ classification,
139
+ commands: receipt.commands,
140
+ completedAt: receipt.completedAt,
141
+ stageInput: receipt.input,
142
+ startedAt: receipt.startedAt,
143
+ }).receiptId !== receipt.receiptId)
144
+ throw new Error('Aggregate contains missing, foreign or stale stage proof.');
145
+ }
146
+ const content = {
147
+ classificationReceiptId: classification.receiptId,
148
+ policyDigest: classification.policyDigest,
149
+ result: 'passed',
150
+ schemaVersion: 'ai-delivery.stage-aggregate@1',
151
+ stages: classification.requiredStages.map((stage) => {
152
+ const receipt = byStage.get(stage.id);
153
+ return { inputId: receipt.input.inputId, receiptId: receipt.receiptId, stageId: stage.id };
154
+ }),
155
+ };
156
+ return RepositoryStageAggregateSchema.parse({ ...content, aggregateId: digestValue(content) });
157
+ }
158
+ function storeRoot(gitCommonDir) {
159
+ return join(gitCommonDir, 'ai-delivery', 'verification@1');
160
+ }
161
+ function outputPath(gitCommonDir, digest) {
162
+ return join(storeRoot(gitCommonDir), 'command-output', `${DigestSchema.parse(digest).slice(7)}.bin`);
163
+ }
164
+ function checkpointPath(gitCommonDir, stageInput) {
165
+ return join(storeRoot(gitCommonDir), 'stages', stageInput.stageId, `${stageInput.inputId.slice(7)}.json`);
166
+ }
167
+ export function writeRepositoryCommandOutput(input) {
168
+ if (input.bytes.length > 8 * 1024 * 1024)
169
+ throw new Error('Command output exceeds bounded evidence limit.');
170
+ const digest = digestBytes(input.bytes);
171
+ writeCreateOnly(outputPath(input.gitCommonDir, digest), input.bytes);
172
+ return digest;
173
+ }
174
+ export function assertRepositoryStageProof(input) {
175
+ const receipt = RepositoryStageReceiptSchema.parse(input.receipt);
176
+ for (const artifact of receipt.artifacts)
177
+ assertArtifact(input.repoRoot, artifact);
178
+ for (const command of receipt.commands)
179
+ if (digestBytes(assertPrivateFile(outputPath(input.gitCommonDir, command.outputDigest))) !== command.outputDigest)
180
+ throw new Error('Command output bytes are missing or corrupt.');
181
+ }
182
+ export function writeRepositoryStageCheckpoint(input) {
183
+ const receipt = RepositoryStageReceiptSchema.parse(input.receipt);
184
+ assertRepositoryStageProof({ ...input, receipt });
185
+ return writeCreateOnly(checkpointPath(input.gitCommonDir, receipt.input), Buffer.from(stableJson(receipt), 'utf8'));
186
+ }
187
+ export function loadRepositoryStageCheckpoint(input) {
188
+ const stageInput = RepositoryStageInputSchema.parse(input.stageInput);
189
+ assertRepositoryClassificationCurrent(input);
190
+ let bytes;
191
+ try {
192
+ bytes = assertPrivateFile(checkpointPath(input.gitCommonDir, stageInput));
193
+ }
194
+ catch (error) {
195
+ if (error.code === 'ENOENT')
196
+ return undefined;
197
+ throw error;
198
+ }
199
+ const receipt = RepositoryStageReceiptSchema.parse(JSON.parse(bytes.toString('utf8')));
200
+ if (!bytes.equals(Buffer.from(stableJson(receipt), 'utf8')) ||
201
+ receipt.input.inputId !== stageInput.inputId ||
202
+ createRepositoryStageReceipt({
203
+ artifacts: receipt.artifacts,
204
+ classification: input.classification,
205
+ commands: receipt.commands,
206
+ completedAt: receipt.completedAt,
207
+ stageInput,
208
+ startedAt: receipt.startedAt,
209
+ }).receiptId !== receipt.receiptId)
210
+ throw new Error('Stage checkpoint is corrupt or belongs to another input.');
211
+ assertRepositoryStageProof({ gitCommonDir: input.gitCommonDir, receipt, repoRoot: input.repoRoot });
212
+ return receipt;
213
+ }
214
+ export function writeRepositoryStageAggregate(input) {
215
+ const aggregate = RepositoryStageAggregateSchema.parse(input.aggregate);
216
+ return writeCreateOnly(join(storeRoot(input.gitCommonDir), 'aggregates', `${aggregate.aggregateId.slice(7)}.json`), Buffer.from(stableJson(aggregate), 'utf8'));
217
+ }
218
+ //# sourceMappingURL=stage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stage.js","sourceRoot":"","sources":["../../src/delivery/stage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { loadDeliveryContext, type UpdateIssueInput } from './issue.js';
2
+ import { type AiDeliveryMcpToolName } from './mcp/tools.js';
3
+ export interface ExecutionContext {
4
+ identity?: string;
5
+ personalAuth?: boolean;
6
+ repo?: string;
7
+ repoRoot: string;
8
+ runtimeEntryPath?: string;
9
+ }
10
+ /** @internal Preserve every accepted tracking field when completing a partially created issue. */
11
+ export declare function resumedIssueUpdate(input: Record<string, unknown>): UpdateIssueInput;
12
+ export declare function contextFor(input: ExecutionContext, commandName: string, role?: 'author' | 'reviewer'): Promise<import("./issue.js").DeliveryContext>;
13
+ /** @internal Keep CLI and MCP start routing on the same native lifecycle owner. */
14
+ export declare function startTrackedIssue(context: Awaited<ReturnType<typeof loadDeliveryContext>>, input: Record<string, unknown>): Promise<Record<string, unknown>>;
15
+ export declare function executeTool(name: AiDeliveryMcpToolName, raw: unknown, execution: ExecutionContext): Promise<unknown>;
@@ -0,0 +1,397 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { loadDeliveryConfig } from './config/deliveryConfig.js';
3
+ import { DeliveryError } from './errors.js';
4
+ import { defaultBaseRef, gitExitCode, gitRoot, primaryGitRoot } from './git.js';
5
+ import { evaluateCommandIdentityPolicy } from './github/commandIdentityPolicy.js';
6
+ import { resolveNativeRelationshipTargets } from './github/relationships.js';
7
+ import { cachedIssueInfo, CreatedTrackingIssueError, createIssue, developIssue, issueInfo, loadDeliveryContext, readyCheck, resumeCreatedIssue, updateIssue, } from './issue.js';
8
+ import { finishIssue, mergePr, prInfo, publishPr, submitFormalReview } from './pr.js';
9
+ import { parseReviewArtifact, reviewArtifactApproval, savePrepublicationArtifact } from './review.js';
10
+ import { evaluateAgentReadiness } from './services/agentReadinessService.js';
11
+ import { assertDeliveryRuntimeAdmitted } from './services/deliveryAdmission.js';
12
+ import { getIssueWorktreeStrict, listWorktreesStrict } from './services/worktreeRegistry.js';
13
+ import { createIssuePhaseEvidence, loadVerifiedRun, verifyIssue } from './verification.js';
14
+ import { prepareStandaloneWorktree } from './worktree.js';
15
+ import { getAiDeliveryMcpTool } from './mcp/tools.js';
16
+ const MUTATING_TOOLS = new Set([
17
+ 'issue_create',
18
+ 'issue_start',
19
+ 'issue_update',
20
+ 'issue_develop',
21
+ 'issue_verify',
22
+ 'issue_pr_create',
23
+ 'issue_pr_review',
24
+ 'issue_pr_merge',
25
+ 'issue_finish',
26
+ 'issue_worktree_create',
27
+ ]);
28
+ function requiredNumber(input, key) {
29
+ const value = input[key];
30
+ if (typeof value !== 'number' || !Number.isSafeInteger(value) || value <= 0)
31
+ throw new DeliveryError(`${key} must be positive.`);
32
+ return value;
33
+ }
34
+ function optionalString(input, key) {
35
+ return typeof input[key] === 'string' ? input[key] : undefined;
36
+ }
37
+ function requireString(input, key) {
38
+ const value = optionalString(input, key);
39
+ if (!value?.trim())
40
+ throw new DeliveryError(`${key} is required.`);
41
+ return value;
42
+ }
43
+ /** @internal Preserve every accepted tracking field when completing a partially created issue. */
44
+ export function resumedIssueUpdate(input) {
45
+ return {
46
+ issueNumber: requiredNumber(input, 'issueNumber'),
47
+ ...(input.body === undefined ? {} : { body: requireString(input, 'body') }),
48
+ ...(input.issueType === undefined ? {} : { issueType: requireString(input, 'issueType') }),
49
+ ...(input.points === undefined ? {} : { points: Number(input.points) }),
50
+ ...(input.priority === undefined ? {} : { priority: requireString(input, 'priority') }),
51
+ ...(input.title === undefined ? {} : { title: requireString(input, 'title') }),
52
+ ...(input.labels === undefined ? {} : { labels: input.labels }),
53
+ ...(input.milestone === undefined ? {} : { milestone: Number(input.milestone) }),
54
+ ...(input.parentIssueNumber === undefined ? {} : { parentIssueNumber: Number(input.parentIssueNumber) }),
55
+ ...(input.blockedBy === undefined ? {} : { blockedBy: input.blockedBy }),
56
+ };
57
+ }
58
+ function identityFor(input, commandName) {
59
+ const config = loadDeliveryConfig(gitRoot(input.repoRoot)).config;
60
+ const identity = input.identity ?? '';
61
+ const policy = evaluateCommandIdentityPolicy({
62
+ commandName,
63
+ deliveryConfig: config,
64
+ identity,
65
+ ...(input.personalAuth === undefined ? {} : { personalAuth: input.personalAuth }),
66
+ });
67
+ if (policy.error)
68
+ throw new DeliveryError(policy.error);
69
+ return identity || config.roles.author.identity;
70
+ }
71
+ function assertRepositorySelector(input, execution) {
72
+ const selector = input.repo ?? execution.repo;
73
+ if (selector === undefined)
74
+ return;
75
+ const configured = loadDeliveryConfig(gitRoot(execution.repoRoot)).config.repository;
76
+ if (typeof selector !== 'string' || selector.toLowerCase() !== configured.toLowerCase()) {
77
+ throw new DeliveryError('Repository selector must match the configured repository for this Git checkout.');
78
+ }
79
+ }
80
+ export async function contextFor(input, commandName, role = 'author') {
81
+ assertRepositorySelector({}, input);
82
+ const identity = identityFor(input, commandName);
83
+ return loadDeliveryContext({
84
+ identity,
85
+ ...(input.personalAuth === undefined ? {} : { personalAuth: input.personalAuth }),
86
+ repoRoot: input.repoRoot,
87
+ role,
88
+ });
89
+ }
90
+ /** @internal Keep CLI and MCP start routing on the same native lifecycle owner. */
91
+ export async function startTrackedIssue(context, input) {
92
+ const knownIssue = input.issueNumber === undefined ? undefined : requiredNumber(input, 'issueNumber');
93
+ if (input.resumeCreated === true && (knownIssue === undefined || input.develop !== true)) {
94
+ throw new DeliveryError('Resume of a known created issue requires issueNumber and develop=true.');
95
+ }
96
+ if (knownIssue !== undefined && input.resumeCreated !== true) {
97
+ const row = await developIssue(context, knownIssue);
98
+ const title = (await issueInfo(context, knownIssue)).title;
99
+ return {
100
+ issueNumber: knownIssue,
101
+ mode: 'existing-issue',
102
+ title,
103
+ branch: row.branch,
104
+ path: row.path,
105
+ worktreePath: row.path,
106
+ };
107
+ }
108
+ const request = optionalString(input, 'request');
109
+ const title = optionalString(input, 'title') ?? requireString(input, 'request');
110
+ const points = input.points === undefined ? 2 : requiredNumber(input, 'points');
111
+ const tracking = {
112
+ body: optionalString(input, 'body') ?? request ?? title,
113
+ title,
114
+ points,
115
+ ...(input.issueType === undefined ? {} : { issueType: requireString(input, 'issueType') }),
116
+ ...(input.priority === undefined ? {} : { priority: requireString(input, 'priority') }),
117
+ ...(input.blockedBy === undefined ? {} : { blockedBy: input.blockedBy }),
118
+ ...(input.labels === undefined ? {} : { labels: input.labels }),
119
+ ...(input.milestone === undefined ? {} : { milestone: Number(input.milestone) }),
120
+ ...(input.parentIssueNumber === undefined ? {} : { parentIssueNumber: Number(input.parentIssueNumber) }),
121
+ };
122
+ if (input.develop === true)
123
+ await preflightStartDevelopment(context, tracking);
124
+ const repository = `${context.repo.owner}/${context.repo.repo}`;
125
+ const createdNotStarted = (createdIssue, phase, error) => ({
126
+ schemaVersion: 'ai-delivery.issue-start-registration@1',
127
+ status: 'created-not-started',
128
+ provider: 'github',
129
+ repository,
130
+ identity: context.config.roles.author.identity,
131
+ createdIssue,
132
+ failure: { phase, message: error instanceof Error ? error.message : String(error) },
133
+ safeResume: {
134
+ tool: 'issue_start',
135
+ arguments: {
136
+ ...tracking,
137
+ ...(input.repo === undefined ? {} : { repo: input.repo }),
138
+ issueNumber: createdIssue.number,
139
+ develop: true,
140
+ resumeCreated: true,
141
+ },
142
+ },
143
+ });
144
+ let created;
145
+ if (knownIssue !== undefined) {
146
+ const existing = (await context.clients.rest.issues.get({ ...context.repo, issue_number: knownIssue })).data;
147
+ if (existing.number !== knownIssue || 'pull_request' in existing) {
148
+ throw new DeliveryError('Known-created issue readback disagrees with the requested issue.');
149
+ }
150
+ created = { number: existing.number, title: existing.title, url: existing.html_url };
151
+ try {
152
+ await resumeCreatedIssue(context, resumedIssueUpdate(input));
153
+ }
154
+ catch (error) {
155
+ return createdNotStarted(created, 'tracking', error);
156
+ }
157
+ }
158
+ else {
159
+ try {
160
+ created = (await createIssue(context, tracking)).created;
161
+ }
162
+ catch (error) {
163
+ if (input.develop === true && error instanceof CreatedTrackingIssueError) {
164
+ return createdNotStarted(error.created, 'tracking', error);
165
+ }
166
+ throw error;
167
+ }
168
+ }
169
+ if (input.develop === true) {
170
+ try {
171
+ const row = await developIssue(context, created.number);
172
+ return {
173
+ schemaVersion: 'ai-delivery.issue-start-registration@1',
174
+ status: 'started',
175
+ provider: 'github',
176
+ repository,
177
+ identity: context.config.roles.author.identity,
178
+ issue: created,
179
+ branch: row.branch,
180
+ worktreePath: row.path,
181
+ };
182
+ }
183
+ catch (error) {
184
+ return createdNotStarted(created, 'development', error);
185
+ }
186
+ }
187
+ return { issueNumber: created.number, issueUrl: created.url, mode: 'created-issue', title: created.title };
188
+ }
189
+ async function preflightStartDevelopment(context, tracking) {
190
+ const targets = await resolveNativeRelationshipTargets({
191
+ blockers: tracking.blockedBy ?? [],
192
+ ...(tracking.parentIssueNumber === undefined ? {} : { parentIssueNumber: tracking.parentIssueNumber }),
193
+ repo: context.repo,
194
+ rest: context.clients.rest,
195
+ });
196
+ const readiness = evaluateAgentReadiness({
197
+ blockedBy: targets.unresolvedBlockers,
198
+ body: tracking.body ?? '',
199
+ ...(tracking.points === undefined ? {} : { points: tracking.points }),
200
+ repoRoot: context.root,
201
+ title: tracking.title,
202
+ });
203
+ if (!readiness.ready) {
204
+ throw new DeliveryError(`New issue is not ready: ${readiness.failures.map((failure) => failure.message).join('; ')}`);
205
+ }
206
+ listWorktreesStrict(context.root);
207
+ if (gitExitCode(context.root, 'rev-parse', '--verify', defaultBaseRef(context.root)) !== 0) {
208
+ throw new DeliveryError('Default base ref is missing before tracked issue creation.');
209
+ }
210
+ }
211
+ function scratchStart(input, execution, identity) {
212
+ const title = (optionalString(input, 'title') ?? requireString(input, 'request'))
213
+ .replace(/\s+/gu, ' ')
214
+ .trim()
215
+ .slice(0, 90)
216
+ .trim();
217
+ const branchOverride = optionalString(input, 'branch');
218
+ const source = (branchOverride ?? optionalString(input, 'request') ?? title).replace(/\//gu, '-');
219
+ const slug = source
220
+ .trim()
221
+ .toLowerCase()
222
+ .replace(/[^a-z0-9]+/gu, '-')
223
+ .replace(/^-+|-+$/gu, '')
224
+ .slice(0, 56)
225
+ .replace(/-+$/gu, '') || 'scratch';
226
+ const branch = branchOverride ?? `scratch/${slug}`;
227
+ const name = `scratch-${slug}`;
228
+ return prepareStandaloneWorktree({ branch, identity, name, repoRoot: execution.repoRoot }).then((row) => ({
229
+ mode: 'scratch',
230
+ title,
231
+ branch: row.branch,
232
+ worktreePath: row.path,
233
+ }));
234
+ }
235
+ export async function executeTool(name, raw, execution) {
236
+ const definition = getAiDeliveryMcpTool(name);
237
+ if (!definition)
238
+ throw new DeliveryError(`Unknown ai-delivery tool ${name}.`);
239
+ const input = definition.inputSchema.parse(raw);
240
+ assertRepositorySelector(input, execution);
241
+ if (MUTATING_TOOLS.has(name) && input.dryRun !== true) {
242
+ assertDeliveryRuntimeAdmitted(execution);
243
+ }
244
+ switch (name) {
245
+ case 'issue_create': {
246
+ const context = await contextFor(execution, 'create');
247
+ return createIssue(context, input);
248
+ }
249
+ case 'issue_start': {
250
+ const identity = identityFor(execution, 'start');
251
+ if (input.resumeCreated === true && (input.issueNumber === undefined || input.develop !== true)) {
252
+ throw new DeliveryError('Resume of a known created issue requires issueNumber and develop=true.');
253
+ }
254
+ if (input.scratch === true) {
255
+ if (input.issueNumber !== undefined || input.develop === true || input.resumeCreated === true) {
256
+ throw new DeliveryError('Scratch worktree cannot claim a tracked issue.');
257
+ }
258
+ return scratchStart(input, execution, identity);
259
+ }
260
+ const context = await contextFor(execution, 'start');
261
+ return startTrackedIssue(context, input);
262
+ }
263
+ case 'issue_update': {
264
+ const context = await contextFor(execution, 'update');
265
+ return updateIssue(context, input);
266
+ }
267
+ case 'issue_info': {
268
+ if (input.cached === true)
269
+ return cachedIssueInfo(execution.repoRoot, requiredNumber(input, 'issueNumber'));
270
+ const context = await contextFor(execution, 'info');
271
+ return issueInfo(context, requiredNumber(input, 'issueNumber'));
272
+ }
273
+ case 'issue_ready_check': {
274
+ const context = await contextFor(execution, 'ready:check');
275
+ return readyCheck(context, requiredNumber(input, 'issueNumber'));
276
+ }
277
+ case 'issue_develop': {
278
+ const context = await contextFor(execution, 'develop');
279
+ const issueNumber = requiredNumber(input, 'issueNumber');
280
+ const result = await developIssue(context, issueNumber);
281
+ if (input.assignee !== undefined)
282
+ await context.clients.rest.issues.addAssignees({
283
+ ...context.repo,
284
+ issue_number: issueNumber,
285
+ assignees: [requireString(input, 'assignee')],
286
+ });
287
+ return result;
288
+ }
289
+ case 'issue_verify': {
290
+ const issueNumber = requiredNumber(input, 'issueNumber');
291
+ const root = primaryGitRoot(execution.repoRoot);
292
+ const row = getIssueWorktreeStrict(issueNumber, root);
293
+ const run = await verifyIssue({
294
+ issueNumber,
295
+ repoRoot: row.path,
296
+ ...(input.admit === undefined
297
+ ? {}
298
+ : { admittedResourceClasses: ['source_only', ...input.admit] }),
299
+ });
300
+ let approval;
301
+ if (input.prepublicationReview !== undefined) {
302
+ const artifact = parseReviewArtifact(readFileSync(requireString(input, 'prepublicationReview'), 'utf8'));
303
+ const config = loadDeliveryConfig(row.path).config;
304
+ savePrepublicationArtifact({
305
+ artifact,
306
+ classification: run.classification,
307
+ config,
308
+ issueNumber,
309
+ repoRoot: row.path,
310
+ });
311
+ approval = reviewArtifactApproval({ artifact, classification: run.classification, config, issueNumber });
312
+ }
313
+ const evidence = await createIssuePhaseEvidence({
314
+ ...(approval === undefined ? {} : { approval }),
315
+ issueNumber,
316
+ phase: 'verify',
317
+ repoRoot: row.path,
318
+ });
319
+ return {
320
+ classificationReceiptId: run.classification.receiptId,
321
+ aggregateId: run.aggregate.aggregateId,
322
+ evidenceId: evidence.evidenceId,
323
+ manifestId: run.manifestId,
324
+ };
325
+ }
326
+ case 'issue_pr_create': {
327
+ const context = await contextFor(execution, 'pr:create');
328
+ const issueNumber = requiredNumber(input, 'issueNumber');
329
+ if (input.dryRun === true) {
330
+ const row = getIssueWorktreeStrict(issueNumber, context.root);
331
+ const run = loadVerifiedRun(row.path, issueNumber);
332
+ return { dryRun: true, headSha: run.classification.head.sha, risk: run.classification.risk };
333
+ }
334
+ return publishPr(context, {
335
+ issueNumber,
336
+ ...(input.body === undefined ? {} : { body: requireString(input, 'body') }),
337
+ ...(input.title === undefined ? {} : { title: requireString(input, 'title') }),
338
+ draft: input.draft !== false,
339
+ });
340
+ }
341
+ case 'issue_pr_info': {
342
+ const context = await contextFor(execution, 'pr:info');
343
+ return prInfo(context, {
344
+ ...(input.issueNumber === undefined ? {} : { issueNumber: Number(input.issueNumber) }),
345
+ ...(input.prNumber === undefined ? {} : { prNumber: Number(input.prNumber) }),
346
+ });
347
+ }
348
+ case 'issue_pr_review': {
349
+ const identity = optionalString(input, 'identity') ?? execution.identity;
350
+ const context = await contextFor({ ...execution, ...(identity === undefined ? {} : { identity }) }, 'pr:review', 'reviewer');
351
+ if (input.dryRun === true) {
352
+ const issueNumber = requiredNumber(input, 'issueNumber');
353
+ const row = getIssueWorktreeStrict(issueNumber, context.root);
354
+ const run = loadVerifiedRun(row.path, issueNumber);
355
+ const artifact = parseReviewArtifact(requireString(input, 'artifact'));
356
+ reviewArtifactApproval({
357
+ artifact,
358
+ classification: run.classification,
359
+ config: context.config,
360
+ issueNumber,
361
+ prNumber: requiredNumber(input, 'prNumber'),
362
+ });
363
+ return { dryRun: true, artifactId: artifact.artifactId };
364
+ }
365
+ return submitFormalReview(context, {
366
+ artifact: requireString(input, 'artifact'),
367
+ issueNumber: requiredNumber(input, 'issueNumber'),
368
+ prNumber: requiredNumber(input, 'prNumber'),
369
+ });
370
+ }
371
+ case 'issue_pr_merge':
372
+ case 'issue_finish': {
373
+ const context = await contextFor(execution, name === 'issue_finish' ? 'finish' : 'pr:merge');
374
+ const issueNumber = requiredNumber(input, 'issueNumber');
375
+ const prNumber = requiredNumber(input, 'prNumber');
376
+ if (input.dryRun === true) {
377
+ const row = getIssueWorktreeStrict(issueNumber, context.root);
378
+ const run = loadVerifiedRun(row.path, issueNumber);
379
+ return { dryRun: true, headSha: run.classification.head.sha, prNumber };
380
+ }
381
+ const strategy = input.strategy;
382
+ return name === 'issue_finish'
383
+ ? finishIssue(context, { issueNumber, prNumber, ...(strategy === undefined ? {} : { strategy }) })
384
+ : mergePr(context, { issueNumber, prNumber, ...(strategy === undefined ? {} : { strategy }) });
385
+ }
386
+ case 'issue_worktree_create': {
387
+ const identity = identityFor(execution, 'worktree:create');
388
+ return prepareStandaloneWorktree({
389
+ branch: requireString(input, 'branch'),
390
+ identity,
391
+ name: requireString(input, 'name'),
392
+ repoRoot: execution.repoRoot,
393
+ });
394
+ }
395
+ }
396
+ }
397
+ //# sourceMappingURL=dispatch.js.map