mrvn-cli 0.2.3 → 0.2.5
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/README.md +32 -18
- package/dist/index.d.ts +1 -0
- package/dist/index.js +862 -49
- package/dist/index.js.map +1 -1
- package/dist/marvin-serve.js +445 -42
- package/dist/marvin-serve.js.map +1 -1
- package/dist/marvin.js +887 -74
- package/dist/marvin.js.map +1 -1
- package/package.json +1 -1
package/dist/marvin-serve.js
CHANGED
|
@@ -15183,6 +15183,60 @@ function createReportTools(store) {
|
|
|
15183
15183
|
},
|
|
15184
15184
|
{ annotations: { readOnly: true } }
|
|
15185
15185
|
),
|
|
15186
|
+
tool8(
|
|
15187
|
+
"generate_sprint_progress",
|
|
15188
|
+
"Generate progress report for a sprint or all sprints, showing linked epics and tagged work items",
|
|
15189
|
+
{
|
|
15190
|
+
sprint: external_exports.string().optional().describe("Specific sprint ID (e.g. 'SP-001') or omit for all")
|
|
15191
|
+
},
|
|
15192
|
+
async (args) => {
|
|
15193
|
+
const allDocs = store.list();
|
|
15194
|
+
const sprintDocs = store.list({ type: "sprint" });
|
|
15195
|
+
const sprints = sprintDocs.filter((s) => !args.sprint || s.frontmatter.id === args.sprint).map((sprintDoc) => {
|
|
15196
|
+
const sprintId = sprintDoc.frontmatter.id;
|
|
15197
|
+
const linkedEpicIds = sprintDoc.frontmatter.linkedEpics ?? [];
|
|
15198
|
+
const linkedEpics = linkedEpicIds.map((epicId) => {
|
|
15199
|
+
const epic = store.get(epicId);
|
|
15200
|
+
return epic ? { id: epicId, title: epic.frontmatter.title, status: epic.frontmatter.status } : { id: epicId, title: "(not found)", status: "unknown" };
|
|
15201
|
+
});
|
|
15202
|
+
const workItems = allDocs.filter(
|
|
15203
|
+
(d) => d.frontmatter.type !== "sprint" && d.frontmatter.type !== "epic" && d.frontmatter.tags?.includes(`sprint:${sprintId}`)
|
|
15204
|
+
);
|
|
15205
|
+
const byStatus = {};
|
|
15206
|
+
for (const doc of workItems) {
|
|
15207
|
+
byStatus[doc.frontmatter.status] = (byStatus[doc.frontmatter.status] ?? 0) + 1;
|
|
15208
|
+
}
|
|
15209
|
+
const doneCount = (byStatus["done"] ?? 0) + (byStatus["resolved"] ?? 0) + (byStatus["closed"] ?? 0);
|
|
15210
|
+
const total = workItems.length;
|
|
15211
|
+
const completionPct = total > 0 ? Math.round(doneCount / total * 100) : 0;
|
|
15212
|
+
return {
|
|
15213
|
+
id: sprintDoc.frontmatter.id,
|
|
15214
|
+
title: sprintDoc.frontmatter.title,
|
|
15215
|
+
status: sprintDoc.frontmatter.status,
|
|
15216
|
+
goal: sprintDoc.frontmatter.goal,
|
|
15217
|
+
startDate: sprintDoc.frontmatter.startDate,
|
|
15218
|
+
endDate: sprintDoc.frontmatter.endDate,
|
|
15219
|
+
linkedEpics,
|
|
15220
|
+
workItems: {
|
|
15221
|
+
total,
|
|
15222
|
+
done: doneCount,
|
|
15223
|
+
completionPct,
|
|
15224
|
+
byStatus,
|
|
15225
|
+
items: workItems.map((d) => ({
|
|
15226
|
+
id: d.frontmatter.id,
|
|
15227
|
+
title: d.frontmatter.title,
|
|
15228
|
+
type: d.frontmatter.type,
|
|
15229
|
+
status: d.frontmatter.status
|
|
15230
|
+
}))
|
|
15231
|
+
}
|
|
15232
|
+
};
|
|
15233
|
+
});
|
|
15234
|
+
return {
|
|
15235
|
+
content: [{ type: "text", text: JSON.stringify({ sprints }, null, 2) }]
|
|
15236
|
+
};
|
|
15237
|
+
},
|
|
15238
|
+
{ annotations: { readOnly: true } }
|
|
15239
|
+
),
|
|
15186
15240
|
tool8(
|
|
15187
15241
|
"generate_feature_progress",
|
|
15188
15242
|
"Generate progress report for features and their linked epics",
|
|
@@ -15229,7 +15283,7 @@ function createReportTools(store) {
|
|
|
15229
15283
|
{
|
|
15230
15284
|
title: external_exports.string().describe("Report title"),
|
|
15231
15285
|
content: external_exports.string().describe("Full report content in markdown"),
|
|
15232
|
-
reportType: external_exports.enum(["status", "risk-register", "gar", "epic-progress", "feature-progress", "custom"]).describe("Type of report"),
|
|
15286
|
+
reportType: external_exports.enum(["status", "risk-register", "gar", "epic-progress", "feature-progress", "sprint-progress", "custom"]).describe("Type of report"),
|
|
15233
15287
|
tags: external_exports.array(external_exports.string()).optional().describe("Additional tags")
|
|
15234
15288
|
},
|
|
15235
15289
|
async (args) => {
|
|
@@ -15526,19 +15580,316 @@ function createEpicTools(store) {
|
|
|
15526
15580
|
];
|
|
15527
15581
|
}
|
|
15528
15582
|
|
|
15583
|
+
// src/plugins/builtin/tools/contributions.ts
|
|
15584
|
+
import { tool as tool11 } from "@anthropic-ai/claude-agent-sdk";
|
|
15585
|
+
function createContributionTools(store) {
|
|
15586
|
+
return [
|
|
15587
|
+
tool11(
|
|
15588
|
+
"list_contributions",
|
|
15589
|
+
"List all contributions in the project, optionally filtered by persona, contribution type, or status",
|
|
15590
|
+
{
|
|
15591
|
+
persona: external_exports.string().optional().describe("Filter by persona (e.g. 'tech-lead', 'product-owner')"),
|
|
15592
|
+
contributionType: external_exports.string().optional().describe("Filter by contribution type (e.g. 'action-result', 'risk-finding')"),
|
|
15593
|
+
status: external_exports.string().optional().describe("Filter by status")
|
|
15594
|
+
},
|
|
15595
|
+
async (args) => {
|
|
15596
|
+
let docs = store.list({ type: "contribution", status: args.status });
|
|
15597
|
+
if (args.persona) {
|
|
15598
|
+
docs = docs.filter((d) => d.frontmatter.persona === args.persona);
|
|
15599
|
+
}
|
|
15600
|
+
if (args.contributionType) {
|
|
15601
|
+
docs = docs.filter((d) => d.frontmatter.contributionType === args.contributionType);
|
|
15602
|
+
}
|
|
15603
|
+
const summary = docs.map((d) => ({
|
|
15604
|
+
id: d.frontmatter.id,
|
|
15605
|
+
title: d.frontmatter.title,
|
|
15606
|
+
status: d.frontmatter.status,
|
|
15607
|
+
persona: d.frontmatter.persona,
|
|
15608
|
+
contributionType: d.frontmatter.contributionType,
|
|
15609
|
+
aboutArtifact: d.frontmatter.aboutArtifact,
|
|
15610
|
+
created: d.frontmatter.created,
|
|
15611
|
+
tags: d.frontmatter.tags
|
|
15612
|
+
}));
|
|
15613
|
+
return {
|
|
15614
|
+
content: [{ type: "text", text: JSON.stringify(summary, null, 2) }]
|
|
15615
|
+
};
|
|
15616
|
+
},
|
|
15617
|
+
{ annotations: { readOnly: true } }
|
|
15618
|
+
),
|
|
15619
|
+
tool11(
|
|
15620
|
+
"get_contribution",
|
|
15621
|
+
"Get the full content of a specific contribution by ID",
|
|
15622
|
+
{ id: external_exports.string().describe("Contribution ID (e.g. 'C-001')") },
|
|
15623
|
+
async (args) => {
|
|
15624
|
+
const doc = store.get(args.id);
|
|
15625
|
+
if (!doc) {
|
|
15626
|
+
return {
|
|
15627
|
+
content: [{ type: "text", text: `Contribution ${args.id} not found` }],
|
|
15628
|
+
isError: true
|
|
15629
|
+
};
|
|
15630
|
+
}
|
|
15631
|
+
return {
|
|
15632
|
+
content: [
|
|
15633
|
+
{
|
|
15634
|
+
type: "text",
|
|
15635
|
+
text: JSON.stringify(
|
|
15636
|
+
{ ...doc.frontmatter, content: doc.content },
|
|
15637
|
+
null,
|
|
15638
|
+
2
|
|
15639
|
+
)
|
|
15640
|
+
}
|
|
15641
|
+
]
|
|
15642
|
+
};
|
|
15643
|
+
},
|
|
15644
|
+
{ annotations: { readOnly: true } }
|
|
15645
|
+
),
|
|
15646
|
+
tool11(
|
|
15647
|
+
"create_contribution",
|
|
15648
|
+
"Create a new contribution record from a persona",
|
|
15649
|
+
{
|
|
15650
|
+
title: external_exports.string().describe("Title of the contribution"),
|
|
15651
|
+
content: external_exports.string().describe("Contribution content \u2014 the input from the persona"),
|
|
15652
|
+
persona: external_exports.string().describe("Persona making the contribution (e.g. 'tech-lead')"),
|
|
15653
|
+
contributionType: external_exports.string().describe("Type of contribution (e.g. 'action-result', 'risk-finding')"),
|
|
15654
|
+
aboutArtifact: external_exports.string().optional().describe("Artifact ID this contribution relates to (e.g. 'A-001')"),
|
|
15655
|
+
status: external_exports.string().optional().describe("Status (default: 'open')"),
|
|
15656
|
+
tags: external_exports.array(external_exports.string()).optional().describe("Tags for categorization")
|
|
15657
|
+
},
|
|
15658
|
+
async (args) => {
|
|
15659
|
+
const frontmatter = {
|
|
15660
|
+
title: args.title,
|
|
15661
|
+
status: args.status ?? "open",
|
|
15662
|
+
persona: args.persona,
|
|
15663
|
+
contributionType: args.contributionType
|
|
15664
|
+
};
|
|
15665
|
+
if (args.aboutArtifact) frontmatter.aboutArtifact = args.aboutArtifact;
|
|
15666
|
+
if (args.tags) frontmatter.tags = args.tags;
|
|
15667
|
+
const doc = store.create("contribution", frontmatter, args.content);
|
|
15668
|
+
return {
|
|
15669
|
+
content: [
|
|
15670
|
+
{
|
|
15671
|
+
type: "text",
|
|
15672
|
+
text: `Created contribution ${doc.frontmatter.id}: ${doc.frontmatter.title}`
|
|
15673
|
+
}
|
|
15674
|
+
]
|
|
15675
|
+
};
|
|
15676
|
+
}
|
|
15677
|
+
),
|
|
15678
|
+
tool11(
|
|
15679
|
+
"update_contribution",
|
|
15680
|
+
"Update an existing contribution (e.g. to append an Effects section)",
|
|
15681
|
+
{
|
|
15682
|
+
id: external_exports.string().describe("Contribution ID to update"),
|
|
15683
|
+
title: external_exports.string().optional().describe("New title"),
|
|
15684
|
+
status: external_exports.string().optional().describe("New status"),
|
|
15685
|
+
content: external_exports.string().optional().describe("New content")
|
|
15686
|
+
},
|
|
15687
|
+
async (args) => {
|
|
15688
|
+
const { id, content, ...updates } = args;
|
|
15689
|
+
const doc = store.update(id, updates, content);
|
|
15690
|
+
return {
|
|
15691
|
+
content: [
|
|
15692
|
+
{
|
|
15693
|
+
type: "text",
|
|
15694
|
+
text: `Updated contribution ${doc.frontmatter.id}: ${doc.frontmatter.title}`
|
|
15695
|
+
}
|
|
15696
|
+
]
|
|
15697
|
+
};
|
|
15698
|
+
}
|
|
15699
|
+
)
|
|
15700
|
+
];
|
|
15701
|
+
}
|
|
15702
|
+
|
|
15703
|
+
// src/plugins/builtin/tools/sprints.ts
|
|
15704
|
+
import { tool as tool12 } from "@anthropic-ai/claude-agent-sdk";
|
|
15705
|
+
function createSprintTools(store) {
|
|
15706
|
+
return [
|
|
15707
|
+
tool12(
|
|
15708
|
+
"list_sprints",
|
|
15709
|
+
"List all sprints in the project, optionally filtered by status",
|
|
15710
|
+
{
|
|
15711
|
+
status: external_exports.enum(["planned", "active", "completed", "cancelled"]).optional().describe("Filter by sprint status")
|
|
15712
|
+
},
|
|
15713
|
+
async (args) => {
|
|
15714
|
+
const docs = store.list({ type: "sprint", status: args.status });
|
|
15715
|
+
const summary = docs.map((d) => ({
|
|
15716
|
+
id: d.frontmatter.id,
|
|
15717
|
+
title: d.frontmatter.title,
|
|
15718
|
+
status: d.frontmatter.status,
|
|
15719
|
+
goal: d.frontmatter.goal,
|
|
15720
|
+
startDate: d.frontmatter.startDate,
|
|
15721
|
+
endDate: d.frontmatter.endDate,
|
|
15722
|
+
linkedEpics: d.frontmatter.linkedEpics,
|
|
15723
|
+
tags: d.frontmatter.tags
|
|
15724
|
+
}));
|
|
15725
|
+
return {
|
|
15726
|
+
content: [{ type: "text", text: JSON.stringify(summary, null, 2) }]
|
|
15727
|
+
};
|
|
15728
|
+
},
|
|
15729
|
+
{ annotations: { readOnly: true } }
|
|
15730
|
+
),
|
|
15731
|
+
tool12(
|
|
15732
|
+
"get_sprint",
|
|
15733
|
+
"Get the full content of a specific sprint by ID",
|
|
15734
|
+
{ id: external_exports.string().describe("Sprint ID (e.g. 'SP-001')") },
|
|
15735
|
+
async (args) => {
|
|
15736
|
+
const doc = store.get(args.id);
|
|
15737
|
+
if (!doc) {
|
|
15738
|
+
return {
|
|
15739
|
+
content: [{ type: "text", text: `Sprint ${args.id} not found` }],
|
|
15740
|
+
isError: true
|
|
15741
|
+
};
|
|
15742
|
+
}
|
|
15743
|
+
return {
|
|
15744
|
+
content: [
|
|
15745
|
+
{
|
|
15746
|
+
type: "text",
|
|
15747
|
+
text: JSON.stringify(
|
|
15748
|
+
{ ...doc.frontmatter, content: doc.content },
|
|
15749
|
+
null,
|
|
15750
|
+
2
|
|
15751
|
+
)
|
|
15752
|
+
}
|
|
15753
|
+
]
|
|
15754
|
+
};
|
|
15755
|
+
},
|
|
15756
|
+
{ annotations: { readOnly: true } }
|
|
15757
|
+
),
|
|
15758
|
+
tool12(
|
|
15759
|
+
"create_sprint",
|
|
15760
|
+
"Create a new sprint with dates, goal, and optionally linked epics",
|
|
15761
|
+
{
|
|
15762
|
+
title: external_exports.string().describe("Sprint title"),
|
|
15763
|
+
content: external_exports.string().describe("Sprint description and objectives"),
|
|
15764
|
+
goal: external_exports.string().describe("Sprint goal \u2014 what this sprint aims to deliver"),
|
|
15765
|
+
startDate: external_exports.string().describe("Sprint start date (ISO format, e.g. '2026-03-01')"),
|
|
15766
|
+
endDate: external_exports.string().describe("Sprint end date (ISO format, e.g. '2026-03-14')"),
|
|
15767
|
+
status: external_exports.enum(["planned", "active", "completed", "cancelled"]).optional().describe("Sprint status (default: 'planned')"),
|
|
15768
|
+
linkedEpics: external_exports.array(external_exports.string()).optional().describe("Epic IDs to link (e.g. ['E-001', 'E-003']). Soft-validated: warns if not found but still creates."),
|
|
15769
|
+
tags: external_exports.array(external_exports.string()).optional().describe("Additional tags")
|
|
15770
|
+
},
|
|
15771
|
+
async (args) => {
|
|
15772
|
+
const warnings = [];
|
|
15773
|
+
if (args.linkedEpics) {
|
|
15774
|
+
for (const epicId of args.linkedEpics) {
|
|
15775
|
+
const epic = store.get(epicId);
|
|
15776
|
+
if (!epic) {
|
|
15777
|
+
warnings.push(`Epic ${epicId} not found (linked anyway)`);
|
|
15778
|
+
}
|
|
15779
|
+
}
|
|
15780
|
+
}
|
|
15781
|
+
const frontmatter = {
|
|
15782
|
+
title: args.title,
|
|
15783
|
+
status: args.status ?? "planned",
|
|
15784
|
+
goal: args.goal,
|
|
15785
|
+
startDate: args.startDate,
|
|
15786
|
+
endDate: args.endDate,
|
|
15787
|
+
linkedEpics: args.linkedEpics ?? [],
|
|
15788
|
+
tags: [...args.tags ?? []]
|
|
15789
|
+
};
|
|
15790
|
+
const doc = store.create("sprint", frontmatter, args.content);
|
|
15791
|
+
const sprintId = doc.frontmatter.id;
|
|
15792
|
+
if (args.linkedEpics) {
|
|
15793
|
+
for (const epicId of args.linkedEpics) {
|
|
15794
|
+
const epic = store.get(epicId);
|
|
15795
|
+
if (epic) {
|
|
15796
|
+
const existingTags = epic.frontmatter.tags ?? [];
|
|
15797
|
+
const sprintTag = `sprint:${sprintId}`;
|
|
15798
|
+
if (!existingTags.includes(sprintTag)) {
|
|
15799
|
+
store.update(epicId, { tags: [...existingTags, sprintTag] });
|
|
15800
|
+
}
|
|
15801
|
+
}
|
|
15802
|
+
}
|
|
15803
|
+
}
|
|
15804
|
+
const parts = [`Created sprint ${sprintId}: ${doc.frontmatter.title}`];
|
|
15805
|
+
if (warnings.length > 0) {
|
|
15806
|
+
parts.push(`Warnings: ${warnings.join("; ")}`);
|
|
15807
|
+
}
|
|
15808
|
+
return {
|
|
15809
|
+
content: [{ type: "text", text: parts.join("\n") }]
|
|
15810
|
+
};
|
|
15811
|
+
}
|
|
15812
|
+
),
|
|
15813
|
+
tool12(
|
|
15814
|
+
"update_sprint",
|
|
15815
|
+
"Update an existing sprint. Cannot change id or type.",
|
|
15816
|
+
{
|
|
15817
|
+
id: external_exports.string().describe("Sprint ID to update"),
|
|
15818
|
+
title: external_exports.string().optional().describe("New title"),
|
|
15819
|
+
status: external_exports.enum(["planned", "active", "completed", "cancelled"]).optional().describe("New status"),
|
|
15820
|
+
content: external_exports.string().optional().describe("New content"),
|
|
15821
|
+
goal: external_exports.string().optional().describe("New sprint goal"),
|
|
15822
|
+
startDate: external_exports.string().optional().describe("New start date"),
|
|
15823
|
+
endDate: external_exports.string().optional().describe("New end date"),
|
|
15824
|
+
linkedEpics: external_exports.array(external_exports.string()).optional().describe("New list of linked epic IDs (replaces existing)"),
|
|
15825
|
+
tags: external_exports.array(external_exports.string()).optional().describe("New tags (replaces existing)")
|
|
15826
|
+
},
|
|
15827
|
+
async (args) => {
|
|
15828
|
+
const { id, content, linkedEpics, ...updates } = args;
|
|
15829
|
+
const existing = store.get(id);
|
|
15830
|
+
if (!existing) {
|
|
15831
|
+
return {
|
|
15832
|
+
content: [{ type: "text", text: `Sprint ${id} not found` }],
|
|
15833
|
+
isError: true
|
|
15834
|
+
};
|
|
15835
|
+
}
|
|
15836
|
+
if (linkedEpics !== void 0) {
|
|
15837
|
+
const oldLinked = existing.frontmatter.linkedEpics ?? [];
|
|
15838
|
+
const sprintTag = `sprint:${id}`;
|
|
15839
|
+
const removed = oldLinked.filter((e) => !linkedEpics.includes(e));
|
|
15840
|
+
for (const epicId of removed) {
|
|
15841
|
+
const epic = store.get(epicId);
|
|
15842
|
+
if (epic) {
|
|
15843
|
+
const tags = epic.frontmatter.tags ?? [];
|
|
15844
|
+
const filtered = tags.filter((t) => t !== sprintTag);
|
|
15845
|
+
if (filtered.length !== tags.length) {
|
|
15846
|
+
store.update(epicId, { tags: filtered });
|
|
15847
|
+
}
|
|
15848
|
+
}
|
|
15849
|
+
}
|
|
15850
|
+
const added = linkedEpics.filter((e) => !oldLinked.includes(e));
|
|
15851
|
+
for (const epicId of added) {
|
|
15852
|
+
const epic = store.get(epicId);
|
|
15853
|
+
if (epic) {
|
|
15854
|
+
const tags = epic.frontmatter.tags ?? [];
|
|
15855
|
+
if (!tags.includes(sprintTag)) {
|
|
15856
|
+
store.update(epicId, { tags: [...tags, sprintTag] });
|
|
15857
|
+
}
|
|
15858
|
+
}
|
|
15859
|
+
}
|
|
15860
|
+
updates.linkedEpics = linkedEpics;
|
|
15861
|
+
}
|
|
15862
|
+
const doc = store.update(id, updates, content);
|
|
15863
|
+
return {
|
|
15864
|
+
content: [
|
|
15865
|
+
{
|
|
15866
|
+
type: "text",
|
|
15867
|
+
text: `Updated sprint ${doc.frontmatter.id}: ${doc.frontmatter.title}`
|
|
15868
|
+
}
|
|
15869
|
+
]
|
|
15870
|
+
};
|
|
15871
|
+
}
|
|
15872
|
+
)
|
|
15873
|
+
];
|
|
15874
|
+
}
|
|
15875
|
+
|
|
15529
15876
|
// src/plugins/common.ts
|
|
15530
15877
|
var COMMON_REGISTRATIONS = [
|
|
15531
15878
|
{ type: "meeting", dirName: "meetings", idPrefix: "M" },
|
|
15532
15879
|
{ type: "report", dirName: "reports", idPrefix: "R" },
|
|
15533
15880
|
{ type: "feature", dirName: "features", idPrefix: "F" },
|
|
15534
|
-
{ type: "epic", dirName: "epics", idPrefix: "E" }
|
|
15881
|
+
{ type: "epic", dirName: "epics", idPrefix: "E" },
|
|
15882
|
+
{ type: "contribution", dirName: "contributions", idPrefix: "C" },
|
|
15883
|
+
{ type: "sprint", dirName: "sprints", idPrefix: "SP" }
|
|
15535
15884
|
];
|
|
15536
15885
|
function createCommonTools(store) {
|
|
15537
15886
|
return [
|
|
15538
15887
|
...createMeetingTools(store),
|
|
15539
15888
|
...createReportTools(store),
|
|
15540
15889
|
...createFeatureTools(store),
|
|
15541
|
-
...createEpicTools(store)
|
|
15890
|
+
...createEpicTools(store),
|
|
15891
|
+
...createContributionTools(store),
|
|
15892
|
+
...createSprintTools(store)
|
|
15542
15893
|
];
|
|
15543
15894
|
}
|
|
15544
15895
|
|
|
@@ -15548,7 +15899,7 @@ var genericAgilePlugin = {
|
|
|
15548
15899
|
name: "Generic Agile",
|
|
15549
15900
|
description: "Default methodology plugin providing standard agile governance patterns for decisions, actions, and questions.",
|
|
15550
15901
|
version: "0.1.0",
|
|
15551
|
-
documentTypes: ["decision", "action", "question", "meeting", "report", "feature", "epic"],
|
|
15902
|
+
documentTypes: ["decision", "action", "question", "meeting", "report", "feature", "epic", "contribution", "sprint"],
|
|
15552
15903
|
documentTypeRegistrations: [...COMMON_REGISTRATIONS],
|
|
15553
15904
|
tools: (store) => [...createCommonTools(store)],
|
|
15554
15905
|
promptFragments: {
|
|
@@ -15569,7 +15920,16 @@ var genericAgilePlugin = {
|
|
|
15569
15920
|
- Create features as "draft" and approve them when requirements are clear and prioritized.
|
|
15570
15921
|
- Do NOT create epics \u2014 that is the Tech Lead's responsibility. You can view epics to track progress.
|
|
15571
15922
|
- Use priority levels (critical, high, medium, low) to communicate business value.
|
|
15572
|
-
- Tag features for categorization and cross-referencing
|
|
15923
|
+
- Tag features for categorization and cross-referencing.
|
|
15924
|
+
|
|
15925
|
+
**Contribution Tools:**
|
|
15926
|
+
- **list_contributions** / **get_contribution**: Browse and read contribution records.
|
|
15927
|
+
- **create_contribution**: Record a contribution with persona, type, and optional related artifact.
|
|
15928
|
+
- **update_contribution**: Update a contribution (e.g. append effects).
|
|
15929
|
+
- Available contribution types: stakeholder-feedback, acceptance-result, priority-change, market-insight.
|
|
15930
|
+
|
|
15931
|
+
**Sprint Tools (read-only for awareness):**
|
|
15932
|
+
- **list_sprints** / **get_sprint**: View sprints to understand delivery timelines and iteration scope.`,
|
|
15573
15933
|
"tech-lead": `You own epics and break approved features into implementation work.
|
|
15574
15934
|
|
|
15575
15935
|
**Epic Tools:**
|
|
@@ -15590,7 +15950,19 @@ var genericAgilePlugin = {
|
|
|
15590
15950
|
- Only create epics against approved features \u2014 create_epic enforces this.
|
|
15591
15951
|
- Tag work items (actions, decisions, questions) with \`epic:E-xxx\` to group them under an epic.
|
|
15592
15952
|
- Collaborate with the Delivery Manager on target dates and effort estimates.
|
|
15593
|
-
- Each epic should have a clear scope and definition of done
|
|
15953
|
+
- Each epic should have a clear scope and definition of done.
|
|
15954
|
+
|
|
15955
|
+
**Contribution Tools:**
|
|
15956
|
+
- **list_contributions** / **get_contribution**: Browse and read contribution records.
|
|
15957
|
+
- **create_contribution**: Record a contribution with persona, type, and optional related artifact.
|
|
15958
|
+
- **update_contribution**: Update a contribution (e.g. append effects).
|
|
15959
|
+
- Available contribution types: action-result, spike-findings, technical-assessment, architecture-review.
|
|
15960
|
+
|
|
15961
|
+
**Sprint Tools:**
|
|
15962
|
+
- **list_sprints** / **get_sprint**: View sprints to understand iteration scope and delivery dates.
|
|
15963
|
+
- **update_sprint**: Assign epics to sprints by updating linkedEpics when breaking features into work.
|
|
15964
|
+
- Tag technical actions and decisions with \`sprint:SP-xxx\` to associate them with a sprint.
|
|
15965
|
+
- Use **generate_sprint_progress** to track technical work completion within an iteration.`,
|
|
15594
15966
|
"delivery-manager": `You track delivery across features and epics, manage schedules, and report on progress.
|
|
15595
15967
|
|
|
15596
15968
|
**Report Tools:**
|
|
@@ -15618,27 +15990,53 @@ var genericAgilePlugin = {
|
|
|
15618
15990
|
- After generating any report, offer to save it with save_report for audit trail.
|
|
15619
15991
|
- Proactively flag risks: unowned actions, overdue items, epics linked to deferred features.
|
|
15620
15992
|
- Use feature progress reports for stakeholder updates and epic progress for sprint-level tracking.
|
|
15621
|
-
- Use analyze_meeting after meetings to extract outcomes into governance artifacts
|
|
15622
|
-
|
|
15993
|
+
- Use analyze_meeting after meetings to extract outcomes into governance artifacts.
|
|
15994
|
+
|
|
15995
|
+
**Contribution Tools:**
|
|
15996
|
+
- **list_contributions** / **get_contribution**: Browse and read contribution records.
|
|
15997
|
+
- **create_contribution**: Record a contribution with persona, type, and optional related artifact.
|
|
15998
|
+
- **update_contribution**: Update a contribution (e.g. append effects).
|
|
15999
|
+
- Available contribution types: risk-finding, blocker-report, dependency-update, status-assessment.
|
|
16000
|
+
|
|
16001
|
+
**Sprint Tools:**
|
|
16002
|
+
- **list_sprints** / **get_sprint**: Browse and read sprint definitions.
|
|
16003
|
+
- **create_sprint**: Create sprints with dates, goals, and linked epics. Use status "planned" for upcoming sprints or "active"/"completed"/"cancelled" for current/past sprints.
|
|
16004
|
+
- **update_sprint**: Update sprint status, dates, goal, or linked epics. When linkedEpics changes, affected epics are re-tagged automatically.
|
|
16005
|
+
- **generate_sprint_progress**: Progress report for a specific sprint or all sprints \u2014 shows linked epics with statuses, work items tagged \`sprint:SP-xxx\` grouped by status, and done/total completion %.
|
|
16006
|
+
- Use \`save_report\` with reportType "sprint-progress" to persist sprint reports.
|
|
16007
|
+
|
|
16008
|
+
**Sprint Workflow:**
|
|
16009
|
+
- Create sprints with clear goals and date boundaries.
|
|
16010
|
+
- Assign epics to sprints via linkedEpics.
|
|
16011
|
+
- Tag work items (actions, decisions, questions) with \`sprint:SP-xxx\` for sprint scoping.
|
|
16012
|
+
- Track delivery dates and flag at-risk sprints.
|
|
16013
|
+
- Register past/completed sprints for historical tracking.`,
|
|
16014
|
+
"*": `You have access to feature, epic, sprint, and meeting tools for project coordination:
|
|
15623
16015
|
|
|
15624
16016
|
**Features** (F-xxx): Product capabilities defined by the Product Owner. Features progress through draft \u2192 approved \u2192 done.
|
|
15625
16017
|
**Epics** (E-xxx): Implementation work packages created by the Tech Lead, linked to approved features. Epics progress through planned \u2192 in-progress \u2192 done.
|
|
16018
|
+
**Sprints** (SP-xxx): Time-boxed iterations that group epics and work items with delivery dates. Sprints progress through planned \u2192 active \u2192 completed (or cancelled).
|
|
15626
16019
|
**Meetings**: Meeting records with attendees, agendas, and notes.
|
|
15627
16020
|
|
|
15628
|
-
**Key workflow rule:** Epics must link to approved features \u2014 the system enforces this. The Product Owner defines and approves features, the Tech Lead breaks them into epics,
|
|
16021
|
+
**Key workflow rule:** Epics must link to approved features \u2014 the system enforces this. The Product Owner defines and approves features, the Tech Lead breaks them into epics, the Delivery Manager plans sprints and tracks dates and progress. Work items are associated with sprints via \`sprint:SP-xxx\` tags.
|
|
15629
16022
|
|
|
15630
16023
|
- **list_meetings** / **get_meeting**: Browse and read meeting records.
|
|
15631
16024
|
- **create_meeting**: Record meetings with attendees, date, and agenda. The meeting date is required \u2014 extract it from the meeting content or ask the user if not found.
|
|
15632
16025
|
- **update_meeting**: Update meeting status or notes.
|
|
15633
|
-
- **analyze_meeting**: Analyze a meeting to extract decisions, actions, and questions as governance artifacts
|
|
16026
|
+
- **analyze_meeting**: Analyze a meeting to extract decisions, actions, and questions as governance artifacts.
|
|
16027
|
+
|
|
16028
|
+
**Contributions** (C-xxx): Structured inputs from personas outside of meetings (e.g. action results, risk findings, stakeholder feedback). Contributions are analyzed to produce governance effects.
|
|
16029
|
+
- **list_contributions** / **get_contribution**: Browse and read contribution records.
|
|
16030
|
+
- **create_contribution**: Record a contribution with persona, type, and optional related artifact.
|
|
16031
|
+
- **update_contribution**: Update a contribution (e.g. append effects).`
|
|
15634
16032
|
}
|
|
15635
16033
|
};
|
|
15636
16034
|
|
|
15637
16035
|
// src/plugins/builtin/tools/use-cases.ts
|
|
15638
|
-
import { tool as
|
|
16036
|
+
import { tool as tool13 } from "@anthropic-ai/claude-agent-sdk";
|
|
15639
16037
|
function createUseCaseTools(store) {
|
|
15640
16038
|
return [
|
|
15641
|
-
|
|
16039
|
+
tool13(
|
|
15642
16040
|
"list_use_cases",
|
|
15643
16041
|
"List all extension use cases, optionally filtered by status or extension type",
|
|
15644
16042
|
{
|
|
@@ -15668,7 +16066,7 @@ function createUseCaseTools(store) {
|
|
|
15668
16066
|
},
|
|
15669
16067
|
{ annotations: { readOnly: true } }
|
|
15670
16068
|
),
|
|
15671
|
-
|
|
16069
|
+
tool13(
|
|
15672
16070
|
"get_use_case",
|
|
15673
16071
|
"Get the full content of a specific use case by ID",
|
|
15674
16072
|
{ id: external_exports.string().describe("Use case ID (e.g. 'UC-001')") },
|
|
@@ -15695,7 +16093,7 @@ function createUseCaseTools(store) {
|
|
|
15695
16093
|
},
|
|
15696
16094
|
{ annotations: { readOnly: true } }
|
|
15697
16095
|
),
|
|
15698
|
-
|
|
16096
|
+
tool13(
|
|
15699
16097
|
"create_use_case",
|
|
15700
16098
|
"Create a new extension use case definition (Phase 1: Assess Extension Use Case)",
|
|
15701
16099
|
{
|
|
@@ -15729,7 +16127,7 @@ function createUseCaseTools(store) {
|
|
|
15729
16127
|
};
|
|
15730
16128
|
}
|
|
15731
16129
|
),
|
|
15732
|
-
|
|
16130
|
+
tool13(
|
|
15733
16131
|
"update_use_case",
|
|
15734
16132
|
"Update an existing extension use case",
|
|
15735
16133
|
{
|
|
@@ -15759,10 +16157,10 @@ function createUseCaseTools(store) {
|
|
|
15759
16157
|
}
|
|
15760
16158
|
|
|
15761
16159
|
// src/plugins/builtin/tools/tech-assessments.ts
|
|
15762
|
-
import { tool as
|
|
16160
|
+
import { tool as tool14 } from "@anthropic-ai/claude-agent-sdk";
|
|
15763
16161
|
function createTechAssessmentTools(store) {
|
|
15764
16162
|
return [
|
|
15765
|
-
|
|
16163
|
+
tool14(
|
|
15766
16164
|
"list_tech_assessments",
|
|
15767
16165
|
"List all technology assessments, optionally filtered by status",
|
|
15768
16166
|
{
|
|
@@ -15793,7 +16191,7 @@ function createTechAssessmentTools(store) {
|
|
|
15793
16191
|
},
|
|
15794
16192
|
{ annotations: { readOnly: true } }
|
|
15795
16193
|
),
|
|
15796
|
-
|
|
16194
|
+
tool14(
|
|
15797
16195
|
"get_tech_assessment",
|
|
15798
16196
|
"Get the full content of a specific technology assessment by ID",
|
|
15799
16197
|
{ id: external_exports.string().describe("Tech assessment ID (e.g. 'TA-001')") },
|
|
@@ -15820,7 +16218,7 @@ function createTechAssessmentTools(store) {
|
|
|
15820
16218
|
},
|
|
15821
16219
|
{ annotations: { readOnly: true } }
|
|
15822
16220
|
),
|
|
15823
|
-
|
|
16221
|
+
tool14(
|
|
15824
16222
|
"create_tech_assessment",
|
|
15825
16223
|
"Create a new technology assessment linked to an assessed/approved use case (Phase 2: Assess Extension Technology)",
|
|
15826
16224
|
{
|
|
@@ -15891,7 +16289,7 @@ function createTechAssessmentTools(store) {
|
|
|
15891
16289
|
};
|
|
15892
16290
|
}
|
|
15893
16291
|
),
|
|
15894
|
-
|
|
16292
|
+
tool14(
|
|
15895
16293
|
"update_tech_assessment",
|
|
15896
16294
|
"Update an existing technology assessment. The linked use case cannot be changed.",
|
|
15897
16295
|
{
|
|
@@ -15921,10 +16319,10 @@ function createTechAssessmentTools(store) {
|
|
|
15921
16319
|
}
|
|
15922
16320
|
|
|
15923
16321
|
// src/plugins/builtin/tools/extension-designs.ts
|
|
15924
|
-
import { tool as
|
|
16322
|
+
import { tool as tool15 } from "@anthropic-ai/claude-agent-sdk";
|
|
15925
16323
|
function createExtensionDesignTools(store) {
|
|
15926
16324
|
return [
|
|
15927
|
-
|
|
16325
|
+
tool15(
|
|
15928
16326
|
"list_extension_designs",
|
|
15929
16327
|
"List all extension designs, optionally filtered by status",
|
|
15930
16328
|
{
|
|
@@ -15954,7 +16352,7 @@ function createExtensionDesignTools(store) {
|
|
|
15954
16352
|
},
|
|
15955
16353
|
{ annotations: { readOnly: true } }
|
|
15956
16354
|
),
|
|
15957
|
-
|
|
16355
|
+
tool15(
|
|
15958
16356
|
"get_extension_design",
|
|
15959
16357
|
"Get the full content of a specific extension design by ID",
|
|
15960
16358
|
{ id: external_exports.string().describe("Extension design ID (e.g. 'XD-001')") },
|
|
@@ -15981,7 +16379,7 @@ function createExtensionDesignTools(store) {
|
|
|
15981
16379
|
},
|
|
15982
16380
|
{ annotations: { readOnly: true } }
|
|
15983
16381
|
),
|
|
15984
|
-
|
|
16382
|
+
tool15(
|
|
15985
16383
|
"create_extension_design",
|
|
15986
16384
|
"Create a new extension design linked to a recommended tech assessment (Phase 3: Define Extension Target Solution)",
|
|
15987
16385
|
{
|
|
@@ -16049,7 +16447,7 @@ function createExtensionDesignTools(store) {
|
|
|
16049
16447
|
};
|
|
16050
16448
|
}
|
|
16051
16449
|
),
|
|
16052
|
-
|
|
16450
|
+
tool15(
|
|
16053
16451
|
"update_extension_design",
|
|
16054
16452
|
"Update an existing extension design. The linked tech assessment cannot be changed.",
|
|
16055
16453
|
{
|
|
@@ -16078,10 +16476,10 @@ function createExtensionDesignTools(store) {
|
|
|
16078
16476
|
}
|
|
16079
16477
|
|
|
16080
16478
|
// src/plugins/builtin/tools/aem-reports.ts
|
|
16081
|
-
import { tool as
|
|
16479
|
+
import { tool as tool16 } from "@anthropic-ai/claude-agent-sdk";
|
|
16082
16480
|
function createAemReportTools(store) {
|
|
16083
16481
|
return [
|
|
16084
|
-
|
|
16482
|
+
tool16(
|
|
16085
16483
|
"generate_extension_portfolio",
|
|
16086
16484
|
"Generate a portfolio view of all use cases with their linked tech assessments and extension designs",
|
|
16087
16485
|
{},
|
|
@@ -16133,7 +16531,7 @@ function createAemReportTools(store) {
|
|
|
16133
16531
|
},
|
|
16134
16532
|
{ annotations: { readOnly: true } }
|
|
16135
16533
|
),
|
|
16136
|
-
|
|
16534
|
+
tool16(
|
|
16137
16535
|
"generate_tech_readiness",
|
|
16138
16536
|
"Generate a BTP technology readiness report showing service coverage and gaps across assessments",
|
|
16139
16537
|
{},
|
|
@@ -16185,7 +16583,7 @@ function createAemReportTools(store) {
|
|
|
16185
16583
|
},
|
|
16186
16584
|
{ annotations: { readOnly: true } }
|
|
16187
16585
|
),
|
|
16188
|
-
|
|
16586
|
+
tool16(
|
|
16189
16587
|
"generate_phase_status",
|
|
16190
16588
|
"Generate a phase progress report showing artifact counts and readiness per AEM phase",
|
|
16191
16589
|
{},
|
|
@@ -16247,11 +16645,11 @@ function createAemReportTools(store) {
|
|
|
16247
16645
|
import * as fs6 from "fs";
|
|
16248
16646
|
import * as path6 from "path";
|
|
16249
16647
|
import * as YAML4 from "yaml";
|
|
16250
|
-
import { tool as
|
|
16648
|
+
import { tool as tool17 } from "@anthropic-ai/claude-agent-sdk";
|
|
16251
16649
|
var PHASES = ["assess-use-case", "assess-technology", "define-solution"];
|
|
16252
16650
|
function createAemPhaseTools(store, marvinDir) {
|
|
16253
16651
|
return [
|
|
16254
|
-
|
|
16652
|
+
tool17(
|
|
16255
16653
|
"get_current_phase",
|
|
16256
16654
|
"Get the current AEM phase from project configuration",
|
|
16257
16655
|
{},
|
|
@@ -16272,7 +16670,7 @@ function createAemPhaseTools(store, marvinDir) {
|
|
|
16272
16670
|
},
|
|
16273
16671
|
{ annotations: { readOnly: true } }
|
|
16274
16672
|
),
|
|
16275
|
-
|
|
16673
|
+
tool17(
|
|
16276
16674
|
"advance_phase",
|
|
16277
16675
|
"Advance to the next AEM phase. Performs soft gate checks and warns if artifacts are incomplete, but does not block.",
|
|
16278
16676
|
{
|
|
@@ -16738,7 +17136,7 @@ ${fragment}`);
|
|
|
16738
17136
|
}
|
|
16739
17137
|
|
|
16740
17138
|
// src/skills/action-tools.ts
|
|
16741
|
-
import { tool as
|
|
17139
|
+
import { tool as tool18 } from "@anthropic-ai/claude-agent-sdk";
|
|
16742
17140
|
|
|
16743
17141
|
// src/skills/action-runner.ts
|
|
16744
17142
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
@@ -16828,7 +17226,7 @@ function createSkillActionTools(skills, context) {
|
|
|
16828
17226
|
if (!skill.actions) continue;
|
|
16829
17227
|
for (const action of skill.actions) {
|
|
16830
17228
|
tools.push(
|
|
16831
|
-
|
|
17229
|
+
tool18(
|
|
16832
17230
|
`${skill.id}__${action.id}`,
|
|
16833
17231
|
action.description,
|
|
16834
17232
|
{
|
|
@@ -16877,7 +17275,8 @@ var productOwner = {
|
|
|
16877
17275
|
"Acceptance criteria",
|
|
16878
17276
|
"Feature definition and prioritization"
|
|
16879
17277
|
],
|
|
16880
|
-
documentTypes: ["decision", "question", "action", "feature"]
|
|
17278
|
+
documentTypes: ["decision", "question", "action", "feature"],
|
|
17279
|
+
contributionTypes: ["stakeholder-feedback", "acceptance-result", "priority-change", "market-insight"]
|
|
16881
17280
|
};
|
|
16882
17281
|
|
|
16883
17282
|
// src/personas/builtin/delivery-manager.ts
|
|
@@ -16913,9 +17312,11 @@ var deliveryManager = {
|
|
|
16913
17312
|
"Team coordination",
|
|
16914
17313
|
"Process governance",
|
|
16915
17314
|
"Status tracking",
|
|
16916
|
-
"Epic scheduling and tracking"
|
|
17315
|
+
"Epic scheduling and tracking",
|
|
17316
|
+
"Sprint planning and tracking"
|
|
16917
17317
|
],
|
|
16918
|
-
documentTypes: ["action", "decision", "meeting", "question", "feature", "epic"]
|
|
17318
|
+
documentTypes: ["action", "decision", "meeting", "question", "feature", "epic", "sprint"],
|
|
17319
|
+
contributionTypes: ["risk-finding", "blocker-report", "dependency-update", "status-assessment"]
|
|
16919
17320
|
};
|
|
16920
17321
|
|
|
16921
17322
|
// src/personas/builtin/tech-lead.ts
|
|
@@ -16951,9 +17352,11 @@ var techLead = {
|
|
|
16951
17352
|
"Technical decisions",
|
|
16952
17353
|
"Implementation guidance",
|
|
16953
17354
|
"Non-functional requirements",
|
|
16954
|
-
"Epic creation and scoping"
|
|
17355
|
+
"Epic creation and scoping",
|
|
17356
|
+
"Sprint scoping and technical execution"
|
|
16955
17357
|
],
|
|
16956
|
-
documentTypes: ["decision", "action", "question", "epic"]
|
|
17358
|
+
documentTypes: ["decision", "action", "question", "epic", "sprint"],
|
|
17359
|
+
contributionTypes: ["action-result", "spike-findings", "technical-assessment", "architecture-review"]
|
|
16957
17360
|
};
|
|
16958
17361
|
|
|
16959
17362
|
// src/personas/registry.ts
|
|
@@ -17050,10 +17453,10 @@ ${lines.join("\n\n")}`;
|
|
|
17050
17453
|
}
|
|
17051
17454
|
|
|
17052
17455
|
// src/mcp/persona-tools.ts
|
|
17053
|
-
import { tool as
|
|
17456
|
+
import { tool as tool19 } from "@anthropic-ai/claude-agent-sdk";
|
|
17054
17457
|
function createPersonaTools(ctx, marvinDir) {
|
|
17055
17458
|
return [
|
|
17056
|
-
|
|
17459
|
+
tool19(
|
|
17057
17460
|
"set_persona",
|
|
17058
17461
|
"Set the active persona for this session. Returns full guidance for the selected persona including behavioral rules, allowed document types, and scope. Call this before working to ensure persona-appropriate behavior.",
|
|
17059
17462
|
{
|
|
@@ -17083,7 +17486,7 @@ ${summaries}`
|
|
|
17083
17486
|
};
|
|
17084
17487
|
}
|
|
17085
17488
|
),
|
|
17086
|
-
|
|
17489
|
+
tool19(
|
|
17087
17490
|
"get_persona_guidance",
|
|
17088
17491
|
"Get guidance for a persona without changing the active persona. If no persona is specified, lists all available personas with summaries.",
|
|
17089
17492
|
{
|