secufusion-mcp 1.0.57 → 1.0.59
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/README.md +8 -15
- package/index.js +3 -33
- 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/README.md
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
| `get_pattern_from_task` | **Phase 1** — Cross-Task Intelligence | Extracts reusable decisions, file patterns, and test scenarios from a completed task |
|
|
22
22
|
| `manage_branch_state` | Legacy — Branch State | Backward-compatible branch-scoped JSON state tracker (for tasks before `manage_task`) |
|
|
23
23
|
| `log_rejected_pattern` | **Phase 3** — Course Correction | Records bad patterns to `.rejected-patterns.json` so they are never repeated |
|
|
24
|
-
| `
|
|
24
|
+
| `(Removed)` | **Phase 4** — PR Handoff | *Replaced by native MD generation protocol in v1.0.58* |
|
|
25
25
|
| `run_pre_pr_checks_with_reviewer_agent` | **Phase 4** — PR Handoff | **NEW** — Unified 3-tier PR gate. Runs mechanical checks, AI file reviews, and context-aware task evaluation in a single pass. |
|
|
26
26
|
| `get_secufusion_rules` | **Setup** | Returns the `AGENTS.md` rules for AI clients that don't natively support MCP Resources |
|
|
27
27
|
| `classify_task` | **Phase 0.5** — Task Classification | **NEW** — Deep multi-pass analysis engine. Classifies any task as `BACKEND_ONLY`, `FRONTEND_ONLY`, `FULL_STACK`, or `EXTENSION_ONLY` based on root cause (where the fix lives), not surface symptoms. Must be the first tool called on any task. |
|
|
@@ -233,20 +233,13 @@ This writes to `.rejected-patterns.json`:
|
|
|
233
233
|
---
|
|
234
234
|
|
|
235
235
|
### 3. generate_ado_comments
|
|
236
|
+
### 3. Native Document Generation (v1.0.58+)
|
|
236
237
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
| `layman_summary` | string | Yes | Non-technical explanation of the business value and what was resolved |
|
|
241
|
-
| `technical_deep_dive` | string | Yes | Comprehensive breakdown of the architectural changes and optimizations |
|
|
242
|
-
|
|
243
|
-
**Example — Generate ADO board comments:**
|
|
244
|
-
|
|
245
|
-
```
|
|
246
|
-
Ask: "Prepare the PR for work item 1042."
|
|
247
|
-
```
|
|
238
|
+
Instead of using a generic tool, the agent natively generates two highly structured files based on strict `AGENTS.md` templates:
|
|
239
|
+
- **`ado-comments.md`**: For the Azure DevOps board (Layman summary + Technical Deep-Dive).
|
|
240
|
+
- **`pr-comment.md`**: For the PR Description (Changes, Impact, Scenarios, Guardrails).
|
|
248
241
|
|
|
249
|
-
The AI
|
|
242
|
+
The AI constructs these dynamically by reading `scenarios.json`, `decisions.json`, and `files-touched.json`, and presents them to the developer.
|
|
250
243
|
|
|
251
244
|
---
|
|
252
245
|
|
|
@@ -428,7 +421,7 @@ These rules are enforced automatically — the AI will never violate them:
|
|
|
428
421
|
├──────────────┼──────────────────────────────────────────────────────────────┤
|
|
429
422
|
│ Phase 4 │ run_pre_pr_checks_with_reviewer_agent │
|
|
430
423
|
│ PR Handoff │ → manage_task (action=complete) → pr-summary.md generated │
|
|
431
|
-
│ │ →
|
|
424
|
+
│ │ → Document Generation (ado-comments.md, pr-comment.md) │
|
|
432
425
|
└──────────────┴──────────────────────────────────────────────────────────────┘
|
|
433
426
|
```
|
|
434
427
|
|
|
@@ -647,7 +640,7 @@ Phase 2: code + log_file_touched + log_decision + add_scenario (ALL mandatory)
|
|
|
647
640
|
↓
|
|
648
641
|
Phase 4: run_pre_pr_checks_with_reviewer_agent → APPROVED / DISCUSS
|
|
649
642
|
→ manage_task complete → pr-summary.md generated
|
|
650
|
-
→
|
|
643
|
+
→ Generate PR & ADO Documents natively using templates
|
|
651
644
|
```
|
|
652
645
|
|
|
653
646
|
### Reusing across projects (Global Bundling)
|
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,35 +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.md`);
|
|
4584
|
-
const mdContent = `# ADO Board Comments for ${work_item_id}\n\n` +
|
|
4585
|
-
`*Generated at: ${new Date().toISOString()}*\n\n` +
|
|
4586
|
-
`## 1. Layman Summary\n${layman_summary}\n\n` +
|
|
4587
|
-
`## 2. Technical Deep-Dive\n${technical_deep_dive}\n`;
|
|
4588
|
-
writeFile(commentsFile, mdContent);
|
|
4589
|
-
out += `✅ Comments persisted to \`.secufusion/classifications/${work_item_id}-comments.md\`\n`;
|
|
4590
|
-
}
|
|
4591
|
-
catch (e) {
|
|
4592
|
-
// ignore
|
|
4593
|
-
}
|
|
4594
|
-
return appendTelemetry({ content: [{ type: "text", text: out }] }, inputChars);
|
|
4595
|
-
});
|
|
4596
4566
|
const transport = new StdioServerTransport();
|
|
4597
4567
|
await server.connect(transport);
|