@catladder/cli 0.0.0-main-4fc3c2ec → 0.0.0-main-aafb3c3b
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.
|
@@ -6061,7 +6061,7 @@ exports.createJobsForAgentContext = createJobsForAgentContext;
|
|
|
6061
6061
|
"use strict";
|
|
6062
6062
|
|
|
6063
6063
|
// prompts.ts — MCP-only, DRY, review-first-then-push, CI diagnosis (no retries), self-mention guard,
|
|
6064
|
-
//
|
|
6064
|
+
// conversations-aware: always read the thread first (issues & MRs), reply inline, avoid duplicates.
|
|
6065
6065
|
// Prevents double-runs: event-triggered work cancels any running "agent-review" job on the MR's own pipeline.
|
|
6066
6066
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
6067
6067
|
exports.getMergeRequestPrompt = exports.getEventPrompt = void 0;
|
|
@@ -6085,6 +6085,30 @@ const goldenRules = ({ agentUserName }) => `
|
|
|
6085
6085
|
- Keep actions minimal and idempotent. Avoid duplicate comments or duplicate MRs.
|
|
6086
6086
|
- Use ONE stable \`source_branch\` per run; do not regenerate its name later.
|
|
6087
6087
|
`;
|
|
6088
|
+
/* ---------- NEW: conversation intake + threading rules ---------- */
|
|
6089
|
+
const conversationsIntake = ({ agentUserName }) => `
|
|
6090
|
+
## Conversations Intake & Threading (MANDATORY before acting)
|
|
6091
|
+
Always load and reason about the current conversation to avoid duplicates and to respond in the right place.
|
|
6092
|
+
|
|
6093
|
+
### What to fetch
|
|
6094
|
+
- **MRs**: Use \`mr_discussions({ projectId: $CI_PROJECT_ID, mergeRequestIid })\` to load all threads and notes.
|
|
6095
|
+
- **Issues**: If an issue-discussions/listing tool exists, use it. If not available in \`gitlab-mcp\`, rely on the **event payload** and **your last note ids** if present; otherwise post a single concise note acknowledging the limitation and proceed.
|
|
6096
|
+
|
|
6097
|
+
### How to use it
|
|
6098
|
+
1) **Detect review/answer context**:
|
|
6099
|
+
- Identify the **latest human note** in the thread (exclude notes authored by "${agentUserName}").
|
|
6100
|
+
- If the latest human note **replies to you** (mentions you or is in a discussion you started), reply **in the same discussion**.
|
|
6101
|
+
2) **De-duplication**:
|
|
6102
|
+
- If your most recent message is the **last message overall** and **no one else replied** since, prefer **updating your last note** instead of posting a new one:
|
|
6103
|
+
- Use \`update_merge_request_note\` or \`update_issue_note\` accordingly.
|
|
6104
|
+
3) **Reply placement**:
|
|
6105
|
+
- For MR code discussions: reply **inline in the same discussion** (preserve thread context).
|
|
6106
|
+
- For general/MR overview threads: add a single consolidated reply (avoid multiple scattered notes).
|
|
6107
|
+
4) **Sanitize before write**:
|
|
6108
|
+
- Apply the Self-mention Guard, then post.
|
|
6109
|
+
5) **If conversations list is unavailable**:
|
|
6110
|
+
- Post one short note: that you cannot fetch the full conversation due to missing MCP capability, then proceed minimally (no spam).
|
|
6111
|
+
`;
|
|
6088
6112
|
const selfMentionGuard = ({ agentUserName }) => `
|
|
6089
6113
|
## Self-mention Guard (mandatory preflight for ALL writes)
|
|
6090
6114
|
Before ANY call that writes text (comment/create/update MR/issue/commit message), sanitize the text:
|
|
@@ -6125,11 +6149,11 @@ const mcpOnly = () => `
|
|
|
6125
6149
|
- list_issues({ projectId, state?: "opened"|"closed", scope?: "all"|... })
|
|
6126
6150
|
|
|
6127
6151
|
- **Branch & Files**
|
|
6128
|
-
- create_branch({ projectId, branchName, ref })
|
|
6152
|
+
- create_branch({ projectId, branchName, ref })
|
|
6129
6153
|
- push_files({ projectId, branch, commitMessage, files: [{ filePath, content }] })
|
|
6130
6154
|
- create_or_update_file({ projectId, branch, filePath, content, commitMessage })
|
|
6131
6155
|
- get_file_contents({ projectId, ref, path })
|
|
6132
|
-
- get_branch_diffs({ projectId, from, to })
|
|
6156
|
+
- get_branch_diffs({ projectId, from, to })
|
|
6133
6157
|
|
|
6134
6158
|
- **Merge Requests**
|
|
6135
6159
|
- create_merge_request({ projectId, sourceBranch, targetBranch, title, description, assigneeUsernames?: string[] })
|
|
@@ -6164,8 +6188,7 @@ From \`event_json\`, extract:
|
|
|
6164
6188
|
- note_id if present (\`#note_<id>\`)
|
|
6165
6189
|
- description/body text, state, author \`user_username\`, timestamps
|
|
6166
6190
|
- project id/path; detect default branch via \`get_merge_request\`/context as needed
|
|
6167
|
-
|
|
6168
|
-
If any key is missing, choose the safest minimal action or briefly explain via a comment.
|
|
6191
|
+
- If available: the discussion id / thread context of the note to enable inline replies.
|
|
6169
6192
|
`;
|
|
6170
6193
|
/* Helper used by Single-Runner Guard and Review-on-Demand to find the MR’s own pipeline */
|
|
6171
6194
|
const resolveMrPipeline = () => `
|
|
@@ -6181,7 +6204,6 @@ Given \`mr_iid\`:
|
|
|
6181
6204
|
4) The chosen pipeline becomes \`mr_pipeline_id\`. Use it for all job queries/plays/cancels related to this MR.
|
|
6182
6205
|
- If no pipeline is found, post a short MR note explaining that no pipeline was located for the current MR head and proceed with review actions without CI job control.
|
|
6183
6206
|
`;
|
|
6184
|
-
// Updated: operate on the MR’s pipeline, not the event pipeline
|
|
6185
6207
|
const singleRunnerGuard = () => `
|
|
6186
6208
|
## Single-Runner Guard (event-triggered work on an existing MR)
|
|
6187
6209
|
Before entering MR Review Mode from an event:
|
|
@@ -6223,6 +6245,7 @@ If the issue/note text **asks for a review** (case-insensitive tokens like: "rev
|
|
|
6223
6245
|
- \`list_pipeline_jobs({ projectId: $CI_PROJECT_ID, pipelineId: mr_pipeline_id })\`.
|
|
6224
6246
|
- If any job has \`status = "manual"\` **and** its \`name\` ends with "agent-review":
|
|
6225
6247
|
- Trigger via \`play_pipeline_job({ projectId: $CI_PROJECT_ID, jobId })\`.
|
|
6248
|
+
- **Conversations Intake**: run the section above to determine **where** to post the confirmation (prefer replying in the same thread that requested review).
|
|
6226
6249
|
- Post a short comment confirming you triggered the review job (sanitize).
|
|
6227
6250
|
- **Stop** further review actions.
|
|
6228
6251
|
|
|
@@ -6236,22 +6259,25 @@ const eventWorkflow = ({ agentUserName }) => `
|
|
|
6236
6259
|
## High-Reliability Workflow (sequence + postconditions)
|
|
6237
6260
|
Follow this order for any change work:
|
|
6238
6261
|
|
|
6262
|
+
0) **Conversations Intake (MANDATORY)**:
|
|
6263
|
+
- For MR targets: call \`mr_discussions\` and apply the rules in **Conversations Intake & Threading**.
|
|
6264
|
+
- For issue targets: attempt to load notes if supported; otherwise rely on event context and post one concise note acknowledging the limitation.
|
|
6265
|
+
|
|
6239
6266
|
1) **Acknowledge** with a short comment on the issue/MR thread (\`create_note\`), **unless the last actor is you**.
|
|
6240
6267
|
2) **Discover default branch** (e.g., "main") — infer from repo/MR context if needed.
|
|
6241
6268
|
3) **Create a working branch** from default (stable name, e.g., \`fix/issue-<iid>-<slug>\` or \`feat/issue-<iid>-<slug>\`) via \`create_branch\`.
|
|
6242
6269
|
4) **Write changes → commit → push to remote branch** via \`push_files\` (or \`create_or_update_file\`).
|
|
6243
6270
|
5) **Verify push landed**:
|
|
6244
|
-
- Fetch latest state
|
|
6245
|
-
- Compare default vs \`source_branch\` via \`get_branch_diffs({ from: "<default>", to: "<source>" })\` and ensure there are diffs.
|
|
6271
|
+
- Fetch latest state and ensure diffs via \`get_branch_diffs({ from: "<default>", to: "<source>" })\`.
|
|
6246
6272
|
6) **Create or update MR** ONLY if there is a non-empty diff via \`create_merge_request\`.
|
|
6247
6273
|
- Include \`Closes #<issue_iid>\` in MR description when applicable.
|
|
6248
6274
|
- **Assign the MR to yourself**: \`assigneeUsernames: ["${agentUserName}"]\`.
|
|
6249
|
-
7) **Follow-up comment** with branch name, any commit short SHA you can obtain, files changed count (approx by diffs), and MR link via \`create_note\`, **unless the last actor is you**.
|
|
6275
|
+
7) **Follow-up comment** with branch name, any commit short SHA you can obtain, files changed count (approx by diffs), and MR link via \`create_note\`, **unless the last actor is you**. Place this **in the relevant conversation thread** (see Intake rules).
|
|
6250
6276
|
8) **If verification fails**:
|
|
6251
6277
|
- Do NOT create the MR.
|
|
6252
6278
|
- Comment the exact failure and retry once with a fresh branch name. If still failing, comment and stop.
|
|
6253
6279
|
|
|
6254
|
-
For Q&A-only (no code changes),
|
|
6280
|
+
For Q&A-only (no code changes), run **Conversations Intake** first, then post a single concise, helpful answer **in the correct thread** (sanitize).
|
|
6255
6281
|
`;
|
|
6256
6282
|
/* ---------- MR-review specific (shared with both prompts) ---------- */
|
|
6257
6283
|
const mrScope = ({ agentUserName }) => `
|
|
@@ -6268,7 +6294,7 @@ Follow this sequence with verification at each step:
|
|
|
6268
6294
|
1) **Collect context**
|
|
6269
6295
|
- Get MR metadata via \`get_merge_request({ projectId: $CI_PROJECT_ID, mergeRequestIid })\`.
|
|
6270
6296
|
- Fetch the full changeset/diffs via \`get_merge_request_diffs\` (or \`list_merge_request_diffs\`) and open discussions via \`mr_discussions\`.
|
|
6271
|
-
-
|
|
6297
|
+
- **Conversations Intake**: analyze discussions to find latest human notes, detect replies to the agent, and decide between inline reply vs updating your prior note.
|
|
6272
6298
|
|
|
6273
6299
|
2) **Code review**
|
|
6274
6300
|
- Identify required changes (bugs, tests, style, security, perf, docs).
|
|
@@ -6282,12 +6308,12 @@ Follow this sequence with verification at each step:
|
|
|
6282
6308
|
- Apply minimal, safe changes; keep commits small and clear.
|
|
6283
6309
|
- **Push** to the MR's **source branch** via \`push_files\` (or \`create_or_update_file\`).
|
|
6284
6310
|
- **Verify push landed** using \`get_branch_diffs({ from: "<target_branch>", to: "<source_branch>" })\` and ensure there are diffs.
|
|
6285
|
-
- Post a follow-up MR note summarizing what changed and why (sanitize).
|
|
6311
|
+
- Post a follow-up MR note summarizing what changed and why, **in the appropriate thread** (sanitize).
|
|
6286
6312
|
`;
|
|
6287
6313
|
const ciInspection = () => `
|
|
6288
6314
|
4) **CI jobs (diagnose only; no job retries)**
|
|
6289
|
-
-
|
|
6290
|
-
- If you
|
|
6315
|
+
- Prefer the **MR pipeline** (not the event pipeline).
|
|
6316
|
+
- If you have \`mr_pipeline_id\` (from **Resolve MR Pipeline**):
|
|
6291
6317
|
- \`list_pipeline_jobs({ projectId: $CI_PROJECT_ID, pipelineId: mr_pipeline_id })\`.
|
|
6292
6318
|
- Consider **only** jobs with \`status = "failed"\` and \`allow_failure = false\`.
|
|
6293
6319
|
- For each such job:
|
|
@@ -6328,11 +6354,12 @@ $(cat $TRIGGER_PAYLOAD)
|
|
|
6328
6354
|
${identity(ctx)}
|
|
6329
6355
|
${goldenRules(ctx)}
|
|
6330
6356
|
${selfMentionGuard(ctx)}
|
|
6357
|
+
${conversationsIntake(ctx)} <!-- NEW: mandatory before acting -->
|
|
6331
6358
|
${eventSelfParse()}
|
|
6332
|
-
${resolveMrPipeline()}
|
|
6333
|
-
${singleRunnerGuard()}
|
|
6359
|
+
${resolveMrPipeline()} <!-- used by review/cancel paths -->
|
|
6360
|
+
${singleRunnerGuard()} <!-- operates on MR pipeline, not event pipeline -->
|
|
6334
6361
|
${reviewOnDemandFromEvents()}
|
|
6335
|
-
${mrReviewBundle(ctx)}
|
|
6362
|
+
${mrReviewBundle(ctx)} <!-- agent can execute when review intent is true -->
|
|
6336
6363
|
${eventWorkflow(ctx)}
|
|
6337
6364
|
${commentGuidelines()}
|
|
6338
6365
|
${mcpOnly()}
|
|
@@ -6352,6 +6379,7 @@ description: $CI_MERGE_REQUEST_DESCRIPTION
|
|
|
6352
6379
|
${mrScope(ctx)}
|
|
6353
6380
|
${goldenRules(ctx)}
|
|
6354
6381
|
${selfMentionGuard(ctx)}
|
|
6382
|
+
${conversationsIntake(ctx)} <!-- NEW: always read MR discussions -->
|
|
6355
6383
|
${mrWorkflow()}
|
|
6356
6384
|
${ciInspection()}
|
|
6357
6385
|
${commentGuidelines()}
|
|
@@ -9289,7 +9289,7 @@ exports.createJobsForAgentContext = createJobsForAgentContext;
|
|
|
9289
9289
|
"use strict";
|
|
9290
9290
|
|
|
9291
9291
|
// prompts.ts — MCP-only, DRY, review-first-then-push, CI diagnosis (no retries), self-mention guard,
|
|
9292
|
-
//
|
|
9292
|
+
// conversations-aware: always read the thread first (issues & MRs), reply inline, avoid duplicates.
|
|
9293
9293
|
// Prevents double-runs: event-triggered work cancels any running "agent-review" job on the MR's own pipeline.
|
|
9294
9294
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
9295
9295
|
exports.getMergeRequestPrompt = exports.getEventPrompt = void 0;
|
|
@@ -9313,6 +9313,30 @@ const goldenRules = ({ agentUserName }) => `
|
|
|
9313
9313
|
- Keep actions minimal and idempotent. Avoid duplicate comments or duplicate MRs.
|
|
9314
9314
|
- Use ONE stable \`source_branch\` per run; do not regenerate its name later.
|
|
9315
9315
|
`;
|
|
9316
|
+
/* ---------- NEW: conversation intake + threading rules ---------- */
|
|
9317
|
+
const conversationsIntake = ({ agentUserName }) => `
|
|
9318
|
+
## Conversations Intake & Threading (MANDATORY before acting)
|
|
9319
|
+
Always load and reason about the current conversation to avoid duplicates and to respond in the right place.
|
|
9320
|
+
|
|
9321
|
+
### What to fetch
|
|
9322
|
+
- **MRs**: Use \`mr_discussions({ projectId: $CI_PROJECT_ID, mergeRequestIid })\` to load all threads and notes.
|
|
9323
|
+
- **Issues**: If an issue-discussions/listing tool exists, use it. If not available in \`gitlab-mcp\`, rely on the **event payload** and **your last note ids** if present; otherwise post a single concise note acknowledging the limitation and proceed.
|
|
9324
|
+
|
|
9325
|
+
### How to use it
|
|
9326
|
+
1) **Detect review/answer context**:
|
|
9327
|
+
- Identify the **latest human note** in the thread (exclude notes authored by "${agentUserName}").
|
|
9328
|
+
- If the latest human note **replies to you** (mentions you or is in a discussion you started), reply **in the same discussion**.
|
|
9329
|
+
2) **De-duplication**:
|
|
9330
|
+
- If your most recent message is the **last message overall** and **no one else replied** since, prefer **updating your last note** instead of posting a new one:
|
|
9331
|
+
- Use \`update_merge_request_note\` or \`update_issue_note\` accordingly.
|
|
9332
|
+
3) **Reply placement**:
|
|
9333
|
+
- For MR code discussions: reply **inline in the same discussion** (preserve thread context).
|
|
9334
|
+
- For general/MR overview threads: add a single consolidated reply (avoid multiple scattered notes).
|
|
9335
|
+
4) **Sanitize before write**:
|
|
9336
|
+
- Apply the Self-mention Guard, then post.
|
|
9337
|
+
5) **If conversations list is unavailable**:
|
|
9338
|
+
- Post one short note: that you cannot fetch the full conversation due to missing MCP capability, then proceed minimally (no spam).
|
|
9339
|
+
`;
|
|
9316
9340
|
const selfMentionGuard = ({ agentUserName }) => `
|
|
9317
9341
|
## Self-mention Guard (mandatory preflight for ALL writes)
|
|
9318
9342
|
Before ANY call that writes text (comment/create/update MR/issue/commit message), sanitize the text:
|
|
@@ -9353,11 +9377,11 @@ const mcpOnly = () => `
|
|
|
9353
9377
|
- list_issues({ projectId, state?: "opened"|"closed", scope?: "all"|... })
|
|
9354
9378
|
|
|
9355
9379
|
- **Branch & Files**
|
|
9356
|
-
- create_branch({ projectId, branchName, ref })
|
|
9380
|
+
- create_branch({ projectId, branchName, ref })
|
|
9357
9381
|
- push_files({ projectId, branch, commitMessage, files: [{ filePath, content }] })
|
|
9358
9382
|
- create_or_update_file({ projectId, branch, filePath, content, commitMessage })
|
|
9359
9383
|
- get_file_contents({ projectId, ref, path })
|
|
9360
|
-
- get_branch_diffs({ projectId, from, to })
|
|
9384
|
+
- get_branch_diffs({ projectId, from, to })
|
|
9361
9385
|
|
|
9362
9386
|
- **Merge Requests**
|
|
9363
9387
|
- create_merge_request({ projectId, sourceBranch, targetBranch, title, description, assigneeUsernames?: string[] })
|
|
@@ -9392,8 +9416,7 @@ From \`event_json\`, extract:
|
|
|
9392
9416
|
- note_id if present (\`#note_<id>\`)
|
|
9393
9417
|
- description/body text, state, author \`user_username\`, timestamps
|
|
9394
9418
|
- project id/path; detect default branch via \`get_merge_request\`/context as needed
|
|
9395
|
-
|
|
9396
|
-
If any key is missing, choose the safest minimal action or briefly explain via a comment.
|
|
9419
|
+
- If available: the discussion id / thread context of the note to enable inline replies.
|
|
9397
9420
|
`;
|
|
9398
9421
|
/* Helper used by Single-Runner Guard and Review-on-Demand to find the MR’s own pipeline */
|
|
9399
9422
|
const resolveMrPipeline = () => `
|
|
@@ -9409,7 +9432,6 @@ Given \`mr_iid\`:
|
|
|
9409
9432
|
4) The chosen pipeline becomes \`mr_pipeline_id\`. Use it for all job queries/plays/cancels related to this MR.
|
|
9410
9433
|
- If no pipeline is found, post a short MR note explaining that no pipeline was located for the current MR head and proceed with review actions without CI job control.
|
|
9411
9434
|
`;
|
|
9412
|
-
// Updated: operate on the MR’s pipeline, not the event pipeline
|
|
9413
9435
|
const singleRunnerGuard = () => `
|
|
9414
9436
|
## Single-Runner Guard (event-triggered work on an existing MR)
|
|
9415
9437
|
Before entering MR Review Mode from an event:
|
|
@@ -9451,6 +9473,7 @@ If the issue/note text **asks for a review** (case-insensitive tokens like: "rev
|
|
|
9451
9473
|
- \`list_pipeline_jobs({ projectId: $CI_PROJECT_ID, pipelineId: mr_pipeline_id })\`.
|
|
9452
9474
|
- If any job has \`status = "manual"\` **and** its \`name\` ends with "agent-review":
|
|
9453
9475
|
- Trigger via \`play_pipeline_job({ projectId: $CI_PROJECT_ID, jobId })\`.
|
|
9476
|
+
- **Conversations Intake**: run the section above to determine **where** to post the confirmation (prefer replying in the same thread that requested review).
|
|
9454
9477
|
- Post a short comment confirming you triggered the review job (sanitize).
|
|
9455
9478
|
- **Stop** further review actions.
|
|
9456
9479
|
|
|
@@ -9464,22 +9487,25 @@ const eventWorkflow = ({ agentUserName }) => `
|
|
|
9464
9487
|
## High-Reliability Workflow (sequence + postconditions)
|
|
9465
9488
|
Follow this order for any change work:
|
|
9466
9489
|
|
|
9490
|
+
0) **Conversations Intake (MANDATORY)**:
|
|
9491
|
+
- For MR targets: call \`mr_discussions\` and apply the rules in **Conversations Intake & Threading**.
|
|
9492
|
+
- For issue targets: attempt to load notes if supported; otherwise rely on event context and post one concise note acknowledging the limitation.
|
|
9493
|
+
|
|
9467
9494
|
1) **Acknowledge** with a short comment on the issue/MR thread (\`create_note\`), **unless the last actor is you**.
|
|
9468
9495
|
2) **Discover default branch** (e.g., "main") — infer from repo/MR context if needed.
|
|
9469
9496
|
3) **Create a working branch** from default (stable name, e.g., \`fix/issue-<iid>-<slug>\` or \`feat/issue-<iid>-<slug>\`) via \`create_branch\`.
|
|
9470
9497
|
4) **Write changes → commit → push to remote branch** via \`push_files\` (or \`create_or_update_file\`).
|
|
9471
9498
|
5) **Verify push landed**:
|
|
9472
|
-
- Fetch latest state
|
|
9473
|
-
- Compare default vs \`source_branch\` via \`get_branch_diffs({ from: "<default>", to: "<source>" })\` and ensure there are diffs.
|
|
9499
|
+
- Fetch latest state and ensure diffs via \`get_branch_diffs({ from: "<default>", to: "<source>" })\`.
|
|
9474
9500
|
6) **Create or update MR** ONLY if there is a non-empty diff via \`create_merge_request\`.
|
|
9475
9501
|
- Include \`Closes #<issue_iid>\` in MR description when applicable.
|
|
9476
9502
|
- **Assign the MR to yourself**: \`assigneeUsernames: ["${agentUserName}"]\`.
|
|
9477
|
-
7) **Follow-up comment** with branch name, any commit short SHA you can obtain, files changed count (approx by diffs), and MR link via \`create_note\`, **unless the last actor is you**.
|
|
9503
|
+
7) **Follow-up comment** with branch name, any commit short SHA you can obtain, files changed count (approx by diffs), and MR link via \`create_note\`, **unless the last actor is you**. Place this **in the relevant conversation thread** (see Intake rules).
|
|
9478
9504
|
8) **If verification fails**:
|
|
9479
9505
|
- Do NOT create the MR.
|
|
9480
9506
|
- Comment the exact failure and retry once with a fresh branch name. If still failing, comment and stop.
|
|
9481
9507
|
|
|
9482
|
-
For Q&A-only (no code changes),
|
|
9508
|
+
For Q&A-only (no code changes), run **Conversations Intake** first, then post a single concise, helpful answer **in the correct thread** (sanitize).
|
|
9483
9509
|
`;
|
|
9484
9510
|
/* ---------- MR-review specific (shared with both prompts) ---------- */
|
|
9485
9511
|
const mrScope = ({ agentUserName }) => `
|
|
@@ -9496,7 +9522,7 @@ Follow this sequence with verification at each step:
|
|
|
9496
9522
|
1) **Collect context**
|
|
9497
9523
|
- Get MR metadata via \`get_merge_request({ projectId: $CI_PROJECT_ID, mergeRequestIid })\`.
|
|
9498
9524
|
- Fetch the full changeset/diffs via \`get_merge_request_diffs\` (or \`list_merge_request_diffs\`) and open discussions via \`mr_discussions\`.
|
|
9499
|
-
-
|
|
9525
|
+
- **Conversations Intake**: analyze discussions to find latest human notes, detect replies to the agent, and decide between inline reply vs updating your prior note.
|
|
9500
9526
|
|
|
9501
9527
|
2) **Code review**
|
|
9502
9528
|
- Identify required changes (bugs, tests, style, security, perf, docs).
|
|
@@ -9510,12 +9536,12 @@ Follow this sequence with verification at each step:
|
|
|
9510
9536
|
- Apply minimal, safe changes; keep commits small and clear.
|
|
9511
9537
|
- **Push** to the MR's **source branch** via \`push_files\` (or \`create_or_update_file\`).
|
|
9512
9538
|
- **Verify push landed** using \`get_branch_diffs({ from: "<target_branch>", to: "<source_branch>" })\` and ensure there are diffs.
|
|
9513
|
-
- Post a follow-up MR note summarizing what changed and why (sanitize).
|
|
9539
|
+
- Post a follow-up MR note summarizing what changed and why, **in the appropriate thread** (sanitize).
|
|
9514
9540
|
`;
|
|
9515
9541
|
const ciInspection = () => `
|
|
9516
9542
|
4) **CI jobs (diagnose only; no job retries)**
|
|
9517
|
-
-
|
|
9518
|
-
- If you
|
|
9543
|
+
- Prefer the **MR pipeline** (not the event pipeline).
|
|
9544
|
+
- If you have \`mr_pipeline_id\` (from **Resolve MR Pipeline**):
|
|
9519
9545
|
- \`list_pipeline_jobs({ projectId: $CI_PROJECT_ID, pipelineId: mr_pipeline_id })\`.
|
|
9520
9546
|
- Consider **only** jobs with \`status = "failed"\` and \`allow_failure = false\`.
|
|
9521
9547
|
- For each such job:
|
|
@@ -9556,11 +9582,12 @@ $(cat $TRIGGER_PAYLOAD)
|
|
|
9556
9582
|
${identity(ctx)}
|
|
9557
9583
|
${goldenRules(ctx)}
|
|
9558
9584
|
${selfMentionGuard(ctx)}
|
|
9585
|
+
${conversationsIntake(ctx)} <!-- NEW: mandatory before acting -->
|
|
9559
9586
|
${eventSelfParse()}
|
|
9560
|
-
${resolveMrPipeline()}
|
|
9561
|
-
${singleRunnerGuard()}
|
|
9587
|
+
${resolveMrPipeline()} <!-- used by review/cancel paths -->
|
|
9588
|
+
${singleRunnerGuard()} <!-- operates on MR pipeline, not event pipeline -->
|
|
9562
9589
|
${reviewOnDemandFromEvents()}
|
|
9563
|
-
${mrReviewBundle(ctx)}
|
|
9590
|
+
${mrReviewBundle(ctx)} <!-- agent can execute when review intent is true -->
|
|
9564
9591
|
${eventWorkflow(ctx)}
|
|
9565
9592
|
${commentGuidelines()}
|
|
9566
9593
|
${mcpOnly()}
|
|
@@ -9580,6 +9607,7 @@ description: $CI_MERGE_REQUEST_DESCRIPTION
|
|
|
9580
9607
|
${mrScope(ctx)}
|
|
9581
9608
|
${goldenRules(ctx)}
|
|
9582
9609
|
${selfMentionGuard(ctx)}
|
|
9610
|
+
${conversationsIntake(ctx)} <!-- NEW: always read MR discussions -->
|
|
9583
9611
|
${mrWorkflow()}
|
|
9584
9612
|
${ciInspection()}
|
|
9585
9613
|
${commentGuidelines()}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// prompts.ts — MCP-only, DRY, review-first-then-push, CI diagnosis (no retries), self-mention guard,
|
|
3
|
-
//
|
|
3
|
+
// conversations-aware: always read the thread first (issues & MRs), reply inline, avoid duplicates.
|
|
4
4
|
// Prevents double-runs: event-triggered work cancels any running "agent-review" job on the MR's own pipeline.
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getMergeRequestPrompt = exports.getEventPrompt = void 0;
|
|
@@ -24,6 +24,30 @@ const goldenRules = ({ agentUserName }) => `
|
|
|
24
24
|
- Keep actions minimal and idempotent. Avoid duplicate comments or duplicate MRs.
|
|
25
25
|
- Use ONE stable \`source_branch\` per run; do not regenerate its name later.
|
|
26
26
|
`;
|
|
27
|
+
/* ---------- NEW: conversation intake + threading rules ---------- */
|
|
28
|
+
const conversationsIntake = ({ agentUserName }) => `
|
|
29
|
+
## Conversations Intake & Threading (MANDATORY before acting)
|
|
30
|
+
Always load and reason about the current conversation to avoid duplicates and to respond in the right place.
|
|
31
|
+
|
|
32
|
+
### What to fetch
|
|
33
|
+
- **MRs**: Use \`mr_discussions({ projectId: $CI_PROJECT_ID, mergeRequestIid })\` to load all threads and notes.
|
|
34
|
+
- **Issues**: If an issue-discussions/listing tool exists, use it. If not available in \`gitlab-mcp\`, rely on the **event payload** and **your last note ids** if present; otherwise post a single concise note acknowledging the limitation and proceed.
|
|
35
|
+
|
|
36
|
+
### How to use it
|
|
37
|
+
1) **Detect review/answer context**:
|
|
38
|
+
- Identify the **latest human note** in the thread (exclude notes authored by "${agentUserName}").
|
|
39
|
+
- If the latest human note **replies to you** (mentions you or is in a discussion you started), reply **in the same discussion**.
|
|
40
|
+
2) **De-duplication**:
|
|
41
|
+
- If your most recent message is the **last message overall** and **no one else replied** since, prefer **updating your last note** instead of posting a new one:
|
|
42
|
+
- Use \`update_merge_request_note\` or \`update_issue_note\` accordingly.
|
|
43
|
+
3) **Reply placement**:
|
|
44
|
+
- For MR code discussions: reply **inline in the same discussion** (preserve thread context).
|
|
45
|
+
- For general/MR overview threads: add a single consolidated reply (avoid multiple scattered notes).
|
|
46
|
+
4) **Sanitize before write**:
|
|
47
|
+
- Apply the Self-mention Guard, then post.
|
|
48
|
+
5) **If conversations list is unavailable**:
|
|
49
|
+
- Post one short note: that you cannot fetch the full conversation due to missing MCP capability, then proceed minimally (no spam).
|
|
50
|
+
`;
|
|
27
51
|
const selfMentionGuard = ({ agentUserName }) => `
|
|
28
52
|
## Self-mention Guard (mandatory preflight for ALL writes)
|
|
29
53
|
Before ANY call that writes text (comment/create/update MR/issue/commit message), sanitize the text:
|
|
@@ -64,11 +88,11 @@ const mcpOnly = () => `
|
|
|
64
88
|
- list_issues({ projectId, state?: "opened"|"closed", scope?: "all"|... })
|
|
65
89
|
|
|
66
90
|
- **Branch & Files**
|
|
67
|
-
- create_branch({ projectId, branchName, ref })
|
|
91
|
+
- create_branch({ projectId, branchName, ref })
|
|
68
92
|
- push_files({ projectId, branch, commitMessage, files: [{ filePath, content }] })
|
|
69
93
|
- create_or_update_file({ projectId, branch, filePath, content, commitMessage })
|
|
70
94
|
- get_file_contents({ projectId, ref, path })
|
|
71
|
-
- get_branch_diffs({ projectId, from, to })
|
|
95
|
+
- get_branch_diffs({ projectId, from, to })
|
|
72
96
|
|
|
73
97
|
- **Merge Requests**
|
|
74
98
|
- create_merge_request({ projectId, sourceBranch, targetBranch, title, description, assigneeUsernames?: string[] })
|
|
@@ -103,8 +127,7 @@ From \`event_json\`, extract:
|
|
|
103
127
|
- note_id if present (\`#note_<id>\`)
|
|
104
128
|
- description/body text, state, author \`user_username\`, timestamps
|
|
105
129
|
- project id/path; detect default branch via \`get_merge_request\`/context as needed
|
|
106
|
-
|
|
107
|
-
If any key is missing, choose the safest minimal action or briefly explain via a comment.
|
|
130
|
+
- If available: the discussion id / thread context of the note to enable inline replies.
|
|
108
131
|
`;
|
|
109
132
|
/* Helper used by Single-Runner Guard and Review-on-Demand to find the MR’s own pipeline */
|
|
110
133
|
const resolveMrPipeline = () => `
|
|
@@ -120,7 +143,6 @@ Given \`mr_iid\`:
|
|
|
120
143
|
4) The chosen pipeline becomes \`mr_pipeline_id\`. Use it for all job queries/plays/cancels related to this MR.
|
|
121
144
|
- If no pipeline is found, post a short MR note explaining that no pipeline was located for the current MR head and proceed with review actions without CI job control.
|
|
122
145
|
`;
|
|
123
|
-
// Updated: operate on the MR’s pipeline, not the event pipeline
|
|
124
146
|
const singleRunnerGuard = () => `
|
|
125
147
|
## Single-Runner Guard (event-triggered work on an existing MR)
|
|
126
148
|
Before entering MR Review Mode from an event:
|
|
@@ -162,6 +184,7 @@ If the issue/note text **asks for a review** (case-insensitive tokens like: "rev
|
|
|
162
184
|
- \`list_pipeline_jobs({ projectId: $CI_PROJECT_ID, pipelineId: mr_pipeline_id })\`.
|
|
163
185
|
- If any job has \`status = "manual"\` **and** its \`name\` ends with "agent-review":
|
|
164
186
|
- Trigger via \`play_pipeline_job({ projectId: $CI_PROJECT_ID, jobId })\`.
|
|
187
|
+
- **Conversations Intake**: run the section above to determine **where** to post the confirmation (prefer replying in the same thread that requested review).
|
|
165
188
|
- Post a short comment confirming you triggered the review job (sanitize).
|
|
166
189
|
- **Stop** further review actions.
|
|
167
190
|
|
|
@@ -175,22 +198,25 @@ const eventWorkflow = ({ agentUserName }) => `
|
|
|
175
198
|
## High-Reliability Workflow (sequence + postconditions)
|
|
176
199
|
Follow this order for any change work:
|
|
177
200
|
|
|
201
|
+
0) **Conversations Intake (MANDATORY)**:
|
|
202
|
+
- For MR targets: call \`mr_discussions\` and apply the rules in **Conversations Intake & Threading**.
|
|
203
|
+
- For issue targets: attempt to load notes if supported; otherwise rely on event context and post one concise note acknowledging the limitation.
|
|
204
|
+
|
|
178
205
|
1) **Acknowledge** with a short comment on the issue/MR thread (\`create_note\`), **unless the last actor is you**.
|
|
179
206
|
2) **Discover default branch** (e.g., "main") — infer from repo/MR context if needed.
|
|
180
207
|
3) **Create a working branch** from default (stable name, e.g., \`fix/issue-<iid>-<slug>\` or \`feat/issue-<iid>-<slug>\`) via \`create_branch\`.
|
|
181
208
|
4) **Write changes → commit → push to remote branch** via \`push_files\` (or \`create_or_update_file\`).
|
|
182
209
|
5) **Verify push landed**:
|
|
183
|
-
- Fetch latest state
|
|
184
|
-
- Compare default vs \`source_branch\` via \`get_branch_diffs({ from: "<default>", to: "<source>" })\` and ensure there are diffs.
|
|
210
|
+
- Fetch latest state and ensure diffs via \`get_branch_diffs({ from: "<default>", to: "<source>" })\`.
|
|
185
211
|
6) **Create or update MR** ONLY if there is a non-empty diff via \`create_merge_request\`.
|
|
186
212
|
- Include \`Closes #<issue_iid>\` in MR description when applicable.
|
|
187
213
|
- **Assign the MR to yourself**: \`assigneeUsernames: ["${agentUserName}"]\`.
|
|
188
|
-
7) **Follow-up comment** with branch name, any commit short SHA you can obtain, files changed count (approx by diffs), and MR link via \`create_note\`, **unless the last actor is you**.
|
|
214
|
+
7) **Follow-up comment** with branch name, any commit short SHA you can obtain, files changed count (approx by diffs), and MR link via \`create_note\`, **unless the last actor is you**. Place this **in the relevant conversation thread** (see Intake rules).
|
|
189
215
|
8) **If verification fails**:
|
|
190
216
|
- Do NOT create the MR.
|
|
191
217
|
- Comment the exact failure and retry once with a fresh branch name. If still failing, comment and stop.
|
|
192
218
|
|
|
193
|
-
For Q&A-only (no code changes),
|
|
219
|
+
For Q&A-only (no code changes), run **Conversations Intake** first, then post a single concise, helpful answer **in the correct thread** (sanitize).
|
|
194
220
|
`;
|
|
195
221
|
/* ---------- MR-review specific (shared with both prompts) ---------- */
|
|
196
222
|
const mrScope = ({ agentUserName }) => `
|
|
@@ -207,7 +233,7 @@ Follow this sequence with verification at each step:
|
|
|
207
233
|
1) **Collect context**
|
|
208
234
|
- Get MR metadata via \`get_merge_request({ projectId: $CI_PROJECT_ID, mergeRequestIid })\`.
|
|
209
235
|
- Fetch the full changeset/diffs via \`get_merge_request_diffs\` (or \`list_merge_request_diffs\`) and open discussions via \`mr_discussions\`.
|
|
210
|
-
-
|
|
236
|
+
- **Conversations Intake**: analyze discussions to find latest human notes, detect replies to the agent, and decide between inline reply vs updating your prior note.
|
|
211
237
|
|
|
212
238
|
2) **Code review**
|
|
213
239
|
- Identify required changes (bugs, tests, style, security, perf, docs).
|
|
@@ -221,12 +247,12 @@ Follow this sequence with verification at each step:
|
|
|
221
247
|
- Apply minimal, safe changes; keep commits small and clear.
|
|
222
248
|
- **Push** to the MR's **source branch** via \`push_files\` (or \`create_or_update_file\`).
|
|
223
249
|
- **Verify push landed** using \`get_branch_diffs({ from: "<target_branch>", to: "<source_branch>" })\` and ensure there are diffs.
|
|
224
|
-
- Post a follow-up MR note summarizing what changed and why (sanitize).
|
|
250
|
+
- Post a follow-up MR note summarizing what changed and why, **in the appropriate thread** (sanitize).
|
|
225
251
|
`;
|
|
226
252
|
const ciInspection = () => `
|
|
227
253
|
4) **CI jobs (diagnose only; no job retries)**
|
|
228
|
-
-
|
|
229
|
-
- If you
|
|
254
|
+
- Prefer the **MR pipeline** (not the event pipeline).
|
|
255
|
+
- If you have \`mr_pipeline_id\` (from **Resolve MR Pipeline**):
|
|
230
256
|
- \`list_pipeline_jobs({ projectId: $CI_PROJECT_ID, pipelineId: mr_pipeline_id })\`.
|
|
231
257
|
- Consider **only** jobs with \`status = "failed"\` and \`allow_failure = false\`.
|
|
232
258
|
- For each such job:
|
|
@@ -267,11 +293,12 @@ $(cat $TRIGGER_PAYLOAD)
|
|
|
267
293
|
${identity(ctx)}
|
|
268
294
|
${goldenRules(ctx)}
|
|
269
295
|
${selfMentionGuard(ctx)}
|
|
296
|
+
${conversationsIntake(ctx)} <!-- NEW: mandatory before acting -->
|
|
270
297
|
${eventSelfParse()}
|
|
271
|
-
${resolveMrPipeline()}
|
|
272
|
-
${singleRunnerGuard()}
|
|
298
|
+
${resolveMrPipeline()} <!-- used by review/cancel paths -->
|
|
299
|
+
${singleRunnerGuard()} <!-- operates on MR pipeline, not event pipeline -->
|
|
273
300
|
${reviewOnDemandFromEvents()}
|
|
274
|
-
${mrReviewBundle(ctx)}
|
|
301
|
+
${mrReviewBundle(ctx)} <!-- agent can execute when review intent is true -->
|
|
275
302
|
${eventWorkflow(ctx)}
|
|
276
303
|
${commentGuidelines()}
|
|
277
304
|
${mcpOnly()}
|
|
@@ -291,6 +318,7 @@ description: $CI_MERGE_REQUEST_DESCRIPTION
|
|
|
291
318
|
${mrScope(ctx)}
|
|
292
319
|
${goldenRules(ctx)}
|
|
293
320
|
${selfMentionGuard(ctx)}
|
|
321
|
+
${conversationsIntake(ctx)} <!-- NEW: always read MR discussions -->
|
|
294
322
|
${mrWorkflow()}
|
|
295
323
|
${ciInspection()}
|
|
296
324
|
${commentGuidelines()}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../../../../pipeline/src/pipeline/agent/prompts.ts"],"names":[],"mappings":";AAAA,qGAAqG;AACrG,
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../../../../pipeline/src/pipeline/agent/prompts.ts"],"names":[],"mappings":"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"}
|