mrvn-cli 0.2.5 → 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 +14 -1
- package/dist/index.js +225 -31
- package/dist/index.js.map +1 -1
- package/dist/marvin-serve.js +224 -30
- package/dist/marvin-serve.js.map +1 -1
- package/dist/marvin.js +250 -56
- package/dist/marvin.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -172,6 +172,19 @@ Feature (PO) Epic (TL) Sprint (DM)
|
|
|
172
172
|
|
|
173
173
|
When a sprint links to epics, those epics are auto-tagged with `sprint:SP-xxx`. Work items (actions, decisions, questions) are associated with sprints via the same `sprint:SP-xxx` tag convention. The `generate_sprint_progress` report shows linked epics with statuses, tagged work items grouped by status, and done/total completion %.
|
|
174
174
|
|
|
175
|
+
**Sprint planning** is supported by the `gather_sprint_planning_context` tool, which aggregates all planning-relevant data in a single call:
|
|
176
|
+
|
|
177
|
+
| Section | Contents |
|
|
178
|
+
|---------|----------|
|
|
179
|
+
| `approvedFeatures` | Approved features sorted by priority, with epic counts by status |
|
|
180
|
+
| `backlog` | Unassigned non-done epics, sorted by parent feature priority, enriched with feature context and effort estimates |
|
|
181
|
+
| `activeSprint` | Current active sprint with linked epic statuses, work item counts, and completion % |
|
|
182
|
+
| `velocityReference` | Last 2 completed sprints with epic count, effort strings, and work item throughput |
|
|
183
|
+
| `blockers` | Open questions, open risk-finding and blocker-report contributions |
|
|
184
|
+
| `summary` | Total backlog size, approved features with no epics, epics at risk, planned sprint count |
|
|
185
|
+
|
|
186
|
+
When asked to propose a sprint, the DM reasons through priority, capacity, dependencies, and risk to present a structured proposal. The TL focuses on technical readiness, effort balance, and feature coverage. Both personas call this tool automatically before proposing a sprint plan.
|
|
187
|
+
|
|
175
188
|
This provides **hard enforcement** (epics must link to approved features) combined with **soft guidance** (persona prompts steer each role toward their responsibilities) and **sprint-level tracking** for time-boxed delivery.
|
|
176
189
|
|
|
177
190
|
## Configuration
|
|
@@ -406,7 +419,7 @@ src/agent/ → Claude Agent SDK integration, MCP tools
|
|
|
406
419
|
src/mcp/ → Standalone MCP stdio server adapter
|
|
407
420
|
src/plugins/ → Plugin system (methodology plugins)
|
|
408
421
|
├── types.ts → MarvinPlugin interface
|
|
409
|
-
├── common.ts → Shared registrations + tool factory (meetings, reports, features, epics, sprints)
|
|
422
|
+
├── common.ts → Shared registrations + tool factory (meetings, reports, features, epics, sprints, sprint planning)
|
|
410
423
|
├── registry.ts → Plugin resolution
|
|
411
424
|
└── builtin/
|
|
412
425
|
├── generic-agile.ts → Default methodology
|
package/dist/index.js
CHANGED
|
@@ -16204,6 +16204,188 @@ function createSprintTools(store) {
|
|
|
16204
16204
|
];
|
|
16205
16205
|
}
|
|
16206
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
|
+
|
|
16207
16389
|
// src/plugins/common.ts
|
|
16208
16390
|
var COMMON_REGISTRATIONS = [
|
|
16209
16391
|
{ type: "meeting", dirName: "meetings", idPrefix: "M" },
|
|
@@ -16220,7 +16402,8 @@ function createCommonTools(store) {
|
|
|
16220
16402
|
...createFeatureTools(store),
|
|
16221
16403
|
...createEpicTools(store),
|
|
16222
16404
|
...createContributionTools(store),
|
|
16223
|
-
...createSprintTools(store)
|
|
16405
|
+
...createSprintTools(store),
|
|
16406
|
+
...createSprintPlanningTools(store)
|
|
16224
16407
|
];
|
|
16225
16408
|
}
|
|
16226
16409
|
|
|
@@ -16293,7 +16476,12 @@ var genericAgilePlugin = {
|
|
|
16293
16476
|
- **list_sprints** / **get_sprint**: View sprints to understand iteration scope and delivery dates.
|
|
16294
16477
|
- **update_sprint**: Assign epics to sprints by updating linkedEpics when breaking features into work.
|
|
16295
16478
|
- Tag technical actions and decisions with \`sprint:SP-xxx\` to associate them with a sprint.
|
|
16296
|
-
- Use **generate_sprint_progress** to track technical work completion within an iteration
|
|
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.`,
|
|
16297
16485
|
"delivery-manager": `You track delivery across features and epics, manage schedules, and report on progress.
|
|
16298
16486
|
|
|
16299
16487
|
**Report Tools:**
|
|
@@ -16341,7 +16529,13 @@ var genericAgilePlugin = {
|
|
|
16341
16529
|
- Assign epics to sprints via linkedEpics.
|
|
16342
16530
|
- Tag work items (actions, decisions, questions) with \`sprint:SP-xxx\` for sprint scoping.
|
|
16343
16531
|
- Track delivery dates and flag at-risk sprints.
|
|
16344
|
-
- Register past/completed sprints for historical tracking
|
|
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.`,
|
|
16345
16539
|
"*": `You have access to feature, epic, sprint, and meeting tools for project coordination:
|
|
16346
16540
|
|
|
16347
16541
|
**Features** (F-xxx): Product capabilities defined by the Product Owner. Features progress through draft \u2192 approved \u2192 done.
|
|
@@ -16364,10 +16558,10 @@ var genericAgilePlugin = {
|
|
|
16364
16558
|
};
|
|
16365
16559
|
|
|
16366
16560
|
// src/plugins/builtin/tools/use-cases.ts
|
|
16367
|
-
import { tool as
|
|
16561
|
+
import { tool as tool14 } from "@anthropic-ai/claude-agent-sdk";
|
|
16368
16562
|
function createUseCaseTools(store) {
|
|
16369
16563
|
return [
|
|
16370
|
-
|
|
16564
|
+
tool14(
|
|
16371
16565
|
"list_use_cases",
|
|
16372
16566
|
"List all extension use cases, optionally filtered by status or extension type",
|
|
16373
16567
|
{
|
|
@@ -16397,7 +16591,7 @@ function createUseCaseTools(store) {
|
|
|
16397
16591
|
},
|
|
16398
16592
|
{ annotations: { readOnly: true } }
|
|
16399
16593
|
),
|
|
16400
|
-
|
|
16594
|
+
tool14(
|
|
16401
16595
|
"get_use_case",
|
|
16402
16596
|
"Get the full content of a specific use case by ID",
|
|
16403
16597
|
{ id: external_exports.string().describe("Use case ID (e.g. 'UC-001')") },
|
|
@@ -16424,7 +16618,7 @@ function createUseCaseTools(store) {
|
|
|
16424
16618
|
},
|
|
16425
16619
|
{ annotations: { readOnly: true } }
|
|
16426
16620
|
),
|
|
16427
|
-
|
|
16621
|
+
tool14(
|
|
16428
16622
|
"create_use_case",
|
|
16429
16623
|
"Create a new extension use case definition (Phase 1: Assess Extension Use Case)",
|
|
16430
16624
|
{
|
|
@@ -16458,7 +16652,7 @@ function createUseCaseTools(store) {
|
|
|
16458
16652
|
};
|
|
16459
16653
|
}
|
|
16460
16654
|
),
|
|
16461
|
-
|
|
16655
|
+
tool14(
|
|
16462
16656
|
"update_use_case",
|
|
16463
16657
|
"Update an existing extension use case",
|
|
16464
16658
|
{
|
|
@@ -16488,10 +16682,10 @@ function createUseCaseTools(store) {
|
|
|
16488
16682
|
}
|
|
16489
16683
|
|
|
16490
16684
|
// src/plugins/builtin/tools/tech-assessments.ts
|
|
16491
|
-
import { tool as
|
|
16685
|
+
import { tool as tool15 } from "@anthropic-ai/claude-agent-sdk";
|
|
16492
16686
|
function createTechAssessmentTools(store) {
|
|
16493
16687
|
return [
|
|
16494
|
-
|
|
16688
|
+
tool15(
|
|
16495
16689
|
"list_tech_assessments",
|
|
16496
16690
|
"List all technology assessments, optionally filtered by status",
|
|
16497
16691
|
{
|
|
@@ -16522,7 +16716,7 @@ function createTechAssessmentTools(store) {
|
|
|
16522
16716
|
},
|
|
16523
16717
|
{ annotations: { readOnly: true } }
|
|
16524
16718
|
),
|
|
16525
|
-
|
|
16719
|
+
tool15(
|
|
16526
16720
|
"get_tech_assessment",
|
|
16527
16721
|
"Get the full content of a specific technology assessment by ID",
|
|
16528
16722
|
{ id: external_exports.string().describe("Tech assessment ID (e.g. 'TA-001')") },
|
|
@@ -16549,7 +16743,7 @@ function createTechAssessmentTools(store) {
|
|
|
16549
16743
|
},
|
|
16550
16744
|
{ annotations: { readOnly: true } }
|
|
16551
16745
|
),
|
|
16552
|
-
|
|
16746
|
+
tool15(
|
|
16553
16747
|
"create_tech_assessment",
|
|
16554
16748
|
"Create a new technology assessment linked to an assessed/approved use case (Phase 2: Assess Extension Technology)",
|
|
16555
16749
|
{
|
|
@@ -16620,7 +16814,7 @@ function createTechAssessmentTools(store) {
|
|
|
16620
16814
|
};
|
|
16621
16815
|
}
|
|
16622
16816
|
),
|
|
16623
|
-
|
|
16817
|
+
tool15(
|
|
16624
16818
|
"update_tech_assessment",
|
|
16625
16819
|
"Update an existing technology assessment. The linked use case cannot be changed.",
|
|
16626
16820
|
{
|
|
@@ -16650,10 +16844,10 @@ function createTechAssessmentTools(store) {
|
|
|
16650
16844
|
}
|
|
16651
16845
|
|
|
16652
16846
|
// src/plugins/builtin/tools/extension-designs.ts
|
|
16653
|
-
import { tool as
|
|
16847
|
+
import { tool as tool16 } from "@anthropic-ai/claude-agent-sdk";
|
|
16654
16848
|
function createExtensionDesignTools(store) {
|
|
16655
16849
|
return [
|
|
16656
|
-
|
|
16850
|
+
tool16(
|
|
16657
16851
|
"list_extension_designs",
|
|
16658
16852
|
"List all extension designs, optionally filtered by status",
|
|
16659
16853
|
{
|
|
@@ -16683,7 +16877,7 @@ function createExtensionDesignTools(store) {
|
|
|
16683
16877
|
},
|
|
16684
16878
|
{ annotations: { readOnly: true } }
|
|
16685
16879
|
),
|
|
16686
|
-
|
|
16880
|
+
tool16(
|
|
16687
16881
|
"get_extension_design",
|
|
16688
16882
|
"Get the full content of a specific extension design by ID",
|
|
16689
16883
|
{ id: external_exports.string().describe("Extension design ID (e.g. 'XD-001')") },
|
|
@@ -16710,7 +16904,7 @@ function createExtensionDesignTools(store) {
|
|
|
16710
16904
|
},
|
|
16711
16905
|
{ annotations: { readOnly: true } }
|
|
16712
16906
|
),
|
|
16713
|
-
|
|
16907
|
+
tool16(
|
|
16714
16908
|
"create_extension_design",
|
|
16715
16909
|
"Create a new extension design linked to a recommended tech assessment (Phase 3: Define Extension Target Solution)",
|
|
16716
16910
|
{
|
|
@@ -16778,7 +16972,7 @@ function createExtensionDesignTools(store) {
|
|
|
16778
16972
|
};
|
|
16779
16973
|
}
|
|
16780
16974
|
),
|
|
16781
|
-
|
|
16975
|
+
tool16(
|
|
16782
16976
|
"update_extension_design",
|
|
16783
16977
|
"Update an existing extension design. The linked tech assessment cannot be changed.",
|
|
16784
16978
|
{
|
|
@@ -16807,10 +17001,10 @@ function createExtensionDesignTools(store) {
|
|
|
16807
17001
|
}
|
|
16808
17002
|
|
|
16809
17003
|
// src/plugins/builtin/tools/aem-reports.ts
|
|
16810
|
-
import { tool as
|
|
17004
|
+
import { tool as tool17 } from "@anthropic-ai/claude-agent-sdk";
|
|
16811
17005
|
function createAemReportTools(store) {
|
|
16812
17006
|
return [
|
|
16813
|
-
|
|
17007
|
+
tool17(
|
|
16814
17008
|
"generate_extension_portfolio",
|
|
16815
17009
|
"Generate a portfolio view of all use cases with their linked tech assessments and extension designs",
|
|
16816
17010
|
{},
|
|
@@ -16862,7 +17056,7 @@ function createAemReportTools(store) {
|
|
|
16862
17056
|
},
|
|
16863
17057
|
{ annotations: { readOnly: true } }
|
|
16864
17058
|
),
|
|
16865
|
-
|
|
17059
|
+
tool17(
|
|
16866
17060
|
"generate_tech_readiness",
|
|
16867
17061
|
"Generate a BTP technology readiness report showing service coverage and gaps across assessments",
|
|
16868
17062
|
{},
|
|
@@ -16914,7 +17108,7 @@ function createAemReportTools(store) {
|
|
|
16914
17108
|
},
|
|
16915
17109
|
{ annotations: { readOnly: true } }
|
|
16916
17110
|
),
|
|
16917
|
-
|
|
17111
|
+
tool17(
|
|
16918
17112
|
"generate_phase_status",
|
|
16919
17113
|
"Generate a phase progress report showing artifact counts and readiness per AEM phase",
|
|
16920
17114
|
{},
|
|
@@ -16976,11 +17170,11 @@ function createAemReportTools(store) {
|
|
|
16976
17170
|
import * as fs6 from "fs";
|
|
16977
17171
|
import * as path6 from "path";
|
|
16978
17172
|
import * as YAML4 from "yaml";
|
|
16979
|
-
import { tool as
|
|
17173
|
+
import { tool as tool18 } from "@anthropic-ai/claude-agent-sdk";
|
|
16980
17174
|
var PHASES = ["assess-use-case", "assess-technology", "define-solution"];
|
|
16981
17175
|
function createAemPhaseTools(store, marvinDir) {
|
|
16982
17176
|
return [
|
|
16983
|
-
|
|
17177
|
+
tool18(
|
|
16984
17178
|
"get_current_phase",
|
|
16985
17179
|
"Get the current AEM phase from project configuration",
|
|
16986
17180
|
{},
|
|
@@ -17001,7 +17195,7 @@ function createAemPhaseTools(store, marvinDir) {
|
|
|
17001
17195
|
},
|
|
17002
17196
|
{ annotations: { readOnly: true } }
|
|
17003
17197
|
),
|
|
17004
|
-
|
|
17198
|
+
tool18(
|
|
17005
17199
|
"advance_phase",
|
|
17006
17200
|
"Advance to the next AEM phase. Performs soft gate checks and warns if artifacts are incomplete, but does not block.",
|
|
17007
17201
|
{
|
|
@@ -17776,7 +17970,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
17776
17970
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
17777
17971
|
|
|
17778
17972
|
// src/skills/action-tools.ts
|
|
17779
|
-
import { tool as
|
|
17973
|
+
import { tool as tool19 } from "@anthropic-ai/claude-agent-sdk";
|
|
17780
17974
|
|
|
17781
17975
|
// src/skills/action-runner.ts
|
|
17782
17976
|
import { query as query3 } from "@anthropic-ai/claude-agent-sdk";
|
|
@@ -17842,7 +18036,7 @@ function createSkillActionTools(skills, context) {
|
|
|
17842
18036
|
if (!skill.actions) continue;
|
|
17843
18037
|
for (const action of skill.actions) {
|
|
17844
18038
|
tools.push(
|
|
17845
|
-
|
|
18039
|
+
tool19(
|
|
17846
18040
|
`${skill.id}__${action.id}`,
|
|
17847
18041
|
action.description,
|
|
17848
18042
|
{
|
|
@@ -17934,10 +18128,10 @@ ${lines.join("\n\n")}`;
|
|
|
17934
18128
|
}
|
|
17935
18129
|
|
|
17936
18130
|
// src/mcp/persona-tools.ts
|
|
17937
|
-
import { tool as
|
|
18131
|
+
import { tool as tool20 } from "@anthropic-ai/claude-agent-sdk";
|
|
17938
18132
|
function createPersonaTools(ctx, marvinDir) {
|
|
17939
18133
|
return [
|
|
17940
|
-
|
|
18134
|
+
tool20(
|
|
17941
18135
|
"set_persona",
|
|
17942
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.",
|
|
17943
18137
|
{
|
|
@@ -17967,7 +18161,7 @@ ${summaries}`
|
|
|
17967
18161
|
};
|
|
17968
18162
|
}
|
|
17969
18163
|
),
|
|
17970
|
-
|
|
18164
|
+
tool20(
|
|
17971
18165
|
"get_persona_guidance",
|
|
17972
18166
|
"Get guidance for a persona without changing the active persona. If no persona is specified, lists all available personas with summaries.",
|
|
17973
18167
|
{
|
|
@@ -20502,7 +20696,7 @@ function createProgram() {
|
|
|
20502
20696
|
const program = new Command();
|
|
20503
20697
|
program.name("marvin").description(
|
|
20504
20698
|
"AI-powered product development assistant with Product Owner, Delivery Manager, and Technical Lead personas"
|
|
20505
|
-
).version("0.2.
|
|
20699
|
+
).version("0.2.6");
|
|
20506
20700
|
program.command("init").description("Initialize a new Marvin project in the current directory").action(async () => {
|
|
20507
20701
|
await initCommand();
|
|
20508
20702
|
});
|