mrvn-cli 0.2.4 → 0.2.6
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 +45 -18
- package/dist/index.js +493 -42
- package/dist/index.js.map +1 -1
- package/dist/marvin-serve.js +489 -40
- package/dist/marvin-serve.js.map +1 -1
- package/dist/marvin.js +518 -67
- 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) => {
|
|
@@ -15646,13 +15700,369 @@ function createContributionTools(store) {
|
|
|
15646
15700
|
];
|
|
15647
15701
|
}
|
|
15648
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
|
+
|
|
15876
|
+
// src/plugins/builtin/tools/sprint-planning.ts
|
|
15877
|
+
import { tool as tool13 } from "@anthropic-ai/claude-agent-sdk";
|
|
15878
|
+
var PRIORITY_ORDER = {
|
|
15879
|
+
critical: 0,
|
|
15880
|
+
high: 1,
|
|
15881
|
+
medium: 2,
|
|
15882
|
+
low: 3
|
|
15883
|
+
};
|
|
15884
|
+
function priorityRank(p) {
|
|
15885
|
+
return PRIORITY_ORDER[p ?? ""] ?? 99;
|
|
15886
|
+
}
|
|
15887
|
+
function createSprintPlanningTools(store) {
|
|
15888
|
+
return [
|
|
15889
|
+
tool13(
|
|
15890
|
+
"gather_sprint_planning_context",
|
|
15891
|
+
"Aggregate all planning-relevant data for proposing the next sprint: approved features, backlog epics, active sprint, velocity reference, blockers, and summary stats",
|
|
15892
|
+
{
|
|
15893
|
+
focusFeature: external_exports.string().optional().describe("Filter backlog to epics of a specific feature ID (e.g. 'F-001')"),
|
|
15894
|
+
sprintDurationDays: external_exports.number().optional().describe("Expected sprint duration in days \u2014 passed through for capacity reasoning")
|
|
15895
|
+
},
|
|
15896
|
+
async (args) => {
|
|
15897
|
+
const features = store.list({ type: "feature" });
|
|
15898
|
+
const epics = store.list({ type: "epic" });
|
|
15899
|
+
const sprints = store.list({ type: "sprint" });
|
|
15900
|
+
const questions = store.list({ type: "question", status: "open" });
|
|
15901
|
+
const contributions = store.list({ type: "contribution" });
|
|
15902
|
+
const approvedFeatures = features.filter((f) => f.frontmatter.status === "approved").sort((a, b) => priorityRank(a.frontmatter.priority) - priorityRank(b.frontmatter.priority)).map((f) => {
|
|
15903
|
+
const linkedEpics = epics.filter((e) => e.frontmatter.linkedFeature === f.frontmatter.id);
|
|
15904
|
+
const epicsByStatus = {};
|
|
15905
|
+
for (const e of linkedEpics) {
|
|
15906
|
+
epicsByStatus[e.frontmatter.status] = (epicsByStatus[e.frontmatter.status] ?? 0) + 1;
|
|
15907
|
+
}
|
|
15908
|
+
return {
|
|
15909
|
+
id: f.frontmatter.id,
|
|
15910
|
+
title: f.frontmatter.title,
|
|
15911
|
+
priority: f.frontmatter.priority,
|
|
15912
|
+
owner: f.frontmatter.owner,
|
|
15913
|
+
epicCount: linkedEpics.length,
|
|
15914
|
+
epicsByStatus
|
|
15915
|
+
};
|
|
15916
|
+
});
|
|
15917
|
+
const assignedEpicIds = /* @__PURE__ */ new Set();
|
|
15918
|
+
for (const sp of sprints) {
|
|
15919
|
+
const linked = sp.frontmatter.linkedEpics ?? [];
|
|
15920
|
+
for (const id of linked) assignedEpicIds.add(id);
|
|
15921
|
+
}
|
|
15922
|
+
const featureMap = new Map(features.map((f) => [f.frontmatter.id, f]));
|
|
15923
|
+
let backlogEpics = epics.filter(
|
|
15924
|
+
(e) => !assignedEpicIds.has(e.frontmatter.id) && e.frontmatter.status !== "done"
|
|
15925
|
+
);
|
|
15926
|
+
if (args.focusFeature) {
|
|
15927
|
+
backlogEpics = backlogEpics.filter(
|
|
15928
|
+
(e) => e.frontmatter.linkedFeature === args.focusFeature
|
|
15929
|
+
);
|
|
15930
|
+
}
|
|
15931
|
+
const backlog = backlogEpics.sort((a, b) => {
|
|
15932
|
+
const fa = featureMap.get(a.frontmatter.linkedFeature);
|
|
15933
|
+
const fb = featureMap.get(b.frontmatter.linkedFeature);
|
|
15934
|
+
return priorityRank(fa?.frontmatter.priority) - priorityRank(fb?.frontmatter.priority);
|
|
15935
|
+
}).map((e) => {
|
|
15936
|
+
const parent = featureMap.get(e.frontmatter.linkedFeature);
|
|
15937
|
+
return {
|
|
15938
|
+
id: e.frontmatter.id,
|
|
15939
|
+
title: e.frontmatter.title,
|
|
15940
|
+
status: e.frontmatter.status,
|
|
15941
|
+
linkedFeature: e.frontmatter.linkedFeature,
|
|
15942
|
+
featureTitle: parent?.frontmatter.title ?? null,
|
|
15943
|
+
featurePriority: parent?.frontmatter.priority ?? null,
|
|
15944
|
+
estimatedEffort: e.frontmatter.estimatedEffort ?? null,
|
|
15945
|
+
targetDate: e.frontmatter.targetDate ?? null
|
|
15946
|
+
};
|
|
15947
|
+
});
|
|
15948
|
+
const activeSprintDoc = sprints.find((s) => s.frontmatter.status === "active") ?? null;
|
|
15949
|
+
let activeSprint = null;
|
|
15950
|
+
if (activeSprintDoc) {
|
|
15951
|
+
const linkedEpicIds = activeSprintDoc.frontmatter.linkedEpics ?? [];
|
|
15952
|
+
const linkedEpics = linkedEpicIds.map((epicId) => {
|
|
15953
|
+
const epic = store.get(epicId);
|
|
15954
|
+
return epic ? { id: epicId, title: epic.frontmatter.title, status: epic.frontmatter.status } : { id: epicId, title: "(not found)", status: "unknown" };
|
|
15955
|
+
});
|
|
15956
|
+
const allDocs = store.list();
|
|
15957
|
+
const sprintTag = `sprint:${activeSprintDoc.frontmatter.id}`;
|
|
15958
|
+
const workItems = allDocs.filter(
|
|
15959
|
+
(d) => d.frontmatter.type !== "sprint" && d.frontmatter.type !== "epic" && d.frontmatter.tags?.includes(sprintTag)
|
|
15960
|
+
);
|
|
15961
|
+
const doneCount = workItems.filter(
|
|
15962
|
+
(d) => d.frontmatter.status === "done" || d.frontmatter.status === "resolved" || d.frontmatter.status === "closed"
|
|
15963
|
+
).length;
|
|
15964
|
+
const completionPct = workItems.length > 0 ? Math.round(doneCount / workItems.length * 100) : 0;
|
|
15965
|
+
activeSprint = {
|
|
15966
|
+
id: activeSprintDoc.frontmatter.id,
|
|
15967
|
+
title: activeSprintDoc.frontmatter.title,
|
|
15968
|
+
goal: activeSprintDoc.frontmatter.goal,
|
|
15969
|
+
startDate: activeSprintDoc.frontmatter.startDate,
|
|
15970
|
+
endDate: activeSprintDoc.frontmatter.endDate,
|
|
15971
|
+
linkedEpics,
|
|
15972
|
+
workItems: { total: workItems.length, done: doneCount, completionPct }
|
|
15973
|
+
};
|
|
15974
|
+
}
|
|
15975
|
+
const completedSprints = sprints.filter((s) => s.frontmatter.status === "completed").sort((a, b) => {
|
|
15976
|
+
const da = a.frontmatter.endDate ?? "";
|
|
15977
|
+
const db = b.frontmatter.endDate ?? "";
|
|
15978
|
+
return da < db ? 1 : da > db ? -1 : 0;
|
|
15979
|
+
}).slice(0, 2);
|
|
15980
|
+
const velocityReference = completedSprints.map((sp) => {
|
|
15981
|
+
const linkedEpicIds = sp.frontmatter.linkedEpics ?? [];
|
|
15982
|
+
const efforts = [];
|
|
15983
|
+
for (const epicId of linkedEpicIds) {
|
|
15984
|
+
const epic = store.get(epicId);
|
|
15985
|
+
if (epic?.frontmatter.estimatedEffort) {
|
|
15986
|
+
efforts.push(String(epic.frontmatter.estimatedEffort));
|
|
15987
|
+
}
|
|
15988
|
+
}
|
|
15989
|
+
const allDocs = store.list();
|
|
15990
|
+
const sprintTag = `sprint:${sp.frontmatter.id}`;
|
|
15991
|
+
const workItems = allDocs.filter(
|
|
15992
|
+
(d) => d.frontmatter.type !== "sprint" && d.frontmatter.type !== "epic" && d.frontmatter.tags?.includes(sprintTag)
|
|
15993
|
+
);
|
|
15994
|
+
return {
|
|
15995
|
+
id: sp.frontmatter.id,
|
|
15996
|
+
title: sp.frontmatter.title,
|
|
15997
|
+
startDate: sp.frontmatter.startDate,
|
|
15998
|
+
endDate: sp.frontmatter.endDate,
|
|
15999
|
+
epicCount: linkedEpicIds.length,
|
|
16000
|
+
efforts,
|
|
16001
|
+
workItemCount: workItems.length
|
|
16002
|
+
};
|
|
16003
|
+
});
|
|
16004
|
+
const openBlockerContributions = contributions.filter(
|
|
16005
|
+
(c) => c.frontmatter.status === "open" && (c.frontmatter.contributionType === "risk-finding" || c.frontmatter.contributionType === "blocker-report")
|
|
16006
|
+
);
|
|
16007
|
+
const blockers = {
|
|
16008
|
+
openQuestions: questions.map((q) => ({
|
|
16009
|
+
id: q.frontmatter.id,
|
|
16010
|
+
title: q.frontmatter.title
|
|
16011
|
+
})),
|
|
16012
|
+
openRiskAndBlockerContributions: openBlockerContributions.map((c) => ({
|
|
16013
|
+
id: c.frontmatter.id,
|
|
16014
|
+
title: c.frontmatter.title,
|
|
16015
|
+
contributionType: c.frontmatter.contributionType
|
|
16016
|
+
}))
|
|
16017
|
+
};
|
|
16018
|
+
const totalBacklogEfforts = backlog.filter((e) => e.estimatedEffort !== null).map((e) => String(e.estimatedEffort));
|
|
16019
|
+
const approvedFeaturesWithNoEpics = approvedFeatures.filter((f) => f.epicCount === 0).map((f) => ({ id: f.id, title: f.title }));
|
|
16020
|
+
const now = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
16021
|
+
const epicsAtRisk = epics.filter((e) => {
|
|
16022
|
+
if (e.frontmatter.status === "done") return false;
|
|
16023
|
+
if (e.frontmatter.targetDate && e.frontmatter.targetDate < now) return true;
|
|
16024
|
+
const parent = featureMap.get(e.frontmatter.linkedFeature);
|
|
16025
|
+
if (parent?.frontmatter.status === "deferred") return true;
|
|
16026
|
+
return false;
|
|
16027
|
+
}).map((e) => ({
|
|
16028
|
+
id: e.frontmatter.id,
|
|
16029
|
+
title: e.frontmatter.title,
|
|
16030
|
+
reason: e.frontmatter.targetDate && e.frontmatter.targetDate < now ? "past-target-date" : "deferred-feature"
|
|
16031
|
+
}));
|
|
16032
|
+
const plannedSprintCount = sprints.filter((s) => s.frontmatter.status === "planned").length;
|
|
16033
|
+
const summary = {
|
|
16034
|
+
totalBacklogEpics: backlog.length,
|
|
16035
|
+
totalBacklogEfforts,
|
|
16036
|
+
approvedFeaturesWithNoEpics,
|
|
16037
|
+
epicsAtRisk,
|
|
16038
|
+
plannedSprintCount
|
|
16039
|
+
};
|
|
16040
|
+
const result = {
|
|
16041
|
+
approvedFeatures,
|
|
16042
|
+
backlog,
|
|
16043
|
+
activeSprint,
|
|
16044
|
+
velocityReference,
|
|
16045
|
+
blockers,
|
|
16046
|
+
summary,
|
|
16047
|
+
...args.sprintDurationDays !== void 0 ? { sprintDurationDays: args.sprintDurationDays } : {}
|
|
16048
|
+
};
|
|
16049
|
+
return {
|
|
16050
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
16051
|
+
};
|
|
16052
|
+
},
|
|
16053
|
+
{ annotations: { readOnly: true } }
|
|
16054
|
+
)
|
|
16055
|
+
];
|
|
16056
|
+
}
|
|
16057
|
+
|
|
15649
16058
|
// src/plugins/common.ts
|
|
15650
16059
|
var COMMON_REGISTRATIONS = [
|
|
15651
16060
|
{ type: "meeting", dirName: "meetings", idPrefix: "M" },
|
|
15652
16061
|
{ type: "report", dirName: "reports", idPrefix: "R" },
|
|
15653
16062
|
{ type: "feature", dirName: "features", idPrefix: "F" },
|
|
15654
16063
|
{ type: "epic", dirName: "epics", idPrefix: "E" },
|
|
15655
|
-
{ type: "contribution", dirName: "contributions", idPrefix: "C" }
|
|
16064
|
+
{ type: "contribution", dirName: "contributions", idPrefix: "C" },
|
|
16065
|
+
{ type: "sprint", dirName: "sprints", idPrefix: "SP" }
|
|
15656
16066
|
];
|
|
15657
16067
|
function createCommonTools(store) {
|
|
15658
16068
|
return [
|
|
@@ -15660,7 +16070,9 @@ function createCommonTools(store) {
|
|
|
15660
16070
|
...createReportTools(store),
|
|
15661
16071
|
...createFeatureTools(store),
|
|
15662
16072
|
...createEpicTools(store),
|
|
15663
|
-
...createContributionTools(store)
|
|
16073
|
+
...createContributionTools(store),
|
|
16074
|
+
...createSprintTools(store),
|
|
16075
|
+
...createSprintPlanningTools(store)
|
|
15664
16076
|
];
|
|
15665
16077
|
}
|
|
15666
16078
|
|
|
@@ -15670,7 +16082,7 @@ var genericAgilePlugin = {
|
|
|
15670
16082
|
name: "Generic Agile",
|
|
15671
16083
|
description: "Default methodology plugin providing standard agile governance patterns for decisions, actions, and questions.",
|
|
15672
16084
|
version: "0.1.0",
|
|
15673
|
-
documentTypes: ["decision", "action", "question", "meeting", "report", "feature", "epic", "contribution"],
|
|
16085
|
+
documentTypes: ["decision", "action", "question", "meeting", "report", "feature", "epic", "contribution", "sprint"],
|
|
15674
16086
|
documentTypeRegistrations: [...COMMON_REGISTRATIONS],
|
|
15675
16087
|
tools: (store) => [...createCommonTools(store)],
|
|
15676
16088
|
promptFragments: {
|
|
@@ -15697,7 +16109,10 @@ var genericAgilePlugin = {
|
|
|
15697
16109
|
- **list_contributions** / **get_contribution**: Browse and read contribution records.
|
|
15698
16110
|
- **create_contribution**: Record a contribution with persona, type, and optional related artifact.
|
|
15699
16111
|
- **update_contribution**: Update a contribution (e.g. append effects).
|
|
15700
|
-
- Available contribution types: stakeholder-feedback, acceptance-result, priority-change, market-insight
|
|
16112
|
+
- Available contribution types: stakeholder-feedback, acceptance-result, priority-change, market-insight.
|
|
16113
|
+
|
|
16114
|
+
**Sprint Tools (read-only for awareness):**
|
|
16115
|
+
- **list_sprints** / **get_sprint**: View sprints to understand delivery timelines and iteration scope.`,
|
|
15701
16116
|
"tech-lead": `You own epics and break approved features into implementation work.
|
|
15702
16117
|
|
|
15703
16118
|
**Epic Tools:**
|
|
@@ -15724,7 +16139,18 @@ var genericAgilePlugin = {
|
|
|
15724
16139
|
- **list_contributions** / **get_contribution**: Browse and read contribution records.
|
|
15725
16140
|
- **create_contribution**: Record a contribution with persona, type, and optional related artifact.
|
|
15726
16141
|
- **update_contribution**: Update a contribution (e.g. append effects).
|
|
15727
|
-
- Available contribution types: action-result, spike-findings, technical-assessment, architecture-review
|
|
16142
|
+
- Available contribution types: action-result, spike-findings, technical-assessment, architecture-review.
|
|
16143
|
+
|
|
16144
|
+
**Sprint Tools:**
|
|
16145
|
+
- **list_sprints** / **get_sprint**: View sprints to understand iteration scope and delivery dates.
|
|
16146
|
+
- **update_sprint**: Assign epics to sprints by updating linkedEpics when breaking features into work.
|
|
16147
|
+
- Tag technical actions and decisions with \`sprint:SP-xxx\` to associate them with a sprint.
|
|
16148
|
+
- Use **generate_sprint_progress** to track technical work completion within an iteration.
|
|
16149
|
+
|
|
16150
|
+
**Sprint Planning:**
|
|
16151
|
+
- When asked to plan or propose a sprint, ALWAYS call **gather_sprint_planning_context** first.
|
|
16152
|
+
- Focus on: technical readiness of each epic, open technical questions or spikes, effort balance across the sprint, and feature coverage.
|
|
16153
|
+
- Present a structured sprint proposal with technical rationale for each selected epic, known technical risks, and any prerequisite work that should be completed first.`,
|
|
15728
16154
|
"delivery-manager": `You track delivery across features and epics, manage schedules, and report on progress.
|
|
15729
16155
|
|
|
15730
16156
|
**Report Tools:**
|
|
@@ -15758,14 +16184,35 @@ var genericAgilePlugin = {
|
|
|
15758
16184
|
- **list_contributions** / **get_contribution**: Browse and read contribution records.
|
|
15759
16185
|
- **create_contribution**: Record a contribution with persona, type, and optional related artifact.
|
|
15760
16186
|
- **update_contribution**: Update a contribution (e.g. append effects).
|
|
15761
|
-
- Available contribution types: risk-finding, blocker-report, dependency-update, status-assessment
|
|
15762
|
-
|
|
16187
|
+
- Available contribution types: risk-finding, blocker-report, dependency-update, status-assessment.
|
|
16188
|
+
|
|
16189
|
+
**Sprint Tools:**
|
|
16190
|
+
- **list_sprints** / **get_sprint**: Browse and read sprint definitions.
|
|
16191
|
+
- **create_sprint**: Create sprints with dates, goals, and linked epics. Use status "planned" for upcoming sprints or "active"/"completed"/"cancelled" for current/past sprints.
|
|
16192
|
+
- **update_sprint**: Update sprint status, dates, goal, or linked epics. When linkedEpics changes, affected epics are re-tagged automatically.
|
|
16193
|
+
- **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 %.
|
|
16194
|
+
- Use \`save_report\` with reportType "sprint-progress" to persist sprint reports.
|
|
16195
|
+
|
|
16196
|
+
**Sprint Workflow:**
|
|
16197
|
+
- Create sprints with clear goals and date boundaries.
|
|
16198
|
+
- Assign epics to sprints via linkedEpics.
|
|
16199
|
+
- Tag work items (actions, decisions, questions) with \`sprint:SP-xxx\` for sprint scoping.
|
|
16200
|
+
- Track delivery dates and flag at-risk sprints.
|
|
16201
|
+
- Register past/completed sprints for historical tracking.
|
|
16202
|
+
|
|
16203
|
+
**Sprint Planning:**
|
|
16204
|
+
- When asked to plan or propose a sprint, ALWAYS call **gather_sprint_planning_context** first. It aggregates approved features, backlog epics, active sprint status, velocity from recent sprints, blockers, and summary stats in one call.
|
|
16205
|
+
- Reason through: priority (critical/high features first), capacity (compare backlog effort to velocity reference), dependencies and blockers, balance across features, and risk.
|
|
16206
|
+
- Present a structured sprint proposal: title, goal, suggested dates, selected epics with rationale for each, excluded epics with reason, and identified risks.
|
|
16207
|
+
- After user confirmation, use **create_sprint** with the agreed epics to persist the sprint.`,
|
|
16208
|
+
"*": `You have access to feature, epic, sprint, and meeting tools for project coordination:
|
|
15763
16209
|
|
|
15764
16210
|
**Features** (F-xxx): Product capabilities defined by the Product Owner. Features progress through draft \u2192 approved \u2192 done.
|
|
15765
16211
|
**Epics** (E-xxx): Implementation work packages created by the Tech Lead, linked to approved features. Epics progress through planned \u2192 in-progress \u2192 done.
|
|
16212
|
+
**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).
|
|
15766
16213
|
**Meetings**: Meeting records with attendees, agendas, and notes.
|
|
15767
16214
|
|
|
15768
|
-
**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,
|
|
16215
|
+
**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.
|
|
15769
16216
|
|
|
15770
16217
|
- **list_meetings** / **get_meeting**: Browse and read meeting records.
|
|
15771
16218
|
- **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.
|
|
@@ -15780,10 +16227,10 @@ var genericAgilePlugin = {
|
|
|
15780
16227
|
};
|
|
15781
16228
|
|
|
15782
16229
|
// src/plugins/builtin/tools/use-cases.ts
|
|
15783
|
-
import { tool as
|
|
16230
|
+
import { tool as tool14 } from "@anthropic-ai/claude-agent-sdk";
|
|
15784
16231
|
function createUseCaseTools(store) {
|
|
15785
16232
|
return [
|
|
15786
|
-
|
|
16233
|
+
tool14(
|
|
15787
16234
|
"list_use_cases",
|
|
15788
16235
|
"List all extension use cases, optionally filtered by status or extension type",
|
|
15789
16236
|
{
|
|
@@ -15813,7 +16260,7 @@ function createUseCaseTools(store) {
|
|
|
15813
16260
|
},
|
|
15814
16261
|
{ annotations: { readOnly: true } }
|
|
15815
16262
|
),
|
|
15816
|
-
|
|
16263
|
+
tool14(
|
|
15817
16264
|
"get_use_case",
|
|
15818
16265
|
"Get the full content of a specific use case by ID",
|
|
15819
16266
|
{ id: external_exports.string().describe("Use case ID (e.g. 'UC-001')") },
|
|
@@ -15840,7 +16287,7 @@ function createUseCaseTools(store) {
|
|
|
15840
16287
|
},
|
|
15841
16288
|
{ annotations: { readOnly: true } }
|
|
15842
16289
|
),
|
|
15843
|
-
|
|
16290
|
+
tool14(
|
|
15844
16291
|
"create_use_case",
|
|
15845
16292
|
"Create a new extension use case definition (Phase 1: Assess Extension Use Case)",
|
|
15846
16293
|
{
|
|
@@ -15874,7 +16321,7 @@ function createUseCaseTools(store) {
|
|
|
15874
16321
|
};
|
|
15875
16322
|
}
|
|
15876
16323
|
),
|
|
15877
|
-
|
|
16324
|
+
tool14(
|
|
15878
16325
|
"update_use_case",
|
|
15879
16326
|
"Update an existing extension use case",
|
|
15880
16327
|
{
|
|
@@ -15904,10 +16351,10 @@ function createUseCaseTools(store) {
|
|
|
15904
16351
|
}
|
|
15905
16352
|
|
|
15906
16353
|
// src/plugins/builtin/tools/tech-assessments.ts
|
|
15907
|
-
import { tool as
|
|
16354
|
+
import { tool as tool15 } from "@anthropic-ai/claude-agent-sdk";
|
|
15908
16355
|
function createTechAssessmentTools(store) {
|
|
15909
16356
|
return [
|
|
15910
|
-
|
|
16357
|
+
tool15(
|
|
15911
16358
|
"list_tech_assessments",
|
|
15912
16359
|
"List all technology assessments, optionally filtered by status",
|
|
15913
16360
|
{
|
|
@@ -15938,7 +16385,7 @@ function createTechAssessmentTools(store) {
|
|
|
15938
16385
|
},
|
|
15939
16386
|
{ annotations: { readOnly: true } }
|
|
15940
16387
|
),
|
|
15941
|
-
|
|
16388
|
+
tool15(
|
|
15942
16389
|
"get_tech_assessment",
|
|
15943
16390
|
"Get the full content of a specific technology assessment by ID",
|
|
15944
16391
|
{ id: external_exports.string().describe("Tech assessment ID (e.g. 'TA-001')") },
|
|
@@ -15965,7 +16412,7 @@ function createTechAssessmentTools(store) {
|
|
|
15965
16412
|
},
|
|
15966
16413
|
{ annotations: { readOnly: true } }
|
|
15967
16414
|
),
|
|
15968
|
-
|
|
16415
|
+
tool15(
|
|
15969
16416
|
"create_tech_assessment",
|
|
15970
16417
|
"Create a new technology assessment linked to an assessed/approved use case (Phase 2: Assess Extension Technology)",
|
|
15971
16418
|
{
|
|
@@ -16036,7 +16483,7 @@ function createTechAssessmentTools(store) {
|
|
|
16036
16483
|
};
|
|
16037
16484
|
}
|
|
16038
16485
|
),
|
|
16039
|
-
|
|
16486
|
+
tool15(
|
|
16040
16487
|
"update_tech_assessment",
|
|
16041
16488
|
"Update an existing technology assessment. The linked use case cannot be changed.",
|
|
16042
16489
|
{
|
|
@@ -16066,10 +16513,10 @@ function createTechAssessmentTools(store) {
|
|
|
16066
16513
|
}
|
|
16067
16514
|
|
|
16068
16515
|
// src/plugins/builtin/tools/extension-designs.ts
|
|
16069
|
-
import { tool as
|
|
16516
|
+
import { tool as tool16 } from "@anthropic-ai/claude-agent-sdk";
|
|
16070
16517
|
function createExtensionDesignTools(store) {
|
|
16071
16518
|
return [
|
|
16072
|
-
|
|
16519
|
+
tool16(
|
|
16073
16520
|
"list_extension_designs",
|
|
16074
16521
|
"List all extension designs, optionally filtered by status",
|
|
16075
16522
|
{
|
|
@@ -16099,7 +16546,7 @@ function createExtensionDesignTools(store) {
|
|
|
16099
16546
|
},
|
|
16100
16547
|
{ annotations: { readOnly: true } }
|
|
16101
16548
|
),
|
|
16102
|
-
|
|
16549
|
+
tool16(
|
|
16103
16550
|
"get_extension_design",
|
|
16104
16551
|
"Get the full content of a specific extension design by ID",
|
|
16105
16552
|
{ id: external_exports.string().describe("Extension design ID (e.g. 'XD-001')") },
|
|
@@ -16126,7 +16573,7 @@ function createExtensionDesignTools(store) {
|
|
|
16126
16573
|
},
|
|
16127
16574
|
{ annotations: { readOnly: true } }
|
|
16128
16575
|
),
|
|
16129
|
-
|
|
16576
|
+
tool16(
|
|
16130
16577
|
"create_extension_design",
|
|
16131
16578
|
"Create a new extension design linked to a recommended tech assessment (Phase 3: Define Extension Target Solution)",
|
|
16132
16579
|
{
|
|
@@ -16194,7 +16641,7 @@ function createExtensionDesignTools(store) {
|
|
|
16194
16641
|
};
|
|
16195
16642
|
}
|
|
16196
16643
|
),
|
|
16197
|
-
|
|
16644
|
+
tool16(
|
|
16198
16645
|
"update_extension_design",
|
|
16199
16646
|
"Update an existing extension design. The linked tech assessment cannot be changed.",
|
|
16200
16647
|
{
|
|
@@ -16223,10 +16670,10 @@ function createExtensionDesignTools(store) {
|
|
|
16223
16670
|
}
|
|
16224
16671
|
|
|
16225
16672
|
// src/plugins/builtin/tools/aem-reports.ts
|
|
16226
|
-
import { tool as
|
|
16673
|
+
import { tool as tool17 } from "@anthropic-ai/claude-agent-sdk";
|
|
16227
16674
|
function createAemReportTools(store) {
|
|
16228
16675
|
return [
|
|
16229
|
-
|
|
16676
|
+
tool17(
|
|
16230
16677
|
"generate_extension_portfolio",
|
|
16231
16678
|
"Generate a portfolio view of all use cases with their linked tech assessments and extension designs",
|
|
16232
16679
|
{},
|
|
@@ -16278,7 +16725,7 @@ function createAemReportTools(store) {
|
|
|
16278
16725
|
},
|
|
16279
16726
|
{ annotations: { readOnly: true } }
|
|
16280
16727
|
),
|
|
16281
|
-
|
|
16728
|
+
tool17(
|
|
16282
16729
|
"generate_tech_readiness",
|
|
16283
16730
|
"Generate a BTP technology readiness report showing service coverage and gaps across assessments",
|
|
16284
16731
|
{},
|
|
@@ -16330,7 +16777,7 @@ function createAemReportTools(store) {
|
|
|
16330
16777
|
},
|
|
16331
16778
|
{ annotations: { readOnly: true } }
|
|
16332
16779
|
),
|
|
16333
|
-
|
|
16780
|
+
tool17(
|
|
16334
16781
|
"generate_phase_status",
|
|
16335
16782
|
"Generate a phase progress report showing artifact counts and readiness per AEM phase",
|
|
16336
16783
|
{},
|
|
@@ -16392,11 +16839,11 @@ function createAemReportTools(store) {
|
|
|
16392
16839
|
import * as fs6 from "fs";
|
|
16393
16840
|
import * as path6 from "path";
|
|
16394
16841
|
import * as YAML4 from "yaml";
|
|
16395
|
-
import { tool as
|
|
16842
|
+
import { tool as tool18 } from "@anthropic-ai/claude-agent-sdk";
|
|
16396
16843
|
var PHASES = ["assess-use-case", "assess-technology", "define-solution"];
|
|
16397
16844
|
function createAemPhaseTools(store, marvinDir) {
|
|
16398
16845
|
return [
|
|
16399
|
-
|
|
16846
|
+
tool18(
|
|
16400
16847
|
"get_current_phase",
|
|
16401
16848
|
"Get the current AEM phase from project configuration",
|
|
16402
16849
|
{},
|
|
@@ -16417,7 +16864,7 @@ function createAemPhaseTools(store, marvinDir) {
|
|
|
16417
16864
|
},
|
|
16418
16865
|
{ annotations: { readOnly: true } }
|
|
16419
16866
|
),
|
|
16420
|
-
|
|
16867
|
+
tool18(
|
|
16421
16868
|
"advance_phase",
|
|
16422
16869
|
"Advance to the next AEM phase. Performs soft gate checks and warns if artifacts are incomplete, but does not block.",
|
|
16423
16870
|
{
|
|
@@ -16883,7 +17330,7 @@ ${fragment}`);
|
|
|
16883
17330
|
}
|
|
16884
17331
|
|
|
16885
17332
|
// src/skills/action-tools.ts
|
|
16886
|
-
import { tool as
|
|
17333
|
+
import { tool as tool19 } from "@anthropic-ai/claude-agent-sdk";
|
|
16887
17334
|
|
|
16888
17335
|
// src/skills/action-runner.ts
|
|
16889
17336
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
@@ -16973,7 +17420,7 @@ function createSkillActionTools(skills, context) {
|
|
|
16973
17420
|
if (!skill.actions) continue;
|
|
16974
17421
|
for (const action of skill.actions) {
|
|
16975
17422
|
tools.push(
|
|
16976
|
-
|
|
17423
|
+
tool19(
|
|
16977
17424
|
`${skill.id}__${action.id}`,
|
|
16978
17425
|
action.description,
|
|
16979
17426
|
{
|
|
@@ -17059,9 +17506,10 @@ var deliveryManager = {
|
|
|
17059
17506
|
"Team coordination",
|
|
17060
17507
|
"Process governance",
|
|
17061
17508
|
"Status tracking",
|
|
17062
|
-
"Epic scheduling and tracking"
|
|
17509
|
+
"Epic scheduling and tracking",
|
|
17510
|
+
"Sprint planning and tracking"
|
|
17063
17511
|
],
|
|
17064
|
-
documentTypes: ["action", "decision", "meeting", "question", "feature", "epic"],
|
|
17512
|
+
documentTypes: ["action", "decision", "meeting", "question", "feature", "epic", "sprint"],
|
|
17065
17513
|
contributionTypes: ["risk-finding", "blocker-report", "dependency-update", "status-assessment"]
|
|
17066
17514
|
};
|
|
17067
17515
|
|
|
@@ -17098,9 +17546,10 @@ var techLead = {
|
|
|
17098
17546
|
"Technical decisions",
|
|
17099
17547
|
"Implementation guidance",
|
|
17100
17548
|
"Non-functional requirements",
|
|
17101
|
-
"Epic creation and scoping"
|
|
17549
|
+
"Epic creation and scoping",
|
|
17550
|
+
"Sprint scoping and technical execution"
|
|
17102
17551
|
],
|
|
17103
|
-
documentTypes: ["decision", "action", "question", "epic"],
|
|
17552
|
+
documentTypes: ["decision", "action", "question", "epic", "sprint"],
|
|
17104
17553
|
contributionTypes: ["action-result", "spike-findings", "technical-assessment", "architecture-review"]
|
|
17105
17554
|
};
|
|
17106
17555
|
|
|
@@ -17198,10 +17647,10 @@ ${lines.join("\n\n")}`;
|
|
|
17198
17647
|
}
|
|
17199
17648
|
|
|
17200
17649
|
// src/mcp/persona-tools.ts
|
|
17201
|
-
import { tool as
|
|
17650
|
+
import { tool as tool20 } from "@anthropic-ai/claude-agent-sdk";
|
|
17202
17651
|
function createPersonaTools(ctx, marvinDir) {
|
|
17203
17652
|
return [
|
|
17204
|
-
|
|
17653
|
+
tool20(
|
|
17205
17654
|
"set_persona",
|
|
17206
17655
|
"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.",
|
|
17207
17656
|
{
|
|
@@ -17231,7 +17680,7 @@ ${summaries}`
|
|
|
17231
17680
|
};
|
|
17232
17681
|
}
|
|
17233
17682
|
),
|
|
17234
|
-
|
|
17683
|
+
tool20(
|
|
17235
17684
|
"get_persona_guidance",
|
|
17236
17685
|
"Get guidance for a persona without changing the active persona. If no persona is specified, lists all available personas with summaries.",
|
|
17237
17686
|
{
|