secufusion-mcp 1.0.56 → 1.0.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +126 -4
- package/index.js +3 -29
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -485,10 +485,12 @@ STEP 2: call manage_task(action: "complete", work_item_id: <id>)
|
|
|
485
485
|
— Only permitted after APPROVED or DISCUSS verdict
|
|
486
486
|
— Marks status complete, auto-generates pr-summary.md
|
|
487
487
|
|
|
488
|
-
STEP 3:
|
|
489
|
-
—
|
|
490
|
-
|
|
491
|
-
|
|
488
|
+
STEP 3: Generate and save PR & ADO Documents manually
|
|
489
|
+
— Read files-touched.json, decisions.json, and scenarios.json from the task folder
|
|
490
|
+
— Generate ado-comments.md and pr-comment.md inside .secufusion/tasks/{id}-{slug}/
|
|
491
|
+
— Follow the strict templates and guardrails defined in the [Document Generation Protocol] section
|
|
492
|
+
— Present the documents to the developer for review
|
|
493
|
+
— call manage_task(action: "log_decision", decision: "ADO comments and PR comment generated")
|
|
492
494
|
```
|
|
493
495
|
|
|
494
496
|
### Hard enforcement
|
|
@@ -717,3 +719,123 @@ Before Phase 0.7 plan presentation:
|
|
|
717
719
|
❌ Do NOT skip `get_task_history` if a match exists — "I remember it" is not a substitute
|
|
718
720
|
❌ Do NOT re-solve a solved problem — task history exists precisely to prevent this
|
|
719
721
|
❌ Re-using a rejected pattern found in task history is a violation even if you disagree with the rejection
|
|
722
|
+
|
|
723
|
+
## Document Generation Protocol
|
|
724
|
+
(For Phase 4 — PR Handoff)
|
|
725
|
+
|
|
726
|
+
### ADO Comments Template (`ado-comments.md`)
|
|
727
|
+
**Audience:** Technical and Non-Technical stakeholders on the Azure DevOps board.
|
|
728
|
+
**Format rules:**
|
|
729
|
+
- Layman summary: NO class names, NO method names, NO technical terms. Pure English.
|
|
730
|
+
- Technical deep-dive: BE specific. Exact class names, exact method names, exact file paths. Source from `files-touched.json`.
|
|
731
|
+
- Tables must have content in every cell. If unknown → "not recorded".
|
|
732
|
+
- Max 2 sentences in any single prose paragraph.
|
|
733
|
+
- Max 600 words.
|
|
734
|
+
|
|
735
|
+
```markdown
|
|
736
|
+
## Layman Summary
|
|
737
|
+
{layman_summary — 2-3 sentences max}
|
|
738
|
+
|
|
739
|
+
## Technical Deep-Dive
|
|
740
|
+
{If auth/permission gating exists:}
|
|
741
|
+
> Both endpoints gated by `{permission}` authority.
|
|
742
|
+
|
|
743
|
+
### Scenarios Handled
|
|
744
|
+
**Happy path:**
|
|
745
|
+
{happy_path from scenarios.json — one sentence}
|
|
746
|
+
|
|
747
|
+
**Sad paths handled:**
|
|
748
|
+
{for each sad_path in scenarios.json:}
|
|
749
|
+
- {sad_path description} → {how handled}
|
|
750
|
+
|
|
751
|
+
**Security cases:**
|
|
752
|
+
{for each security_case in scenarios.json:}
|
|
753
|
+
- {security concern} → {enforcement}
|
|
754
|
+
|
|
755
|
+
### What did NOT change
|
|
756
|
+
| Area | Status |
|
|
757
|
+
|---|---|
|
|
758
|
+
| DB migration | {✅ Not required / ⚠️ Created: V{n}__...sql} |
|
|
759
|
+
| Kafka topics | {✅ No new topics / ⚠️ New topic: {name}} |
|
|
760
|
+
| {other_service}-api | {✅ No changes / ⚠️ Changes required} |
|
|
761
|
+
| API contract | {✅ No breaking changes / ⚠️ See decisions} |
|
|
762
|
+
|
|
763
|
+
---
|
|
764
|
+
*Generated by SecuFusion MCP · {service} · {work_item_id}*
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
### PR Comment Template (`pr-comment.md`)
|
|
768
|
+
**Audience:** Busy Developer Reviewers reading the PR description.
|
|
769
|
+
**Format rules:**
|
|
770
|
+
- Group changes by WHAT changed, not by file name (e.g., "New endpoint: GET /path", "Test coverage: N scenarios").
|
|
771
|
+
- ✅ for things NOT changing is equally important.
|
|
772
|
+
- Guardrails section is mandatory.
|
|
773
|
+
- Max 400 words. Condense changes table if longer.
|
|
774
|
+
|
|
775
|
+
```markdown
|
|
776
|
+
# {task_type_emoji} {work_item_id}: {title}
|
|
777
|
+
|
|
778
|
+
> **Type:** {task_type_display} · **Service:** `{service}` · **Work Item:** [{work_item_id}]({devops_url}/{work_item_id})
|
|
779
|
+
|
|
780
|
+
---
|
|
781
|
+
## Summary
|
|
782
|
+
{2-3 sentences MAX. What changed and why.}
|
|
783
|
+
|
|
784
|
+
---
|
|
785
|
+
## Changes
|
|
786
|
+
| Area | What changed |
|
|
787
|
+
|---|---|
|
|
788
|
+
| {logical area} | {what changed in plain terms} |
|
|
789
|
+
|
|
790
|
+
---
|
|
791
|
+
## Affected Service
|
|
792
|
+
- `{service-name}`
|
|
793
|
+
|
|
794
|
+
---
|
|
795
|
+
## Impact
|
|
796
|
+
- ✅ No functional or behavioral changes {OR describe actual behavioral change}
|
|
797
|
+
- ✅ No DB migration required {OR: ⚠️ Flyway migration V{n} included}
|
|
798
|
+
- ✅ No Kafka topic changes {OR: ⚠️ New topic: {name}}
|
|
799
|
+
- ✅ No API contract changes {OR: ⚠️ New endpoints: see Changes above}
|
|
800
|
+
|
|
801
|
+
---
|
|
802
|
+
## Scenarios
|
|
803
|
+
**Happy path:** {happy_path one line}
|
|
804
|
+
|
|
805
|
+
**Sad paths handled:**
|
|
806
|
+
- {what fails} → {how handled}
|
|
807
|
+
|
|
808
|
+
---
|
|
809
|
+
## Guardrails
|
|
810
|
+
- ✅ No `console.log` / `System.out.println` in source
|
|
811
|
+
- ✅ No hardcoded UAT/Prod URLs or IPs
|
|
812
|
+
- ✅ `tenantId` scoping maintained on all queries
|
|
813
|
+
- ✅ No `@Entity` changes — Flyway not required
|
|
814
|
+
- ✅ All pre-PR checks passed
|
|
815
|
+
|
|
816
|
+
{if any rejected patterns were relevant:}
|
|
817
|
+
**Patterns avoided:**
|
|
818
|
+
- Rejected pattern #{id}: {short description}
|
|
819
|
+
```
|
|
820
|
+
|
|
821
|
+
### Task Type Emoji Map
|
|
822
|
+
- bug → 🐛
|
|
823
|
+
- user_story → 📖
|
|
824
|
+
- feature → ✨
|
|
825
|
+
- hotfix → 🚨
|
|
826
|
+
- refactor → 🔄
|
|
827
|
+
- chore → 🧹
|
|
828
|
+
|
|
829
|
+
### Presentation Format
|
|
830
|
+
When presenting to the developer, output this exactly:
|
|
831
|
+
```text
|
|
832
|
+
────────────────────────────────────────────────
|
|
833
|
+
✅ Two documents generated for {work_item_id}:
|
|
834
|
+
|
|
835
|
+
📄 ADO Comments → paste into WI comment thread
|
|
836
|
+
📄 PR Comment → paste into PR description
|
|
837
|
+
|
|
838
|
+
Review below. Say LGTM to confirm, or tell me what to change.
|
|
839
|
+
────────────────────────────────────────────────
|
|
840
|
+
```
|
|
841
|
+
Then show the full `ado-comments.md` followed by a `────────────────────────────────` divider, followed by the full `pr-comment.md`.
|
package/index.js
CHANGED
|
@@ -3366,7 +3366,7 @@ server.tool("run_pre_pr_checks_with_reviewer_agent", "Unified, single-call PR re
|
|
|
3366
3366
|
if (verdict === "✅ APPROVED") {
|
|
3367
3367
|
out += `\n**Next steps:**\n`;
|
|
3368
3368
|
out += `1. \`manage_task(action: "complete", work_item_id: "${work_item_id}")\`\n`;
|
|
3369
|
-
out += `2.
|
|
3369
|
+
out += `2. Generate PR and ADO documents manually using AGENTS.md rules\n`;
|
|
3370
3370
|
out += `3. Raise the PR\n`;
|
|
3371
3371
|
}
|
|
3372
3372
|
else if (verdict === "❌ CHANGES_REQUESTED") {
|
|
@@ -4010,7 +4010,7 @@ server.tool("run_pre_pr_checks", "Full-spectrum PR review system — runs BEFORE
|
|
|
4010
4010
|
if (verdict === "✅ APPROVED") {
|
|
4011
4011
|
out += `\n**Next steps:**\n`;
|
|
4012
4012
|
out += `1. Call \`manage_task(action: "complete", work_item_id: "${work_item_id}")\`\n`;
|
|
4013
|
-
out += `2.
|
|
4013
|
+
out += `2. Generate PR and ADO documents manually as per Phase 4\n`;
|
|
4014
4014
|
out += `3. Raise the PR\n`;
|
|
4015
4015
|
}
|
|
4016
4016
|
else if (verdict === "❌ CHANGES_REQUESTED") {
|
|
@@ -4509,7 +4509,7 @@ server.tool("reviewer_agent", "Context-aware architectural review agent — call
|
|
|
4509
4509
|
if (verdict === "✅ APPROVED") {
|
|
4510
4510
|
out += `\n**Next steps:**\n`;
|
|
4511
4511
|
out += `1. Call \`manage_task(action: "complete", work_item_id: "${work_item_id}")\`\n`;
|
|
4512
|
-
out += `2.
|
|
4512
|
+
out += `2. Generate PR and ADO documents manually as per Phase 4\n`;
|
|
4513
4513
|
out += `3. Raise the PR\n`;
|
|
4514
4514
|
}
|
|
4515
4515
|
else if (verdict === "❌ CHANGES_REQUESTED") {
|
|
@@ -4563,31 +4563,5 @@ server.tool("get_secufusion_rules", "Fetches the mandatory AGENTS.md workflow ru
|
|
|
4563
4563
|
content: [{ type: "text", text: content }]
|
|
4564
4564
|
}, 0);
|
|
4565
4565
|
});
|
|
4566
|
-
server.tool("generate_ado_comments", "Generates and formats the final Azure DevOps board comments for a completed task. Call this in Phase 4 after PR checks pass.", {
|
|
4567
|
-
work_item_id: z.string().describe("Azure DevOps work item ID, e.g. 'BUG-1140'."),
|
|
4568
|
-
layman_summary: z.string().describe("A short, fundamental, non-technical explanation of the business value and what was resolved."),
|
|
4569
|
-
technical_deep_dive: z.string().describe("A comprehensive, highly technical breakdown of the architectural changes, core optimizations, and exact implementation details.")
|
|
4570
|
-
}, async ({ work_item_id, layman_summary, technical_deep_dive }) => {
|
|
4571
|
-
const inputChars = JSON.stringify({ work_item_id, layman_summary, technical_deep_dive }).length;
|
|
4572
|
-
let out = `## ADO Board Comments for ${work_item_id}\n\n`;
|
|
4573
|
-
out += `Please paste the following two comments into the Azure DevOps board:\n\n`;
|
|
4574
|
-
out += `### 1. Layman Summary\n`;
|
|
4575
|
-
out += `\`\`\`text\n${layman_summary}\n\`\`\`\n\n`;
|
|
4576
|
-
out += `### 2. Technical Deep-Dive\n`;
|
|
4577
|
-
out += `\`\`\`text\n${technical_deep_dive}\n\`\`\`\n\n`;
|
|
4578
|
-
try {
|
|
4579
|
-
const classifDir = resolve(".secufusion/classifications");
|
|
4580
|
-
if (!fs.existsSync(classifDir)) {
|
|
4581
|
-
fs.mkdirSync(classifDir, { recursive: true });
|
|
4582
|
-
}
|
|
4583
|
-
const commentsFile = path.join(classifDir, `${work_item_id}-comments.json`);
|
|
4584
|
-
writeFile(commentsFile, JSON.stringify({ layman_summary, technical_deep_dive, generated_at: new Date().toISOString() }, null, 2));
|
|
4585
|
-
out += `✅ Comments persisted to \`.secufusion/classifications/${work_item_id}-comments.json\`\n`;
|
|
4586
|
-
}
|
|
4587
|
-
catch (e) {
|
|
4588
|
-
// ignore
|
|
4589
|
-
}
|
|
4590
|
-
return appendTelemetry({ content: [{ type: "text", text: out }] }, inputChars);
|
|
4591
|
-
});
|
|
4592
4566
|
const transport = new StdioServerTransport();
|
|
4593
4567
|
await server.connect(transport);
|