opencode-magi 0.9.0 → 0.11.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 (126) hide show
  1. package/README.ja.md +254 -0
  2. package/README.md +37 -34
  3. package/dist/commands.js +11 -9
  4. package/dist/config/index.js +2 -0
  5. package/dist/config/resolve.js +120 -248
  6. package/dist/config/validate.js +103 -1100
  7. package/dist/constant.js +135 -0
  8. package/dist/graphql/index.generated.js +125 -0
  9. package/dist/graphql/index.js +49 -0
  10. package/dist/index.js +12 -800
  11. package/dist/magi.js +357 -0
  12. package/dist/permissions/common.json +22 -22
  13. package/dist/permissions/editor.json +12 -12
  14. package/dist/prompts/index.js +98 -0
  15. package/dist/prompts/merge/ci-classification/output-contract.md +22 -0
  16. package/dist/prompts/merge/ci-classification/task.md +10 -0
  17. package/dist/prompts/merge/ci-classification/validate.json +20 -0
  18. package/dist/prompts/merge/conflict/output-contract.md +12 -0
  19. package/dist/prompts/merge/conflict/task.md +9 -0
  20. package/dist/prompts/merge/conflict/validate.json +4 -0
  21. package/dist/prompts/merge/edit/output-contract.md +26 -0
  22. package/dist/prompts/merge/edit/task.md +10 -0
  23. package/dist/prompts/merge/edit/validate.json +60 -0
  24. package/dist/prompts/review/ci-classification/output-contract.md +21 -0
  25. package/dist/prompts/review/ci-classification/task.md +7 -0
  26. package/dist/prompts/review/ci-classification/validate.json +20 -0
  27. package/dist/prompts/review/close-reconsideration/output-contract.md +21 -0
  28. package/dist/prompts/review/close-reconsideration/task.md +6 -0
  29. package/dist/prompts/review/close-reconsideration/validate.json +44 -0
  30. package/dist/prompts/review/comment/output-contract.md +11 -0
  31. package/dist/prompts/review/comment/task.md +3 -0
  32. package/dist/prompts/review/comment/validate.json +8 -0
  33. package/dist/prompts/review/finding-validation/output-contract.md +25 -0
  34. package/dist/prompts/{templates/review/finding-validation.md → review/finding-validation/task.md} +2 -3
  35. package/dist/prompts/review/finding-validation/validate.json +21 -0
  36. package/dist/prompts/review/rereview/output-contract.md +30 -0
  37. package/dist/prompts/{templates/review/rereview.md → review/rereview/task.md} +8 -11
  38. package/dist/prompts/review/rereview/validate.json +87 -0
  39. package/dist/prompts/review/review/output-contract.md +25 -0
  40. package/dist/prompts/{templates/review/review.md → review/review/task.md} +2 -5
  41. package/dist/prompts/review/review/validate.json +54 -0
  42. package/dist/prompts/triage/acceptance/output-contract.md +16 -0
  43. package/dist/prompts/triage/acceptance/validate.json +23 -0
  44. package/dist/prompts/triage/category/output-contract.md +16 -0
  45. package/dist/prompts/triage/category/validate.json +23 -0
  46. package/dist/prompts/triage/comment-classification/output-contract.md +15 -0
  47. package/dist/prompts/triage/comment-classification/validate.json +28 -0
  48. package/dist/prompts/triage/create/output-contract.md +28 -0
  49. package/dist/prompts/triage/create/validate.json +73 -0
  50. package/dist/prompts/triage/deplicate/output-contract.md +16 -0
  51. package/dist/prompts/triage/deplicate/validate.json +20 -0
  52. package/dist/prompts/triage/existing/output-contract.md +16 -0
  53. package/dist/prompts/triage/existing/validate.json +13 -0
  54. package/dist/prompts/triage/reconsider/output-contract.md +16 -0
  55. package/dist/prompts/triage/reconsider/validate.json +23 -0
  56. package/dist/prompts/triage/signal/output-contract.md +19 -0
  57. package/dist/prompts/triage/signal/validate.json +18 -0
  58. package/dist/tools/clear/index.js +21 -0
  59. package/dist/tools/index.js +12 -0
  60. package/dist/tools/merge/action.js +47 -0
  61. package/dist/tools/merge/context.js +118 -0
  62. package/dist/tools/merge/editor.js +264 -0
  63. package/dist/tools/merge/index.js +151 -0
  64. package/dist/tools/merge/index.type.js +1 -0
  65. package/dist/tools/merge/merge.js +42 -0
  66. package/dist/tools/merge/report.js +73 -0
  67. package/dist/tools/review/action.js +429 -0
  68. package/dist/tools/review/check.js +295 -0
  69. package/dist/tools/review/context.js +258 -0
  70. package/dist/tools/review/index.js +104 -0
  71. package/dist/tools/review/index.type.js +1 -0
  72. package/dist/tools/review/report.js +143 -0
  73. package/dist/tools/review/review.js +145 -0
  74. package/dist/tools/review/reviewer.js +409 -0
  75. package/dist/tools/triage/index.js +16 -0
  76. package/dist/tools/validate/index.js +28 -0
  77. package/dist/utils/array.js +6 -0
  78. package/dist/utils/assertion.js +38 -0
  79. package/dist/utils/exec.js +14 -0
  80. package/dist/utils/fs.js +24 -0
  81. package/dist/utils/function.js +37 -0
  82. package/dist/utils/github.js +63 -0
  83. package/dist/utils/index.js +10 -0
  84. package/dist/utils/index.type.js +1 -0
  85. package/dist/utils/object.js +21 -0
  86. package/dist/utils/opencode.js +25 -0
  87. package/dist/utils/string.js +38 -0
  88. package/dist/utils/worker.js +30 -0
  89. package/package.json +20 -8
  90. package/schema.json +9 -7
  91. package/dist/config/load.js +0 -62
  92. package/dist/config/output.js +0 -25
  93. package/dist/config/worktree.js +0 -25
  94. package/dist/github/commands.js +0 -905
  95. package/dist/github/retry.js +0 -44
  96. package/dist/orchestrator/abort.js +0 -9
  97. package/dist/orchestrator/ci.js +0 -579
  98. package/dist/orchestrator/findings.js +0 -88
  99. package/dist/orchestrator/inline-comments.js +0 -73
  100. package/dist/orchestrator/majority.js +0 -62
  101. package/dist/orchestrator/merge.js +0 -1260
  102. package/dist/orchestrator/model.js +0 -216
  103. package/dist/orchestrator/pool.js +0 -15
  104. package/dist/orchestrator/report.js +0 -175
  105. package/dist/orchestrator/review-context.js +0 -342
  106. package/dist/orchestrator/review.js +0 -1478
  107. package/dist/orchestrator/run-manager.js +0 -2132
  108. package/dist/orchestrator/safety.js +0 -44
  109. package/dist/orchestrator/triage.js +0 -1370
  110. package/dist/prompts/compose.js +0 -473
  111. package/dist/prompts/contracts.js +0 -300
  112. package/dist/prompts/output.js +0 -401
  113. package/dist/prompts/templates/merge/ci-classification.md +0 -16
  114. package/dist/prompts/templates/merge/conflict.md +0 -10
  115. package/dist/prompts/templates/merge/edit.md +0 -15
  116. package/dist/prompts/templates/review/ci-classification.md +0 -9
  117. package/dist/prompts/templates/review/close-reconsideration.md +0 -6
  118. /package/dist/{types.js → config/index.type.js} +0 -0
  119. /package/dist/prompts/{templates/triage/acceptance.md → triage/acceptance/task.md} +0 -0
  120. /package/dist/prompts/{templates/triage/category.md → triage/category/task.md} +0 -0
  121. /package/dist/prompts/{templates/triage/comment-classification.md → triage/comment-classification/task.md} +0 -0
  122. /package/dist/prompts/{templates/triage/create.md → triage/create/task.md} +0 -0
  123. /package/dist/prompts/{templates/triage/duplicate.md → triage/deplicate/task.md} +0 -0
  124. /package/dist/prompts/{templates/triage/existing-pr.md → triage/existing/task.md} +0 -0
  125. /package/dist/prompts/{templates/triage/reconsider.md → triage/reconsider/task.md} +0 -0
  126. /package/dist/prompts/{templates/triage/signal.md → triage/signal/task.md} +0 -0
@@ -1,473 +0,0 @@
1
- import { readFile } from "node:fs/promises";
2
- import { homedir } from "node:os";
3
- import { isAbsolute, join } from "node:path";
4
- import { ciClassificationAfterEditOutputContract, ciClassificationOutputContract, closeReconsiderationOutputContract, editOutputContract, findingValidationOutputContract, rereviewCloseReconsiderationOutputContract, rereviewOutputContract, reviewOutputContract, triageCommentClassificationOutputContract, triageCreatePrOutputContract, triageDuplicateOutputContract, triageSignalOutputContract, triageVoteOutputContract, } from "./contracts";
5
- async function readOptionalPrompt(directory, path, values = {}) {
6
- if (!path)
7
- return "";
8
- const fullPath = promptPath(directory, path);
9
- return renderTemplate(await readFile(fullPath, "utf8"), values);
10
- }
11
- function promptPath(directory, path) {
12
- if (path === "~")
13
- return homedir();
14
- if (path.startsWith("~/"))
15
- return join(homedir(), path.slice(2));
16
- return isAbsolute(path) ? path : join(directory, path);
17
- }
18
- async function readTemplate(name) {
19
- return readFile(new URL(`./templates/${name}.md`, import.meta.url), "utf8");
20
- }
21
- function renderTemplate(template, values) {
22
- return template.replaceAll(/\{([A-Za-z0-9_]+)\}/g, (match, key) => values[key] ?? match);
23
- }
24
- async function taskBlock(input) {
25
- const body = input.customPath
26
- ? await readOptionalPrompt(input.directory, input.customPath, input.values)
27
- : renderTemplate(await readTemplate(input.builtin), input.values);
28
- return `<task>\n${body.trim()}\n</task>`;
29
- }
30
- function repositoryValues(repository) {
31
- return {
32
- owner: repository.github.owner,
33
- repo: repository.github.repo,
34
- };
35
- }
36
- function reviewValues(input) {
37
- const ciFailureContext = input.ciFailureContext?.trim() ?? "";
38
- const mergeConflictContext = input.mergeConflictContext?.trim() ?? "";
39
- return {
40
- ...repositoryValues(input.repository),
41
- baseSha: input.baseSha,
42
- ciFailureContext,
43
- ciFailureContextBlock: ciFailureContext
44
- ? `<ci_failure_context>\n${ciFailureContext}\n</ci_failure_context>`
45
- : "",
46
- headSha: input.headSha,
47
- jsonEncodedWorktreePath: JSON.stringify(input.worktreePath),
48
- mergeConflictContext,
49
- mergeConflictContextBlock: mergeConflictContext
50
- ? `<merge_conflict_context>\n${mergeConflictContext}\n</merge_conflict_context>`
51
- : "",
52
- pr: String(input.pr),
53
- reviewContext: input.reviewContext ?? "",
54
- worktreePath: input.worktreePath,
55
- };
56
- }
57
- function rereviewValues(input) {
58
- return {
59
- ...reviewValues(input),
60
- previousHeadSha: input.previousHeadSha,
61
- previousReview: input.previousReview ?? "",
62
- previousReviewBlock: previousReviewBlock(input.previousReview),
63
- unresolvedThreads: input.unresolvedThreads,
64
- };
65
- }
66
- function editValues(input) {
67
- return {
68
- ...repositoryValues(input.repository),
69
- pr: String(input.pr),
70
- reviewFindings: input.reviewFindings,
71
- unresolvedThreads: input.unresolvedThreads,
72
- worktreePath: input.worktreePath,
73
- };
74
- }
75
- function mergeConflictValues(input) {
76
- return {
77
- ...repositoryValues(input.repository),
78
- baseBranch: input.baseBranch,
79
- baseSha: input.baseSha,
80
- conflictedFiles: input.conflictedFiles,
81
- headSha: input.headSha,
82
- pr: String(input.pr),
83
- worktreePath: input.worktreePath,
84
- };
85
- }
86
- function triageValues(input) {
87
- const categories = input.repository.triage?.categories ?? [];
88
- const categoryOptions = categories
89
- .map((category) => category.description
90
- ? `- ${category.id}: ${category.description}`
91
- : `- ${category.id}`)
92
- .join("\n");
93
- const signalOptions = (input.repository.triage?.signals ?? [])
94
- .map((signal) => `- ${signal.id}: ${signal.description}`)
95
- .join("\n");
96
- return {
97
- ...repositoryValues(input.repository),
98
- author: input.author ?? "",
99
- categoryOptions,
100
- context: input.context,
101
- issue: String(input.issue),
102
- signalOptions,
103
- worktreePath: input.worktreePath ?? "",
104
- };
105
- }
106
- function personaBlock(persona) {
107
- return persona ? `<persona>\n${persona}\n</persona>` : "";
108
- }
109
- function languageBlock(language) {
110
- return language ? `<language>\n${language}\n</language>` : "";
111
- }
112
- function previousReviewBlock(previousReview) {
113
- return previousReview?.trim()
114
- ? `<previous_review>\n${previousReview.trim()}\n</previous_review>`
115
- : "";
116
- }
117
- function reviewContextBlock(reviewContext) {
118
- return reviewContext?.trim() ? reviewContext.trim() : "";
119
- }
120
- function mergeConflictContextBlock(mergeConflictContext) {
121
- const body = mergeConflictContext?.trim();
122
- return body
123
- ? `<merge_conflict_context>\n${body}\n</merge_conflict_context>`
124
- : "";
125
- }
126
- async function reviewGuidelinesBlock(input) {
127
- const body = (await readOptionalPrompt(input.directory, input.path, input.values)).trim();
128
- return body ? `<review_guidelines>\n${body}\n</review_guidelines>` : "";
129
- }
130
- async function editGuidelinesBlock(input) {
131
- const body = (await readOptionalPrompt(input.directory, input.path, input.values)).trim();
132
- return body ? `<edit_guidelines>\n${body}\n</edit_guidelines>` : "";
133
- }
134
- async function createGuidelinesBlock(input) {
135
- const body = (await readOptionalPrompt(input.directory, input.path, input.values)).trim();
136
- return body ? `<create_guidelines>\n${body}\n</create_guidelines>` : "";
137
- }
138
- async function sessionContextBlocks(input) {
139
- return [
140
- input.includeSessionContext
141
- ? reviewContextBlock(input.values.reviewContext)
142
- : "",
143
- input.includeSessionContext ? languageBlock(input.repository.language) : "",
144
- input.includeSessionContext ? personaBlock(input.reviewer.persona) : "",
145
- input.includeReviewGuidelines
146
- ? await reviewGuidelinesBlock({
147
- directory: input.directory,
148
- path: input.repository.prompts.reviewGuidelines,
149
- values: input.values,
150
- })
151
- : "",
152
- ];
153
- }
154
- export async function composeReviewPrompt(input) {
155
- const values = reviewValues(input);
156
- const task = await taskBlock({
157
- builtin: "review/review",
158
- customPath: input.repository.prompts.review,
159
- directory: input.directory,
160
- values,
161
- });
162
- return [
163
- task,
164
- reviewContextBlock(input.reviewContext),
165
- mergeConflictContextBlock(input.mergeConflictContext),
166
- languageBlock(input.repository.language),
167
- personaBlock(input.reviewer.persona),
168
- await reviewGuidelinesBlock({
169
- directory: input.directory,
170
- path: input.repository.prompts.reviewGuidelines,
171
- values,
172
- }),
173
- reviewOutputContract,
174
- ]
175
- .filter(Boolean)
176
- .join("\n\n");
177
- }
178
- export async function composeRereviewPrompt(input) {
179
- const values = rereviewValues(input);
180
- const task = await taskBlock({
181
- builtin: "review/rereview",
182
- customPath: input.repository.prompts.rereview,
183
- directory: input.directory,
184
- values,
185
- });
186
- return [
187
- task,
188
- reviewContextBlock(input.reviewContext),
189
- mergeConflictContextBlock(input.mergeConflictContext),
190
- input.includeSessionContext === false
191
- ? ""
192
- : languageBlock(input.repository.language),
193
- input.includeSessionContext === false
194
- ? ""
195
- : personaBlock(input.reviewer.persona),
196
- input.includeReviewGuidelines === false
197
- ? ""
198
- : await reviewGuidelinesBlock({
199
- directory: input.directory,
200
- path: input.repository.prompts.reviewGuidelines,
201
- values,
202
- }),
203
- rereviewOutputContract,
204
- ]
205
- .filter(Boolean)
206
- .join("\n\n");
207
- }
208
- export async function composeEditPrompt(input) {
209
- const values = editValues(input);
210
- const task = await taskBlock({
211
- builtin: "merge/edit",
212
- customPath: input.repository.prompts.edit,
213
- directory: input.directory,
214
- values,
215
- });
216
- const persona = input.repository.agents.editor?.persona;
217
- return [
218
- task,
219
- languageBlock(input.repository.language),
220
- personaBlock(persona),
221
- await editGuidelinesBlock({
222
- directory: input.directory,
223
- path: input.repository.prompts.editGuidelines,
224
- values,
225
- }),
226
- editOutputContract,
227
- ]
228
- .filter(Boolean)
229
- .join("\n\n");
230
- }
231
- export async function composeMergeConflictPrompt(input) {
232
- const values = mergeConflictValues(input);
233
- const task = await taskBlock({
234
- builtin: "merge/conflict",
235
- directory: input.directory,
236
- values,
237
- });
238
- const persona = input.repository.agents.editor?.persona;
239
- return [
240
- task,
241
- languageBlock(input.repository.language),
242
- personaBlock(persona),
243
- await editGuidelinesBlock({
244
- directory: input.directory,
245
- path: input.repository.prompts.editGuidelines,
246
- values,
247
- }),
248
- editOutputContract,
249
- ]
250
- .filter(Boolean)
251
- .join("\n\n");
252
- }
253
- export async function composeFindingValidationPrompt(input) {
254
- const values = { ...reviewValues(input), findings: input.findings };
255
- const task = await taskBlock({
256
- builtin: "review/finding-validation",
257
- customPath: input.repository.prompts.findingValidation,
258
- directory: input.directory,
259
- values,
260
- });
261
- return [
262
- task,
263
- ...(await sessionContextBlocks({
264
- directory: input.directory,
265
- includeReviewGuidelines: input.includeReviewGuidelines,
266
- includeSessionContext: input.includeSessionContext,
267
- repository: input.repository,
268
- reviewer: input.reviewer,
269
- values,
270
- })),
271
- findingValidationOutputContract,
272
- ]
273
- .filter(Boolean)
274
- .join("\n\n");
275
- }
276
- export async function composeCloseReconsiderationPrompt(input) {
277
- const values = {
278
- ...reviewValues(input),
279
- closeReason: input.closeReason ?? "",
280
- };
281
- const task = await taskBlock({
282
- builtin: "review/close-reconsideration",
283
- customPath: input.repository.prompts.closeReconsideration,
284
- directory: input.directory,
285
- values,
286
- });
287
- return [
288
- task,
289
- ...(await sessionContextBlocks({
290
- directory: input.directory,
291
- includeReviewGuidelines: input.includeReviewGuidelines,
292
- includeSessionContext: input.includeSessionContext,
293
- repository: input.repository,
294
- reviewer: input.reviewer,
295
- values,
296
- })),
297
- closeReconsiderationOutputContract,
298
- ]
299
- .filter(Boolean)
300
- .join("\n\n");
301
- }
302
- export async function composeRereviewCloseReconsiderationPrompt(input) {
303
- const values = {
304
- ...reviewValues(input),
305
- closeReason: input.closeReason ?? "",
306
- previousHeadSha: input.previousHeadSha,
307
- };
308
- const task = await taskBlock({
309
- builtin: "review/close-reconsideration",
310
- customPath: input.repository.prompts.closeReconsideration,
311
- directory: input.directory,
312
- values,
313
- });
314
- return [
315
- task,
316
- ...(await sessionContextBlocks({
317
- directory: input.directory,
318
- includeReviewGuidelines: input.includeReviewGuidelines,
319
- includeSessionContext: input.includeSessionContext,
320
- repository: input.repository,
321
- reviewer: input.reviewer,
322
- values,
323
- })),
324
- rereviewCloseReconsiderationOutputContract,
325
- ]
326
- .filter(Boolean)
327
- .join("\n\n");
328
- }
329
- export async function composeCiClassificationPrompt(input) {
330
- const values = {
331
- ...repositoryValues(input.repository),
332
- failedChecks: JSON.stringify(input.checks, null, 2),
333
- pr: String(input.pr),
334
- };
335
- const task = await taskBlock({
336
- builtin: "review/ci-classification",
337
- customPath: input.repository.prompts.ciClassification,
338
- directory: input.directory,
339
- values,
340
- });
341
- return [
342
- task,
343
- languageBlock(input.repository.language),
344
- ciClassificationOutputContract,
345
- ]
346
- .filter(Boolean)
347
- .join("\n\n");
348
- }
349
- export async function composeCiClassificationAfterEditPrompt(input) {
350
- const values = {
351
- ...repositoryValues(input.repository),
352
- cycle: String(input.cycle),
353
- failedChecks: JSON.stringify(input.checks, null, 2),
354
- headSha: input.headSha,
355
- jsonEncodedWorktreePath: JSON.stringify(input.worktreePath),
356
- previousHeadSha: input.previousHeadSha,
357
- pr: String(input.pr),
358
- worktreePath: input.worktreePath,
359
- };
360
- const task = await taskBlock({
361
- builtin: "merge/ci-classification",
362
- customPath: input.repository.prompts.ciClassificationAfterEdit ??
363
- input.repository.prompts.ciClassification,
364
- directory: input.directory,
365
- values,
366
- });
367
- return [
368
- task,
369
- languageBlock(input.repository.language),
370
- ciClassificationAfterEditOutputContract,
371
- ]
372
- .filter(Boolean)
373
- .join("\n\n");
374
- }
375
- async function composeTriageVotePrompt(input) {
376
- const values = triageValues(input);
377
- const task = await taskBlock({
378
- builtin: `triage/${input.builtin}`,
379
- customPath: input.customPath,
380
- directory: input.directory,
381
- values,
382
- });
383
- return [
384
- task,
385
- languageBlock(input.repository.language),
386
- personaBlock(input.voter.persona),
387
- input.outputContract,
388
- ]
389
- .filter(Boolean)
390
- .join("\n\n");
391
- }
392
- export async function composeTriageCreatePrPrompt(input) {
393
- const values = triageValues(input);
394
- const task = await taskBlock({
395
- builtin: "triage/create",
396
- customPath: input.repository.triage?.prompts.create,
397
- directory: input.directory,
398
- values,
399
- });
400
- const persona = input.repository.agents.triageCreator?.persona;
401
- return [
402
- task,
403
- languageBlock(input.repository.language),
404
- personaBlock(persona),
405
- await createGuidelinesBlock({
406
- directory: input.directory,
407
- path: input.repository.triage?.prompts.createGuidelines,
408
- values,
409
- }),
410
- triageCreatePrOutputContract,
411
- ]
412
- .filter(Boolean)
413
- .join("\n\n");
414
- }
415
- export async function composeTriageExistingPrPrompt(input) {
416
- return composeTriageVotePrompt({
417
- ...input,
418
- builtin: "existing-pr",
419
- customPath: input.repository.triage?.prompts.existingPr,
420
- outputContract: triageVoteOutputContract('"RELATED_PR_HANDLES_ISSUE" | "RELATED_PR_DOES_NOT_HANDLE_ISSUE"'),
421
- });
422
- }
423
- export async function composeTriageDuplicatePrompt(input) {
424
- return composeTriageVotePrompt({
425
- ...input,
426
- builtin: "duplicate",
427
- customPath: input.repository.triage?.prompts.duplicate,
428
- outputContract: triageDuplicateOutputContract,
429
- });
430
- }
431
- export async function composeTriageCategoryPrompt(input) {
432
- const categories = input.repository.triage?.categories ?? [];
433
- const votes = ["ASK", ...categories.map((category) => category.id)]
434
- .map((vote) => JSON.stringify(vote))
435
- .join(" | ");
436
- return composeTriageVotePrompt({
437
- ...input,
438
- builtin: "category",
439
- customPath: input.repository.triage?.prompts.category,
440
- outputContract: triageVoteOutputContract(votes),
441
- });
442
- }
443
- export async function composeTriageAcceptancePrompt(input) {
444
- return composeTriageVotePrompt({
445
- ...input,
446
- builtin: "acceptance",
447
- customPath: input.repository.triage?.prompts.acceptance,
448
- outputContract: triageVoteOutputContract('"YES" | "NO" | "INVALID" | "ASK"'),
449
- });
450
- }
451
- export async function composeTriageSignalPrompt(input) {
452
- return composeTriageVotePrompt({
453
- ...input,
454
- builtin: "signal",
455
- outputContract: triageSignalOutputContract,
456
- });
457
- }
458
- export async function composeTriageCommentClassificationPrompt(input) {
459
- return composeTriageVotePrompt({
460
- ...input,
461
- builtin: "comment-classification",
462
- customPath: input.repository.triage?.prompts.commentClassification,
463
- outputContract: triageCommentClassificationOutputContract,
464
- });
465
- }
466
- export async function composeTriageReconsiderPrompt(input) {
467
- return composeTriageVotePrompt({
468
- ...input,
469
- builtin: "reconsider",
470
- customPath: input.repository.triage?.prompts.reconsider,
471
- outputContract: triageVoteOutputContract('"YES" | "NO" | "ASK"'),
472
- });
473
- }