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/index.js
CHANGED
|
@@ -438,9 +438,10 @@ var deliveryManager = {
|
|
|
438
438
|
"Team coordination",
|
|
439
439
|
"Process governance",
|
|
440
440
|
"Status tracking",
|
|
441
|
-
"Epic scheduling and tracking"
|
|
441
|
+
"Epic scheduling and tracking",
|
|
442
|
+
"Sprint planning and tracking"
|
|
442
443
|
],
|
|
443
|
-
documentTypes: ["action", "decision", "meeting", "question", "feature", "epic"],
|
|
444
|
+
documentTypes: ["action", "decision", "meeting", "question", "feature", "epic", "sprint"],
|
|
444
445
|
contributionTypes: ["risk-finding", "blocker-report", "dependency-update", "status-assessment"]
|
|
445
446
|
};
|
|
446
447
|
|
|
@@ -477,9 +478,10 @@ var techLead = {
|
|
|
477
478
|
"Technical decisions",
|
|
478
479
|
"Implementation guidance",
|
|
479
480
|
"Non-functional requirements",
|
|
480
|
-
"Epic creation and scoping"
|
|
481
|
+
"Epic creation and scoping",
|
|
482
|
+
"Sprint scoping and technical execution"
|
|
481
483
|
],
|
|
482
|
-
documentTypes: ["decision", "action", "question", "epic"],
|
|
484
|
+
documentTypes: ["decision", "action", "question", "epic", "sprint"],
|
|
483
485
|
contributionTypes: ["action-result", "spike-findings", "technical-assessment", "architecture-review"]
|
|
484
486
|
};
|
|
485
487
|
|
|
@@ -528,6 +530,7 @@ You have access to governance tools for managing project artifacts:
|
|
|
528
530
|
- **Questions** (Q-xxx): List, get, create, and update questions
|
|
529
531
|
- **Features** (F-xxx): List, get, create, and update feature definitions
|
|
530
532
|
- **Epics** (E-xxx): List, get, create, and update implementation epics (must link to approved features)
|
|
533
|
+
- **Sprints** (SP-xxx): List, get, create, and update time-boxed iterations with linked epics and delivery dates
|
|
531
534
|
- **Documents**: Search and read any project document
|
|
532
535
|
- **Sources**: List source documents and view their processing status and derived artifacts
|
|
533
536
|
|
|
@@ -15511,6 +15514,60 @@ function createReportTools(store) {
|
|
|
15511
15514
|
},
|
|
15512
15515
|
{ annotations: { readOnly: true } }
|
|
15513
15516
|
),
|
|
15517
|
+
tool8(
|
|
15518
|
+
"generate_sprint_progress",
|
|
15519
|
+
"Generate progress report for a sprint or all sprints, showing linked epics and tagged work items",
|
|
15520
|
+
{
|
|
15521
|
+
sprint: external_exports.string().optional().describe("Specific sprint ID (e.g. 'SP-001') or omit for all")
|
|
15522
|
+
},
|
|
15523
|
+
async (args) => {
|
|
15524
|
+
const allDocs = store.list();
|
|
15525
|
+
const sprintDocs = store.list({ type: "sprint" });
|
|
15526
|
+
const sprints = sprintDocs.filter((s) => !args.sprint || s.frontmatter.id === args.sprint).map((sprintDoc) => {
|
|
15527
|
+
const sprintId = sprintDoc.frontmatter.id;
|
|
15528
|
+
const linkedEpicIds = sprintDoc.frontmatter.linkedEpics ?? [];
|
|
15529
|
+
const linkedEpics = linkedEpicIds.map((epicId) => {
|
|
15530
|
+
const epic = store.get(epicId);
|
|
15531
|
+
return epic ? { id: epicId, title: epic.frontmatter.title, status: epic.frontmatter.status } : { id: epicId, title: "(not found)", status: "unknown" };
|
|
15532
|
+
});
|
|
15533
|
+
const workItems = allDocs.filter(
|
|
15534
|
+
(d) => d.frontmatter.type !== "sprint" && d.frontmatter.type !== "epic" && d.frontmatter.tags?.includes(`sprint:${sprintId}`)
|
|
15535
|
+
);
|
|
15536
|
+
const byStatus = {};
|
|
15537
|
+
for (const doc of workItems) {
|
|
15538
|
+
byStatus[doc.frontmatter.status] = (byStatus[doc.frontmatter.status] ?? 0) + 1;
|
|
15539
|
+
}
|
|
15540
|
+
const doneCount = (byStatus["done"] ?? 0) + (byStatus["resolved"] ?? 0) + (byStatus["closed"] ?? 0);
|
|
15541
|
+
const total = workItems.length;
|
|
15542
|
+
const completionPct = total > 0 ? Math.round(doneCount / total * 100) : 0;
|
|
15543
|
+
return {
|
|
15544
|
+
id: sprintDoc.frontmatter.id,
|
|
15545
|
+
title: sprintDoc.frontmatter.title,
|
|
15546
|
+
status: sprintDoc.frontmatter.status,
|
|
15547
|
+
goal: sprintDoc.frontmatter.goal,
|
|
15548
|
+
startDate: sprintDoc.frontmatter.startDate,
|
|
15549
|
+
endDate: sprintDoc.frontmatter.endDate,
|
|
15550
|
+
linkedEpics,
|
|
15551
|
+
workItems: {
|
|
15552
|
+
total,
|
|
15553
|
+
done: doneCount,
|
|
15554
|
+
completionPct,
|
|
15555
|
+
byStatus,
|
|
15556
|
+
items: workItems.map((d) => ({
|
|
15557
|
+
id: d.frontmatter.id,
|
|
15558
|
+
title: d.frontmatter.title,
|
|
15559
|
+
type: d.frontmatter.type,
|
|
15560
|
+
status: d.frontmatter.status
|
|
15561
|
+
}))
|
|
15562
|
+
}
|
|
15563
|
+
};
|
|
15564
|
+
});
|
|
15565
|
+
return {
|
|
15566
|
+
content: [{ type: "text", text: JSON.stringify({ sprints }, null, 2) }]
|
|
15567
|
+
};
|
|
15568
|
+
},
|
|
15569
|
+
{ annotations: { readOnly: true } }
|
|
15570
|
+
),
|
|
15514
15571
|
tool8(
|
|
15515
15572
|
"generate_feature_progress",
|
|
15516
15573
|
"Generate progress report for features and their linked epics",
|
|
@@ -15557,7 +15614,7 @@ function createReportTools(store) {
|
|
|
15557
15614
|
{
|
|
15558
15615
|
title: external_exports.string().describe("Report title"),
|
|
15559
15616
|
content: external_exports.string().describe("Full report content in markdown"),
|
|
15560
|
-
reportType: external_exports.enum(["status", "risk-register", "gar", "epic-progress", "feature-progress", "custom"]).describe("Type of report"),
|
|
15617
|
+
reportType: external_exports.enum(["status", "risk-register", "gar", "epic-progress", "feature-progress", "sprint-progress", "custom"]).describe("Type of report"),
|
|
15561
15618
|
tags: external_exports.array(external_exports.string()).optional().describe("Additional tags")
|
|
15562
15619
|
},
|
|
15563
15620
|
async (args) => {
|
|
@@ -15974,13 +16031,369 @@ function createContributionTools(store) {
|
|
|
15974
16031
|
];
|
|
15975
16032
|
}
|
|
15976
16033
|
|
|
16034
|
+
// src/plugins/builtin/tools/sprints.ts
|
|
16035
|
+
import { tool as tool12 } from "@anthropic-ai/claude-agent-sdk";
|
|
16036
|
+
function createSprintTools(store) {
|
|
16037
|
+
return [
|
|
16038
|
+
tool12(
|
|
16039
|
+
"list_sprints",
|
|
16040
|
+
"List all sprints in the project, optionally filtered by status",
|
|
16041
|
+
{
|
|
16042
|
+
status: external_exports.enum(["planned", "active", "completed", "cancelled"]).optional().describe("Filter by sprint status")
|
|
16043
|
+
},
|
|
16044
|
+
async (args) => {
|
|
16045
|
+
const docs = store.list({ type: "sprint", status: args.status });
|
|
16046
|
+
const summary = docs.map((d) => ({
|
|
16047
|
+
id: d.frontmatter.id,
|
|
16048
|
+
title: d.frontmatter.title,
|
|
16049
|
+
status: d.frontmatter.status,
|
|
16050
|
+
goal: d.frontmatter.goal,
|
|
16051
|
+
startDate: d.frontmatter.startDate,
|
|
16052
|
+
endDate: d.frontmatter.endDate,
|
|
16053
|
+
linkedEpics: d.frontmatter.linkedEpics,
|
|
16054
|
+
tags: d.frontmatter.tags
|
|
16055
|
+
}));
|
|
16056
|
+
return {
|
|
16057
|
+
content: [{ type: "text", text: JSON.stringify(summary, null, 2) }]
|
|
16058
|
+
};
|
|
16059
|
+
},
|
|
16060
|
+
{ annotations: { readOnly: true } }
|
|
16061
|
+
),
|
|
16062
|
+
tool12(
|
|
16063
|
+
"get_sprint",
|
|
16064
|
+
"Get the full content of a specific sprint by ID",
|
|
16065
|
+
{ id: external_exports.string().describe("Sprint ID (e.g. 'SP-001')") },
|
|
16066
|
+
async (args) => {
|
|
16067
|
+
const doc = store.get(args.id);
|
|
16068
|
+
if (!doc) {
|
|
16069
|
+
return {
|
|
16070
|
+
content: [{ type: "text", text: `Sprint ${args.id} not found` }],
|
|
16071
|
+
isError: true
|
|
16072
|
+
};
|
|
16073
|
+
}
|
|
16074
|
+
return {
|
|
16075
|
+
content: [
|
|
16076
|
+
{
|
|
16077
|
+
type: "text",
|
|
16078
|
+
text: JSON.stringify(
|
|
16079
|
+
{ ...doc.frontmatter, content: doc.content },
|
|
16080
|
+
null,
|
|
16081
|
+
2
|
|
16082
|
+
)
|
|
16083
|
+
}
|
|
16084
|
+
]
|
|
16085
|
+
};
|
|
16086
|
+
},
|
|
16087
|
+
{ annotations: { readOnly: true } }
|
|
16088
|
+
),
|
|
16089
|
+
tool12(
|
|
16090
|
+
"create_sprint",
|
|
16091
|
+
"Create a new sprint with dates, goal, and optionally linked epics",
|
|
16092
|
+
{
|
|
16093
|
+
title: external_exports.string().describe("Sprint title"),
|
|
16094
|
+
content: external_exports.string().describe("Sprint description and objectives"),
|
|
16095
|
+
goal: external_exports.string().describe("Sprint goal \u2014 what this sprint aims to deliver"),
|
|
16096
|
+
startDate: external_exports.string().describe("Sprint start date (ISO format, e.g. '2026-03-01')"),
|
|
16097
|
+
endDate: external_exports.string().describe("Sprint end date (ISO format, e.g. '2026-03-14')"),
|
|
16098
|
+
status: external_exports.enum(["planned", "active", "completed", "cancelled"]).optional().describe("Sprint status (default: 'planned')"),
|
|
16099
|
+
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."),
|
|
16100
|
+
tags: external_exports.array(external_exports.string()).optional().describe("Additional tags")
|
|
16101
|
+
},
|
|
16102
|
+
async (args) => {
|
|
16103
|
+
const warnings = [];
|
|
16104
|
+
if (args.linkedEpics) {
|
|
16105
|
+
for (const epicId of args.linkedEpics) {
|
|
16106
|
+
const epic = store.get(epicId);
|
|
16107
|
+
if (!epic) {
|
|
16108
|
+
warnings.push(`Epic ${epicId} not found (linked anyway)`);
|
|
16109
|
+
}
|
|
16110
|
+
}
|
|
16111
|
+
}
|
|
16112
|
+
const frontmatter = {
|
|
16113
|
+
title: args.title,
|
|
16114
|
+
status: args.status ?? "planned",
|
|
16115
|
+
goal: args.goal,
|
|
16116
|
+
startDate: args.startDate,
|
|
16117
|
+
endDate: args.endDate,
|
|
16118
|
+
linkedEpics: args.linkedEpics ?? [],
|
|
16119
|
+
tags: [...args.tags ?? []]
|
|
16120
|
+
};
|
|
16121
|
+
const doc = store.create("sprint", frontmatter, args.content);
|
|
16122
|
+
const sprintId = doc.frontmatter.id;
|
|
16123
|
+
if (args.linkedEpics) {
|
|
16124
|
+
for (const epicId of args.linkedEpics) {
|
|
16125
|
+
const epic = store.get(epicId);
|
|
16126
|
+
if (epic) {
|
|
16127
|
+
const existingTags = epic.frontmatter.tags ?? [];
|
|
16128
|
+
const sprintTag = `sprint:${sprintId}`;
|
|
16129
|
+
if (!existingTags.includes(sprintTag)) {
|
|
16130
|
+
store.update(epicId, { tags: [...existingTags, sprintTag] });
|
|
16131
|
+
}
|
|
16132
|
+
}
|
|
16133
|
+
}
|
|
16134
|
+
}
|
|
16135
|
+
const parts = [`Created sprint ${sprintId}: ${doc.frontmatter.title}`];
|
|
16136
|
+
if (warnings.length > 0) {
|
|
16137
|
+
parts.push(`Warnings: ${warnings.join("; ")}`);
|
|
16138
|
+
}
|
|
16139
|
+
return {
|
|
16140
|
+
content: [{ type: "text", text: parts.join("\n") }]
|
|
16141
|
+
};
|
|
16142
|
+
}
|
|
16143
|
+
),
|
|
16144
|
+
tool12(
|
|
16145
|
+
"update_sprint",
|
|
16146
|
+
"Update an existing sprint. Cannot change id or type.",
|
|
16147
|
+
{
|
|
16148
|
+
id: external_exports.string().describe("Sprint ID to update"),
|
|
16149
|
+
title: external_exports.string().optional().describe("New title"),
|
|
16150
|
+
status: external_exports.enum(["planned", "active", "completed", "cancelled"]).optional().describe("New status"),
|
|
16151
|
+
content: external_exports.string().optional().describe("New content"),
|
|
16152
|
+
goal: external_exports.string().optional().describe("New sprint goal"),
|
|
16153
|
+
startDate: external_exports.string().optional().describe("New start date"),
|
|
16154
|
+
endDate: external_exports.string().optional().describe("New end date"),
|
|
16155
|
+
linkedEpics: external_exports.array(external_exports.string()).optional().describe("New list of linked epic IDs (replaces existing)"),
|
|
16156
|
+
tags: external_exports.array(external_exports.string()).optional().describe("New tags (replaces existing)")
|
|
16157
|
+
},
|
|
16158
|
+
async (args) => {
|
|
16159
|
+
const { id, content, linkedEpics, ...updates } = args;
|
|
16160
|
+
const existing = store.get(id);
|
|
16161
|
+
if (!existing) {
|
|
16162
|
+
return {
|
|
16163
|
+
content: [{ type: "text", text: `Sprint ${id} not found` }],
|
|
16164
|
+
isError: true
|
|
16165
|
+
};
|
|
16166
|
+
}
|
|
16167
|
+
if (linkedEpics !== void 0) {
|
|
16168
|
+
const oldLinked = existing.frontmatter.linkedEpics ?? [];
|
|
16169
|
+
const sprintTag = `sprint:${id}`;
|
|
16170
|
+
const removed = oldLinked.filter((e) => !linkedEpics.includes(e));
|
|
16171
|
+
for (const epicId of removed) {
|
|
16172
|
+
const epic = store.get(epicId);
|
|
16173
|
+
if (epic) {
|
|
16174
|
+
const tags = epic.frontmatter.tags ?? [];
|
|
16175
|
+
const filtered = tags.filter((t) => t !== sprintTag);
|
|
16176
|
+
if (filtered.length !== tags.length) {
|
|
16177
|
+
store.update(epicId, { tags: filtered });
|
|
16178
|
+
}
|
|
16179
|
+
}
|
|
16180
|
+
}
|
|
16181
|
+
const added = linkedEpics.filter((e) => !oldLinked.includes(e));
|
|
16182
|
+
for (const epicId of added) {
|
|
16183
|
+
const epic = store.get(epicId);
|
|
16184
|
+
if (epic) {
|
|
16185
|
+
const tags = epic.frontmatter.tags ?? [];
|
|
16186
|
+
if (!tags.includes(sprintTag)) {
|
|
16187
|
+
store.update(epicId, { tags: [...tags, sprintTag] });
|
|
16188
|
+
}
|
|
16189
|
+
}
|
|
16190
|
+
}
|
|
16191
|
+
updates.linkedEpics = linkedEpics;
|
|
16192
|
+
}
|
|
16193
|
+
const doc = store.update(id, updates, content);
|
|
16194
|
+
return {
|
|
16195
|
+
content: [
|
|
16196
|
+
{
|
|
16197
|
+
type: "text",
|
|
16198
|
+
text: `Updated sprint ${doc.frontmatter.id}: ${doc.frontmatter.title}`
|
|
16199
|
+
}
|
|
16200
|
+
]
|
|
16201
|
+
};
|
|
16202
|
+
}
|
|
16203
|
+
)
|
|
16204
|
+
];
|
|
16205
|
+
}
|
|
16206
|
+
|
|
16207
|
+
// src/plugins/builtin/tools/sprint-planning.ts
|
|
16208
|
+
import { tool as tool13 } from "@anthropic-ai/claude-agent-sdk";
|
|
16209
|
+
var PRIORITY_ORDER = {
|
|
16210
|
+
critical: 0,
|
|
16211
|
+
high: 1,
|
|
16212
|
+
medium: 2,
|
|
16213
|
+
low: 3
|
|
16214
|
+
};
|
|
16215
|
+
function priorityRank(p) {
|
|
16216
|
+
return PRIORITY_ORDER[p ?? ""] ?? 99;
|
|
16217
|
+
}
|
|
16218
|
+
function createSprintPlanningTools(store) {
|
|
16219
|
+
return [
|
|
16220
|
+
tool13(
|
|
16221
|
+
"gather_sprint_planning_context",
|
|
16222
|
+
"Aggregate all planning-relevant data for proposing the next sprint: approved features, backlog epics, active sprint, velocity reference, blockers, and summary stats",
|
|
16223
|
+
{
|
|
16224
|
+
focusFeature: external_exports.string().optional().describe("Filter backlog to epics of a specific feature ID (e.g. 'F-001')"),
|
|
16225
|
+
sprintDurationDays: external_exports.number().optional().describe("Expected sprint duration in days \u2014 passed through for capacity reasoning")
|
|
16226
|
+
},
|
|
16227
|
+
async (args) => {
|
|
16228
|
+
const features = store.list({ type: "feature" });
|
|
16229
|
+
const epics = store.list({ type: "epic" });
|
|
16230
|
+
const sprints = store.list({ type: "sprint" });
|
|
16231
|
+
const questions = store.list({ type: "question", status: "open" });
|
|
16232
|
+
const contributions = store.list({ type: "contribution" });
|
|
16233
|
+
const approvedFeatures = features.filter((f) => f.frontmatter.status === "approved").sort((a, b) => priorityRank(a.frontmatter.priority) - priorityRank(b.frontmatter.priority)).map((f) => {
|
|
16234
|
+
const linkedEpics = epics.filter((e) => e.frontmatter.linkedFeature === f.frontmatter.id);
|
|
16235
|
+
const epicsByStatus = {};
|
|
16236
|
+
for (const e of linkedEpics) {
|
|
16237
|
+
epicsByStatus[e.frontmatter.status] = (epicsByStatus[e.frontmatter.status] ?? 0) + 1;
|
|
16238
|
+
}
|
|
16239
|
+
return {
|
|
16240
|
+
id: f.frontmatter.id,
|
|
16241
|
+
title: f.frontmatter.title,
|
|
16242
|
+
priority: f.frontmatter.priority,
|
|
16243
|
+
owner: f.frontmatter.owner,
|
|
16244
|
+
epicCount: linkedEpics.length,
|
|
16245
|
+
epicsByStatus
|
|
16246
|
+
};
|
|
16247
|
+
});
|
|
16248
|
+
const assignedEpicIds = /* @__PURE__ */ new Set();
|
|
16249
|
+
for (const sp of sprints) {
|
|
16250
|
+
const linked = sp.frontmatter.linkedEpics ?? [];
|
|
16251
|
+
for (const id of linked) assignedEpicIds.add(id);
|
|
16252
|
+
}
|
|
16253
|
+
const featureMap = new Map(features.map((f) => [f.frontmatter.id, f]));
|
|
16254
|
+
let backlogEpics = epics.filter(
|
|
16255
|
+
(e) => !assignedEpicIds.has(e.frontmatter.id) && e.frontmatter.status !== "done"
|
|
16256
|
+
);
|
|
16257
|
+
if (args.focusFeature) {
|
|
16258
|
+
backlogEpics = backlogEpics.filter(
|
|
16259
|
+
(e) => e.frontmatter.linkedFeature === args.focusFeature
|
|
16260
|
+
);
|
|
16261
|
+
}
|
|
16262
|
+
const backlog = backlogEpics.sort((a, b) => {
|
|
16263
|
+
const fa = featureMap.get(a.frontmatter.linkedFeature);
|
|
16264
|
+
const fb = featureMap.get(b.frontmatter.linkedFeature);
|
|
16265
|
+
return priorityRank(fa?.frontmatter.priority) - priorityRank(fb?.frontmatter.priority);
|
|
16266
|
+
}).map((e) => {
|
|
16267
|
+
const parent = featureMap.get(e.frontmatter.linkedFeature);
|
|
16268
|
+
return {
|
|
16269
|
+
id: e.frontmatter.id,
|
|
16270
|
+
title: e.frontmatter.title,
|
|
16271
|
+
status: e.frontmatter.status,
|
|
16272
|
+
linkedFeature: e.frontmatter.linkedFeature,
|
|
16273
|
+
featureTitle: parent?.frontmatter.title ?? null,
|
|
16274
|
+
featurePriority: parent?.frontmatter.priority ?? null,
|
|
16275
|
+
estimatedEffort: e.frontmatter.estimatedEffort ?? null,
|
|
16276
|
+
targetDate: e.frontmatter.targetDate ?? null
|
|
16277
|
+
};
|
|
16278
|
+
});
|
|
16279
|
+
const activeSprintDoc = sprints.find((s) => s.frontmatter.status === "active") ?? null;
|
|
16280
|
+
let activeSprint = null;
|
|
16281
|
+
if (activeSprintDoc) {
|
|
16282
|
+
const linkedEpicIds = activeSprintDoc.frontmatter.linkedEpics ?? [];
|
|
16283
|
+
const linkedEpics = linkedEpicIds.map((epicId) => {
|
|
16284
|
+
const epic = store.get(epicId);
|
|
16285
|
+
return epic ? { id: epicId, title: epic.frontmatter.title, status: epic.frontmatter.status } : { id: epicId, title: "(not found)", status: "unknown" };
|
|
16286
|
+
});
|
|
16287
|
+
const allDocs = store.list();
|
|
16288
|
+
const sprintTag = `sprint:${activeSprintDoc.frontmatter.id}`;
|
|
16289
|
+
const workItems = allDocs.filter(
|
|
16290
|
+
(d) => d.frontmatter.type !== "sprint" && d.frontmatter.type !== "epic" && d.frontmatter.tags?.includes(sprintTag)
|
|
16291
|
+
);
|
|
16292
|
+
const doneCount = workItems.filter(
|
|
16293
|
+
(d) => d.frontmatter.status === "done" || d.frontmatter.status === "resolved" || d.frontmatter.status === "closed"
|
|
16294
|
+
).length;
|
|
16295
|
+
const completionPct = workItems.length > 0 ? Math.round(doneCount / workItems.length * 100) : 0;
|
|
16296
|
+
activeSprint = {
|
|
16297
|
+
id: activeSprintDoc.frontmatter.id,
|
|
16298
|
+
title: activeSprintDoc.frontmatter.title,
|
|
16299
|
+
goal: activeSprintDoc.frontmatter.goal,
|
|
16300
|
+
startDate: activeSprintDoc.frontmatter.startDate,
|
|
16301
|
+
endDate: activeSprintDoc.frontmatter.endDate,
|
|
16302
|
+
linkedEpics,
|
|
16303
|
+
workItems: { total: workItems.length, done: doneCount, completionPct }
|
|
16304
|
+
};
|
|
16305
|
+
}
|
|
16306
|
+
const completedSprints = sprints.filter((s) => s.frontmatter.status === "completed").sort((a, b) => {
|
|
16307
|
+
const da = a.frontmatter.endDate ?? "";
|
|
16308
|
+
const db = b.frontmatter.endDate ?? "";
|
|
16309
|
+
return da < db ? 1 : da > db ? -1 : 0;
|
|
16310
|
+
}).slice(0, 2);
|
|
16311
|
+
const velocityReference = completedSprints.map((sp) => {
|
|
16312
|
+
const linkedEpicIds = sp.frontmatter.linkedEpics ?? [];
|
|
16313
|
+
const efforts = [];
|
|
16314
|
+
for (const epicId of linkedEpicIds) {
|
|
16315
|
+
const epic = store.get(epicId);
|
|
16316
|
+
if (epic?.frontmatter.estimatedEffort) {
|
|
16317
|
+
efforts.push(String(epic.frontmatter.estimatedEffort));
|
|
16318
|
+
}
|
|
16319
|
+
}
|
|
16320
|
+
const allDocs = store.list();
|
|
16321
|
+
const sprintTag = `sprint:${sp.frontmatter.id}`;
|
|
16322
|
+
const workItems = allDocs.filter(
|
|
16323
|
+
(d) => d.frontmatter.type !== "sprint" && d.frontmatter.type !== "epic" && d.frontmatter.tags?.includes(sprintTag)
|
|
16324
|
+
);
|
|
16325
|
+
return {
|
|
16326
|
+
id: sp.frontmatter.id,
|
|
16327
|
+
title: sp.frontmatter.title,
|
|
16328
|
+
startDate: sp.frontmatter.startDate,
|
|
16329
|
+
endDate: sp.frontmatter.endDate,
|
|
16330
|
+
epicCount: linkedEpicIds.length,
|
|
16331
|
+
efforts,
|
|
16332
|
+
workItemCount: workItems.length
|
|
16333
|
+
};
|
|
16334
|
+
});
|
|
16335
|
+
const openBlockerContributions = contributions.filter(
|
|
16336
|
+
(c) => c.frontmatter.status === "open" && (c.frontmatter.contributionType === "risk-finding" || c.frontmatter.contributionType === "blocker-report")
|
|
16337
|
+
);
|
|
16338
|
+
const blockers = {
|
|
16339
|
+
openQuestions: questions.map((q) => ({
|
|
16340
|
+
id: q.frontmatter.id,
|
|
16341
|
+
title: q.frontmatter.title
|
|
16342
|
+
})),
|
|
16343
|
+
openRiskAndBlockerContributions: openBlockerContributions.map((c) => ({
|
|
16344
|
+
id: c.frontmatter.id,
|
|
16345
|
+
title: c.frontmatter.title,
|
|
16346
|
+
contributionType: c.frontmatter.contributionType
|
|
16347
|
+
}))
|
|
16348
|
+
};
|
|
16349
|
+
const totalBacklogEfforts = backlog.filter((e) => e.estimatedEffort !== null).map((e) => String(e.estimatedEffort));
|
|
16350
|
+
const approvedFeaturesWithNoEpics = approvedFeatures.filter((f) => f.epicCount === 0).map((f) => ({ id: f.id, title: f.title }));
|
|
16351
|
+
const now = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
16352
|
+
const epicsAtRisk = epics.filter((e) => {
|
|
16353
|
+
if (e.frontmatter.status === "done") return false;
|
|
16354
|
+
if (e.frontmatter.targetDate && e.frontmatter.targetDate < now) return true;
|
|
16355
|
+
const parent = featureMap.get(e.frontmatter.linkedFeature);
|
|
16356
|
+
if (parent?.frontmatter.status === "deferred") return true;
|
|
16357
|
+
return false;
|
|
16358
|
+
}).map((e) => ({
|
|
16359
|
+
id: e.frontmatter.id,
|
|
16360
|
+
title: e.frontmatter.title,
|
|
16361
|
+
reason: e.frontmatter.targetDate && e.frontmatter.targetDate < now ? "past-target-date" : "deferred-feature"
|
|
16362
|
+
}));
|
|
16363
|
+
const plannedSprintCount = sprints.filter((s) => s.frontmatter.status === "planned").length;
|
|
16364
|
+
const summary = {
|
|
16365
|
+
totalBacklogEpics: backlog.length,
|
|
16366
|
+
totalBacklogEfforts,
|
|
16367
|
+
approvedFeaturesWithNoEpics,
|
|
16368
|
+
epicsAtRisk,
|
|
16369
|
+
plannedSprintCount
|
|
16370
|
+
};
|
|
16371
|
+
const result = {
|
|
16372
|
+
approvedFeatures,
|
|
16373
|
+
backlog,
|
|
16374
|
+
activeSprint,
|
|
16375
|
+
velocityReference,
|
|
16376
|
+
blockers,
|
|
16377
|
+
summary,
|
|
16378
|
+
...args.sprintDurationDays !== void 0 ? { sprintDurationDays: args.sprintDurationDays } : {}
|
|
16379
|
+
};
|
|
16380
|
+
return {
|
|
16381
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
16382
|
+
};
|
|
16383
|
+
},
|
|
16384
|
+
{ annotations: { readOnly: true } }
|
|
16385
|
+
)
|
|
16386
|
+
];
|
|
16387
|
+
}
|
|
16388
|
+
|
|
15977
16389
|
// src/plugins/common.ts
|
|
15978
16390
|
var COMMON_REGISTRATIONS = [
|
|
15979
16391
|
{ type: "meeting", dirName: "meetings", idPrefix: "M" },
|
|
15980
16392
|
{ type: "report", dirName: "reports", idPrefix: "R" },
|
|
15981
16393
|
{ type: "feature", dirName: "features", idPrefix: "F" },
|
|
15982
16394
|
{ type: "epic", dirName: "epics", idPrefix: "E" },
|
|
15983
|
-
{ type: "contribution", dirName: "contributions", idPrefix: "C" }
|
|
16395
|
+
{ type: "contribution", dirName: "contributions", idPrefix: "C" },
|
|
16396
|
+
{ type: "sprint", dirName: "sprints", idPrefix: "SP" }
|
|
15984
16397
|
];
|
|
15985
16398
|
function createCommonTools(store) {
|
|
15986
16399
|
return [
|
|
@@ -15988,7 +16401,9 @@ function createCommonTools(store) {
|
|
|
15988
16401
|
...createReportTools(store),
|
|
15989
16402
|
...createFeatureTools(store),
|
|
15990
16403
|
...createEpicTools(store),
|
|
15991
|
-
...createContributionTools(store)
|
|
16404
|
+
...createContributionTools(store),
|
|
16405
|
+
...createSprintTools(store),
|
|
16406
|
+
...createSprintPlanningTools(store)
|
|
15992
16407
|
];
|
|
15993
16408
|
}
|
|
15994
16409
|
|
|
@@ -15998,7 +16413,7 @@ var genericAgilePlugin = {
|
|
|
15998
16413
|
name: "Generic Agile",
|
|
15999
16414
|
description: "Default methodology plugin providing standard agile governance patterns for decisions, actions, and questions.",
|
|
16000
16415
|
version: "0.1.0",
|
|
16001
|
-
documentTypes: ["decision", "action", "question", "meeting", "report", "feature", "epic", "contribution"],
|
|
16416
|
+
documentTypes: ["decision", "action", "question", "meeting", "report", "feature", "epic", "contribution", "sprint"],
|
|
16002
16417
|
documentTypeRegistrations: [...COMMON_REGISTRATIONS],
|
|
16003
16418
|
tools: (store) => [...createCommonTools(store)],
|
|
16004
16419
|
promptFragments: {
|
|
@@ -16025,7 +16440,10 @@ var genericAgilePlugin = {
|
|
|
16025
16440
|
- **list_contributions** / **get_contribution**: Browse and read contribution records.
|
|
16026
16441
|
- **create_contribution**: Record a contribution with persona, type, and optional related artifact.
|
|
16027
16442
|
- **update_contribution**: Update a contribution (e.g. append effects).
|
|
16028
|
-
- Available contribution types: stakeholder-feedback, acceptance-result, priority-change, market-insight
|
|
16443
|
+
- Available contribution types: stakeholder-feedback, acceptance-result, priority-change, market-insight.
|
|
16444
|
+
|
|
16445
|
+
**Sprint Tools (read-only for awareness):**
|
|
16446
|
+
- **list_sprints** / **get_sprint**: View sprints to understand delivery timelines and iteration scope.`,
|
|
16029
16447
|
"tech-lead": `You own epics and break approved features into implementation work.
|
|
16030
16448
|
|
|
16031
16449
|
**Epic Tools:**
|
|
@@ -16052,7 +16470,18 @@ var genericAgilePlugin = {
|
|
|
16052
16470
|
- **list_contributions** / **get_contribution**: Browse and read contribution records.
|
|
16053
16471
|
- **create_contribution**: Record a contribution with persona, type, and optional related artifact.
|
|
16054
16472
|
- **update_contribution**: Update a contribution (e.g. append effects).
|
|
16055
|
-
- Available contribution types: action-result, spike-findings, technical-assessment, architecture-review
|
|
16473
|
+
- Available contribution types: action-result, spike-findings, technical-assessment, architecture-review.
|
|
16474
|
+
|
|
16475
|
+
**Sprint Tools:**
|
|
16476
|
+
- **list_sprints** / **get_sprint**: View sprints to understand iteration scope and delivery dates.
|
|
16477
|
+
- **update_sprint**: Assign epics to sprints by updating linkedEpics when breaking features into work.
|
|
16478
|
+
- Tag technical actions and decisions with \`sprint:SP-xxx\` to associate them with a sprint.
|
|
16479
|
+
- Use **generate_sprint_progress** to track technical work completion within an iteration.
|
|
16480
|
+
|
|
16481
|
+
**Sprint Planning:**
|
|
16482
|
+
- When asked to plan or propose a sprint, ALWAYS call **gather_sprint_planning_context** first.
|
|
16483
|
+
- Focus on: technical readiness of each epic, open technical questions or spikes, effort balance across the sprint, and feature coverage.
|
|
16484
|
+
- Present a structured sprint proposal with technical rationale for each selected epic, known technical risks, and any prerequisite work that should be completed first.`,
|
|
16056
16485
|
"delivery-manager": `You track delivery across features and epics, manage schedules, and report on progress.
|
|
16057
16486
|
|
|
16058
16487
|
**Report Tools:**
|
|
@@ -16086,14 +16515,35 @@ var genericAgilePlugin = {
|
|
|
16086
16515
|
- **list_contributions** / **get_contribution**: Browse and read contribution records.
|
|
16087
16516
|
- **create_contribution**: Record a contribution with persona, type, and optional related artifact.
|
|
16088
16517
|
- **update_contribution**: Update a contribution (e.g. append effects).
|
|
16089
|
-
- Available contribution types: risk-finding, blocker-report, dependency-update, status-assessment
|
|
16090
|
-
|
|
16518
|
+
- Available contribution types: risk-finding, blocker-report, dependency-update, status-assessment.
|
|
16519
|
+
|
|
16520
|
+
**Sprint Tools:**
|
|
16521
|
+
- **list_sprints** / **get_sprint**: Browse and read sprint definitions.
|
|
16522
|
+
- **create_sprint**: Create sprints with dates, goals, and linked epics. Use status "planned" for upcoming sprints or "active"/"completed"/"cancelled" for current/past sprints.
|
|
16523
|
+
- **update_sprint**: Update sprint status, dates, goal, or linked epics. When linkedEpics changes, affected epics are re-tagged automatically.
|
|
16524
|
+
- **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 %.
|
|
16525
|
+
- Use \`save_report\` with reportType "sprint-progress" to persist sprint reports.
|
|
16526
|
+
|
|
16527
|
+
**Sprint Workflow:**
|
|
16528
|
+
- Create sprints with clear goals and date boundaries.
|
|
16529
|
+
- Assign epics to sprints via linkedEpics.
|
|
16530
|
+
- Tag work items (actions, decisions, questions) with \`sprint:SP-xxx\` for sprint scoping.
|
|
16531
|
+
- Track delivery dates and flag at-risk sprints.
|
|
16532
|
+
- Register past/completed sprints for historical tracking.
|
|
16533
|
+
|
|
16534
|
+
**Sprint Planning:**
|
|
16535
|
+
- 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.
|
|
16536
|
+
- Reason through: priority (critical/high features first), capacity (compare backlog effort to velocity reference), dependencies and blockers, balance across features, and risk.
|
|
16537
|
+
- Present a structured sprint proposal: title, goal, suggested dates, selected epics with rationale for each, excluded epics with reason, and identified risks.
|
|
16538
|
+
- After user confirmation, use **create_sprint** with the agreed epics to persist the sprint.`,
|
|
16539
|
+
"*": `You have access to feature, epic, sprint, and meeting tools for project coordination:
|
|
16091
16540
|
|
|
16092
16541
|
**Features** (F-xxx): Product capabilities defined by the Product Owner. Features progress through draft \u2192 approved \u2192 done.
|
|
16093
16542
|
**Epics** (E-xxx): Implementation work packages created by the Tech Lead, linked to approved features. Epics progress through planned \u2192 in-progress \u2192 done.
|
|
16543
|
+
**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).
|
|
16094
16544
|
**Meetings**: Meeting records with attendees, agendas, and notes.
|
|
16095
16545
|
|
|
16096
|
-
**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,
|
|
16546
|
+
**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.
|
|
16097
16547
|
|
|
16098
16548
|
- **list_meetings** / **get_meeting**: Browse and read meeting records.
|
|
16099
16549
|
- **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.
|
|
@@ -16108,10 +16558,10 @@ var genericAgilePlugin = {
|
|
|
16108
16558
|
};
|
|
16109
16559
|
|
|
16110
16560
|
// src/plugins/builtin/tools/use-cases.ts
|
|
16111
|
-
import { tool as
|
|
16561
|
+
import { tool as tool14 } from "@anthropic-ai/claude-agent-sdk";
|
|
16112
16562
|
function createUseCaseTools(store) {
|
|
16113
16563
|
return [
|
|
16114
|
-
|
|
16564
|
+
tool14(
|
|
16115
16565
|
"list_use_cases",
|
|
16116
16566
|
"List all extension use cases, optionally filtered by status or extension type",
|
|
16117
16567
|
{
|
|
@@ -16141,7 +16591,7 @@ function createUseCaseTools(store) {
|
|
|
16141
16591
|
},
|
|
16142
16592
|
{ annotations: { readOnly: true } }
|
|
16143
16593
|
),
|
|
16144
|
-
|
|
16594
|
+
tool14(
|
|
16145
16595
|
"get_use_case",
|
|
16146
16596
|
"Get the full content of a specific use case by ID",
|
|
16147
16597
|
{ id: external_exports.string().describe("Use case ID (e.g. 'UC-001')") },
|
|
@@ -16168,7 +16618,7 @@ function createUseCaseTools(store) {
|
|
|
16168
16618
|
},
|
|
16169
16619
|
{ annotations: { readOnly: true } }
|
|
16170
16620
|
),
|
|
16171
|
-
|
|
16621
|
+
tool14(
|
|
16172
16622
|
"create_use_case",
|
|
16173
16623
|
"Create a new extension use case definition (Phase 1: Assess Extension Use Case)",
|
|
16174
16624
|
{
|
|
@@ -16202,7 +16652,7 @@ function createUseCaseTools(store) {
|
|
|
16202
16652
|
};
|
|
16203
16653
|
}
|
|
16204
16654
|
),
|
|
16205
|
-
|
|
16655
|
+
tool14(
|
|
16206
16656
|
"update_use_case",
|
|
16207
16657
|
"Update an existing extension use case",
|
|
16208
16658
|
{
|
|
@@ -16232,10 +16682,10 @@ function createUseCaseTools(store) {
|
|
|
16232
16682
|
}
|
|
16233
16683
|
|
|
16234
16684
|
// src/plugins/builtin/tools/tech-assessments.ts
|
|
16235
|
-
import { tool as
|
|
16685
|
+
import { tool as tool15 } from "@anthropic-ai/claude-agent-sdk";
|
|
16236
16686
|
function createTechAssessmentTools(store) {
|
|
16237
16687
|
return [
|
|
16238
|
-
|
|
16688
|
+
tool15(
|
|
16239
16689
|
"list_tech_assessments",
|
|
16240
16690
|
"List all technology assessments, optionally filtered by status",
|
|
16241
16691
|
{
|
|
@@ -16266,7 +16716,7 @@ function createTechAssessmentTools(store) {
|
|
|
16266
16716
|
},
|
|
16267
16717
|
{ annotations: { readOnly: true } }
|
|
16268
16718
|
),
|
|
16269
|
-
|
|
16719
|
+
tool15(
|
|
16270
16720
|
"get_tech_assessment",
|
|
16271
16721
|
"Get the full content of a specific technology assessment by ID",
|
|
16272
16722
|
{ id: external_exports.string().describe("Tech assessment ID (e.g. 'TA-001')") },
|
|
@@ -16293,7 +16743,7 @@ function createTechAssessmentTools(store) {
|
|
|
16293
16743
|
},
|
|
16294
16744
|
{ annotations: { readOnly: true } }
|
|
16295
16745
|
),
|
|
16296
|
-
|
|
16746
|
+
tool15(
|
|
16297
16747
|
"create_tech_assessment",
|
|
16298
16748
|
"Create a new technology assessment linked to an assessed/approved use case (Phase 2: Assess Extension Technology)",
|
|
16299
16749
|
{
|
|
@@ -16364,7 +16814,7 @@ function createTechAssessmentTools(store) {
|
|
|
16364
16814
|
};
|
|
16365
16815
|
}
|
|
16366
16816
|
),
|
|
16367
|
-
|
|
16817
|
+
tool15(
|
|
16368
16818
|
"update_tech_assessment",
|
|
16369
16819
|
"Update an existing technology assessment. The linked use case cannot be changed.",
|
|
16370
16820
|
{
|
|
@@ -16394,10 +16844,10 @@ function createTechAssessmentTools(store) {
|
|
|
16394
16844
|
}
|
|
16395
16845
|
|
|
16396
16846
|
// src/plugins/builtin/tools/extension-designs.ts
|
|
16397
|
-
import { tool as
|
|
16847
|
+
import { tool as tool16 } from "@anthropic-ai/claude-agent-sdk";
|
|
16398
16848
|
function createExtensionDesignTools(store) {
|
|
16399
16849
|
return [
|
|
16400
|
-
|
|
16850
|
+
tool16(
|
|
16401
16851
|
"list_extension_designs",
|
|
16402
16852
|
"List all extension designs, optionally filtered by status",
|
|
16403
16853
|
{
|
|
@@ -16427,7 +16877,7 @@ function createExtensionDesignTools(store) {
|
|
|
16427
16877
|
},
|
|
16428
16878
|
{ annotations: { readOnly: true } }
|
|
16429
16879
|
),
|
|
16430
|
-
|
|
16880
|
+
tool16(
|
|
16431
16881
|
"get_extension_design",
|
|
16432
16882
|
"Get the full content of a specific extension design by ID",
|
|
16433
16883
|
{ id: external_exports.string().describe("Extension design ID (e.g. 'XD-001')") },
|
|
@@ -16454,7 +16904,7 @@ function createExtensionDesignTools(store) {
|
|
|
16454
16904
|
},
|
|
16455
16905
|
{ annotations: { readOnly: true } }
|
|
16456
16906
|
),
|
|
16457
|
-
|
|
16907
|
+
tool16(
|
|
16458
16908
|
"create_extension_design",
|
|
16459
16909
|
"Create a new extension design linked to a recommended tech assessment (Phase 3: Define Extension Target Solution)",
|
|
16460
16910
|
{
|
|
@@ -16522,7 +16972,7 @@ function createExtensionDesignTools(store) {
|
|
|
16522
16972
|
};
|
|
16523
16973
|
}
|
|
16524
16974
|
),
|
|
16525
|
-
|
|
16975
|
+
tool16(
|
|
16526
16976
|
"update_extension_design",
|
|
16527
16977
|
"Update an existing extension design. The linked tech assessment cannot be changed.",
|
|
16528
16978
|
{
|
|
@@ -16551,10 +17001,10 @@ function createExtensionDesignTools(store) {
|
|
|
16551
17001
|
}
|
|
16552
17002
|
|
|
16553
17003
|
// src/plugins/builtin/tools/aem-reports.ts
|
|
16554
|
-
import { tool as
|
|
17004
|
+
import { tool as tool17 } from "@anthropic-ai/claude-agent-sdk";
|
|
16555
17005
|
function createAemReportTools(store) {
|
|
16556
17006
|
return [
|
|
16557
|
-
|
|
17007
|
+
tool17(
|
|
16558
17008
|
"generate_extension_portfolio",
|
|
16559
17009
|
"Generate a portfolio view of all use cases with their linked tech assessments and extension designs",
|
|
16560
17010
|
{},
|
|
@@ -16606,7 +17056,7 @@ function createAemReportTools(store) {
|
|
|
16606
17056
|
},
|
|
16607
17057
|
{ annotations: { readOnly: true } }
|
|
16608
17058
|
),
|
|
16609
|
-
|
|
17059
|
+
tool17(
|
|
16610
17060
|
"generate_tech_readiness",
|
|
16611
17061
|
"Generate a BTP technology readiness report showing service coverage and gaps across assessments",
|
|
16612
17062
|
{},
|
|
@@ -16658,7 +17108,7 @@ function createAemReportTools(store) {
|
|
|
16658
17108
|
},
|
|
16659
17109
|
{ annotations: { readOnly: true } }
|
|
16660
17110
|
),
|
|
16661
|
-
|
|
17111
|
+
tool17(
|
|
16662
17112
|
"generate_phase_status",
|
|
16663
17113
|
"Generate a phase progress report showing artifact counts and readiness per AEM phase",
|
|
16664
17114
|
{},
|
|
@@ -16720,11 +17170,11 @@ function createAemReportTools(store) {
|
|
|
16720
17170
|
import * as fs6 from "fs";
|
|
16721
17171
|
import * as path6 from "path";
|
|
16722
17172
|
import * as YAML4 from "yaml";
|
|
16723
|
-
import { tool as
|
|
17173
|
+
import { tool as tool18 } from "@anthropic-ai/claude-agent-sdk";
|
|
16724
17174
|
var PHASES = ["assess-use-case", "assess-technology", "define-solution"];
|
|
16725
17175
|
function createAemPhaseTools(store, marvinDir) {
|
|
16726
17176
|
return [
|
|
16727
|
-
|
|
17177
|
+
tool18(
|
|
16728
17178
|
"get_current_phase",
|
|
16729
17179
|
"Get the current AEM phase from project configuration",
|
|
16730
17180
|
{},
|
|
@@ -16745,7 +17195,7 @@ function createAemPhaseTools(store, marvinDir) {
|
|
|
16745
17195
|
},
|
|
16746
17196
|
{ annotations: { readOnly: true } }
|
|
16747
17197
|
),
|
|
16748
|
-
|
|
17198
|
+
tool18(
|
|
16749
17199
|
"advance_phase",
|
|
16750
17200
|
"Advance to the next AEM phase. Performs soft gate checks and warns if artifacts are incomplete, but does not block.",
|
|
16751
17201
|
{
|
|
@@ -17520,7 +17970,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
17520
17970
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
17521
17971
|
|
|
17522
17972
|
// src/skills/action-tools.ts
|
|
17523
|
-
import { tool as
|
|
17973
|
+
import { tool as tool19 } from "@anthropic-ai/claude-agent-sdk";
|
|
17524
17974
|
|
|
17525
17975
|
// src/skills/action-runner.ts
|
|
17526
17976
|
import { query as query3 } from "@anthropic-ai/claude-agent-sdk";
|
|
@@ -17586,7 +18036,7 @@ function createSkillActionTools(skills, context) {
|
|
|
17586
18036
|
if (!skill.actions) continue;
|
|
17587
18037
|
for (const action of skill.actions) {
|
|
17588
18038
|
tools.push(
|
|
17589
|
-
|
|
18039
|
+
tool19(
|
|
17590
18040
|
`${skill.id}__${action.id}`,
|
|
17591
18041
|
action.description,
|
|
17592
18042
|
{
|
|
@@ -17678,10 +18128,10 @@ ${lines.join("\n\n")}`;
|
|
|
17678
18128
|
}
|
|
17679
18129
|
|
|
17680
18130
|
// src/mcp/persona-tools.ts
|
|
17681
|
-
import { tool as
|
|
18131
|
+
import { tool as tool20 } from "@anthropic-ai/claude-agent-sdk";
|
|
17682
18132
|
function createPersonaTools(ctx, marvinDir) {
|
|
17683
18133
|
return [
|
|
17684
|
-
|
|
18134
|
+
tool20(
|
|
17685
18135
|
"set_persona",
|
|
17686
18136
|
"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.",
|
|
17687
18137
|
{
|
|
@@ -17711,7 +18161,7 @@ ${summaries}`
|
|
|
17711
18161
|
};
|
|
17712
18162
|
}
|
|
17713
18163
|
),
|
|
17714
|
-
|
|
18164
|
+
tool20(
|
|
17715
18165
|
"get_persona_guidance",
|
|
17716
18166
|
"Get guidance for a persona without changing the active persona. If no persona is specified, lists all available personas with summaries.",
|
|
17717
18167
|
{
|
|
@@ -19338,7 +19788,8 @@ function getDirNameForType(store, type) {
|
|
|
19338
19788
|
meeting: "meetings",
|
|
19339
19789
|
report: "reports",
|
|
19340
19790
|
feature: "features",
|
|
19341
|
-
epic: "epics"
|
|
19791
|
+
epic: "epics",
|
|
19792
|
+
sprint: "sprints"
|
|
19342
19793
|
};
|
|
19343
19794
|
return typeDir[type] ?? `${type}s`;
|
|
19344
19795
|
}
|
|
@@ -20245,7 +20696,7 @@ function createProgram() {
|
|
|
20245
20696
|
const program = new Command();
|
|
20246
20697
|
program.name("marvin").description(
|
|
20247
20698
|
"AI-powered product development assistant with Product Owner, Delivery Manager, and Technical Lead personas"
|
|
20248
|
-
).version("0.2.
|
|
20699
|
+
).version("0.2.6");
|
|
20249
20700
|
program.command("init").description("Initialize a new Marvin project in the current directory").action(async () => {
|
|
20250
20701
|
await initCommand();
|
|
20251
20702
|
});
|