mrvn-cli 0.4.8 → 0.4.9
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/dist/index.js +68 -21
- package/dist/index.js.map +1 -1
- package/dist/marvin-serve.js +67 -20
- package/dist/marvin-serve.js.map +1 -1
- package/dist/marvin.js +68 -21
- package/dist/marvin.js.map +1 -1
- package/package.json +1 -1
package/dist/marvin.js
CHANGED
|
@@ -14594,11 +14594,13 @@ function collectSprintSummaryData(store, sprintId) {
|
|
|
14594
14594
|
const sprintItemIds = new Set(workItemDocs.map((d) => d.frontmatter.id));
|
|
14595
14595
|
for (const doc of workItemDocs) {
|
|
14596
14596
|
const about = doc.frontmatter.aboutArtifact;
|
|
14597
|
+
const streamTag = (doc.frontmatter.tags ?? []).find((t) => t.startsWith("stream:"));
|
|
14597
14598
|
const item = {
|
|
14598
14599
|
id: doc.frontmatter.id,
|
|
14599
14600
|
title: doc.frontmatter.title,
|
|
14600
14601
|
type: doc.frontmatter.type,
|
|
14601
14602
|
status: doc.frontmatter.status,
|
|
14603
|
+
workStream: streamTag ? streamTag.slice(7) : void 0,
|
|
14602
14604
|
aboutArtifact: about
|
|
14603
14605
|
};
|
|
14604
14606
|
allItemsById.set(item.id, item);
|
|
@@ -15618,7 +15620,8 @@ function createContributionTools(store) {
|
|
|
15618
15620
|
contributionType: external_exports.string().describe("Type of contribution (e.g. 'action-result', 'risk-finding')"),
|
|
15619
15621
|
aboutArtifact: external_exports.string().describe("Artifact ID this contribution relates to (e.g. 'A-001', 'T-003')"),
|
|
15620
15622
|
status: external_exports.string().optional().describe("Status (default: 'done')"),
|
|
15621
|
-
tags: external_exports.array(external_exports.string()).optional().describe("Tags for categorization")
|
|
15623
|
+
tags: external_exports.array(external_exports.string()).optional().describe("Tags for categorization"),
|
|
15624
|
+
workStream: external_exports.string().optional().describe("Work stream name (e.g. 'Budget UX'). Adds a stream:<value> tag.")
|
|
15622
15625
|
},
|
|
15623
15626
|
async (args) => {
|
|
15624
15627
|
const frontmatter = {
|
|
@@ -15628,7 +15631,9 @@ function createContributionTools(store) {
|
|
|
15628
15631
|
contributionType: args.contributionType
|
|
15629
15632
|
};
|
|
15630
15633
|
frontmatter.aboutArtifact = args.aboutArtifact;
|
|
15631
|
-
|
|
15634
|
+
const tags = [...args.tags ?? []];
|
|
15635
|
+
if (args.workStream) tags.push(`stream:${args.workStream}`);
|
|
15636
|
+
if (tags.length > 0) frontmatter.tags = tags;
|
|
15632
15637
|
const doc = store.create("contribution", frontmatter, args.content);
|
|
15633
15638
|
return {
|
|
15634
15639
|
content: [
|
|
@@ -15647,10 +15652,18 @@ function createContributionTools(store) {
|
|
|
15647
15652
|
id: external_exports.string().describe("Contribution ID to update"),
|
|
15648
15653
|
title: external_exports.string().optional().describe("New title"),
|
|
15649
15654
|
status: external_exports.string().optional().describe("New status"),
|
|
15650
|
-
content: external_exports.string().optional().describe("New content")
|
|
15655
|
+
content: external_exports.string().optional().describe("New content"),
|
|
15656
|
+
workStream: external_exports.string().optional().describe("Work stream name (e.g. 'Budget UX'). Replaces existing stream:<value> tag.")
|
|
15651
15657
|
},
|
|
15652
15658
|
async (args) => {
|
|
15653
|
-
const { id, content, ...updates } = args;
|
|
15659
|
+
const { id, content, workStream, ...updates } = args;
|
|
15660
|
+
if (workStream !== void 0) {
|
|
15661
|
+
const existing = store.get(id);
|
|
15662
|
+
const existingTags = existing?.frontmatter.tags ?? [];
|
|
15663
|
+
const filtered = existingTags.filter((t) => !t.startsWith("stream:"));
|
|
15664
|
+
filtered.push(`stream:${workStream}`);
|
|
15665
|
+
updates.tags = filtered;
|
|
15666
|
+
}
|
|
15654
15667
|
const doc = store.update(id, updates, content);
|
|
15655
15668
|
return {
|
|
15656
15669
|
content: [
|
|
@@ -16118,7 +16131,8 @@ function createTaskTools(store) {
|
|
|
16118
16131
|
estimatedPoints: external_exports.number().optional().describe("Story point estimate"),
|
|
16119
16132
|
complexity: external_exports.enum(["trivial", "simple", "moderate", "complex", "very-complex"]).optional().describe("Task complexity"),
|
|
16120
16133
|
priority: external_exports.enum(["critical", "high", "medium", "low"]).optional().describe("Task priority"),
|
|
16121
|
-
tags: external_exports.array(external_exports.string()).optional().describe("Additional tags")
|
|
16134
|
+
tags: external_exports.array(external_exports.string()).optional().describe("Additional tags"),
|
|
16135
|
+
workStream: external_exports.string().optional().describe("Work stream name (e.g. 'Budget UX'). Adds a stream:<value> tag.")
|
|
16122
16136
|
},
|
|
16123
16137
|
async (args) => {
|
|
16124
16138
|
const linkedEpics = normalizeLinkedEpics(args.linkedEpic);
|
|
@@ -16131,11 +16145,13 @@ function createTaskTools(store) {
|
|
|
16131
16145
|
warnings.push(`Warning: ${epicId} is a ${epic.frontmatter.type}, not an epic`);
|
|
16132
16146
|
}
|
|
16133
16147
|
}
|
|
16148
|
+
const baseTags = [...generateEpicTags(linkedEpics), ...args.tags ?? []];
|
|
16149
|
+
if (args.workStream) baseTags.push(`stream:${args.workStream}`);
|
|
16134
16150
|
const frontmatter = {
|
|
16135
16151
|
title: args.title,
|
|
16136
16152
|
status: args.status ?? "backlog",
|
|
16137
16153
|
linkedEpic: linkedEpics,
|
|
16138
|
-
tags:
|
|
16154
|
+
tags: baseTags
|
|
16139
16155
|
};
|
|
16140
16156
|
if (args.aboutArtifact) frontmatter.aboutArtifact = args.aboutArtifact;
|
|
16141
16157
|
if (args.acceptanceCriteria) frontmatter.acceptanceCriteria = args.acceptanceCriteria;
|
|
@@ -16170,10 +16186,11 @@ function createTaskTools(store) {
|
|
|
16170
16186
|
estimatedPoints: external_exports.number().optional().describe("New story point estimate"),
|
|
16171
16187
|
complexity: external_exports.enum(["trivial", "simple", "moderate", "complex", "very-complex"]).optional().describe("New complexity"),
|
|
16172
16188
|
priority: external_exports.enum(["critical", "high", "medium", "low"]).optional().describe("New priority"),
|
|
16173
|
-
tags: external_exports.array(external_exports.string()).optional().describe("Replace tags (e.g. remove old tags, add new ones)")
|
|
16189
|
+
tags: external_exports.array(external_exports.string()).optional().describe("Replace tags (e.g. remove old tags, add new ones)"),
|
|
16190
|
+
workStream: external_exports.string().optional().describe("Work stream name (e.g. 'Budget UX'). Replaces existing stream:<value> tag.")
|
|
16174
16191
|
},
|
|
16175
16192
|
async (args) => {
|
|
16176
|
-
const { id, content, linkedEpic: rawLinkedEpic, tags: userTags, ...updates } = args;
|
|
16193
|
+
const { id, content, linkedEpic: rawLinkedEpic, tags: userTags, workStream, ...updates } = args;
|
|
16177
16194
|
const warnings = [];
|
|
16178
16195
|
if (rawLinkedEpic !== void 0) {
|
|
16179
16196
|
const linkedEpics = normalizeLinkedEpics(rawLinkedEpic);
|
|
@@ -16194,6 +16211,12 @@ function createTaskTools(store) {
|
|
|
16194
16211
|
} else if (userTags !== void 0) {
|
|
16195
16212
|
updates.tags = userTags;
|
|
16196
16213
|
}
|
|
16214
|
+
if (workStream !== void 0) {
|
|
16215
|
+
const currentTags = updates.tags ?? store.get(id)?.frontmatter.tags ?? [];
|
|
16216
|
+
const filtered = currentTags.filter((t) => !t.startsWith("stream:"));
|
|
16217
|
+
filtered.push(`stream:${workStream}`);
|
|
16218
|
+
updates.tags = filtered;
|
|
16219
|
+
}
|
|
16197
16220
|
const doc = store.update(id, updates, content);
|
|
16198
16221
|
const parts = [`Updated task ${doc.frontmatter.id}: ${doc.frontmatter.title}`];
|
|
16199
16222
|
if (warnings.length > 0) {
|
|
@@ -18180,7 +18203,8 @@ function createActionTools(store) {
|
|
|
18180
18203
|
priority: external_exports.string().optional().describe("Priority (high, medium, low)"),
|
|
18181
18204
|
tags: external_exports.array(external_exports.string()).optional().describe("Tags for categorization"),
|
|
18182
18205
|
dueDate: external_exports.string().optional().describe("Due date in ISO format (e.g. '2026-03-15')"),
|
|
18183
|
-
sprints: external_exports.array(external_exports.string()).optional().describe("Sprint IDs to assign (e.g. ['SP-001']). Adds sprint:SP-xxx tags.")
|
|
18206
|
+
sprints: external_exports.array(external_exports.string()).optional().describe("Sprint IDs to assign (e.g. ['SP-001']). Adds sprint:SP-xxx tags."),
|
|
18207
|
+
workStream: external_exports.string().optional().describe("Work stream name (e.g. 'Budget UX'). Adds a stream:<value> tag.")
|
|
18184
18208
|
},
|
|
18185
18209
|
async (args) => {
|
|
18186
18210
|
const tags = [...args.tags ?? []];
|
|
@@ -18190,6 +18214,9 @@ function createActionTools(store) {
|
|
|
18190
18214
|
if (!tags.includes(tag)) tags.push(tag);
|
|
18191
18215
|
}
|
|
18192
18216
|
}
|
|
18217
|
+
if (args.workStream) {
|
|
18218
|
+
tags.push(`stream:${args.workStream}`);
|
|
18219
|
+
}
|
|
18193
18220
|
const doc = store.create(
|
|
18194
18221
|
"action",
|
|
18195
18222
|
{
|
|
@@ -18227,10 +18254,11 @@ function createActionTools(store) {
|
|
|
18227
18254
|
priority: external_exports.string().optional().describe("New priority"),
|
|
18228
18255
|
dueDate: external_exports.string().optional().describe("Due date in ISO format (e.g. '2026-03-15')"),
|
|
18229
18256
|
tags: external_exports.array(external_exports.string()).optional().describe("Replace all tags. When provided with sprints, sprint tags are merged into this array."),
|
|
18230
|
-
sprints: external_exports.array(external_exports.string()).optional().describe("Sprint IDs to assign (replaces existing sprint tags). E.g. ['SP-001'].")
|
|
18257
|
+
sprints: external_exports.array(external_exports.string()).optional().describe("Sprint IDs to assign (replaces existing sprint tags). E.g. ['SP-001']."),
|
|
18258
|
+
workStream: external_exports.string().optional().describe("Work stream name (e.g. 'Budget UX'). Replaces existing stream:<value> tag.")
|
|
18231
18259
|
},
|
|
18232
18260
|
async (args) => {
|
|
18233
|
-
const { id, content, sprints, tags, ...updates } = args;
|
|
18261
|
+
const { id, content, sprints, tags, workStream, ...updates } = args;
|
|
18234
18262
|
if (tags !== void 0) {
|
|
18235
18263
|
const merged = [...tags];
|
|
18236
18264
|
if (sprints) {
|
|
@@ -18239,8 +18267,14 @@ function createActionTools(store) {
|
|
|
18239
18267
|
if (!merged.includes(tag)) merged.push(tag);
|
|
18240
18268
|
}
|
|
18241
18269
|
}
|
|
18242
|
-
|
|
18243
|
-
|
|
18270
|
+
if (workStream !== void 0) {
|
|
18271
|
+
const filtered = merged.filter((t) => !t.startsWith("stream:"));
|
|
18272
|
+
filtered.push(`stream:${workStream}`);
|
|
18273
|
+
updates.tags = filtered;
|
|
18274
|
+
} else {
|
|
18275
|
+
updates.tags = merged;
|
|
18276
|
+
}
|
|
18277
|
+
} else if (sprints !== void 0 || workStream !== void 0) {
|
|
18244
18278
|
const existing = store.get(id);
|
|
18245
18279
|
if (!existing) {
|
|
18246
18280
|
return {
|
|
@@ -18248,10 +18282,16 @@ function createActionTools(store) {
|
|
|
18248
18282
|
isError: true
|
|
18249
18283
|
};
|
|
18250
18284
|
}
|
|
18251
|
-
|
|
18252
|
-
|
|
18253
|
-
|
|
18254
|
-
|
|
18285
|
+
let existingTags = existing.frontmatter.tags ?? [];
|
|
18286
|
+
if (sprints !== void 0) {
|
|
18287
|
+
existingTags = existingTags.filter((t) => !t.startsWith("sprint:"));
|
|
18288
|
+
existingTags.push(...sprints.map((s) => `sprint:${s}`));
|
|
18289
|
+
}
|
|
18290
|
+
if (workStream !== void 0) {
|
|
18291
|
+
existingTags = existingTags.filter((t) => !t.startsWith("stream:"));
|
|
18292
|
+
existingTags.push(`stream:${workStream}`);
|
|
18293
|
+
}
|
|
18294
|
+
updates.tags = existingTags;
|
|
18255
18295
|
}
|
|
18256
18296
|
const doc = store.update(id, updates, content);
|
|
18257
18297
|
return {
|
|
@@ -18416,14 +18456,19 @@ function createDocumentTools(store) {
|
|
|
18416
18456
|
{
|
|
18417
18457
|
type: external_exports.string().optional().describe(`Filter by document type (registered types: ${store.registeredTypes.join(", ")})`),
|
|
18418
18458
|
status: external_exports.string().optional().describe("Filter by status"),
|
|
18419
|
-
tag: external_exports.string().optional().describe("Filter by tag")
|
|
18459
|
+
tag: external_exports.string().optional().describe("Filter by tag"),
|
|
18460
|
+
workStream: external_exports.string().optional().describe("Filter by work stream name (matches stream:<value> tag)")
|
|
18420
18461
|
},
|
|
18421
18462
|
async (args) => {
|
|
18422
|
-
|
|
18463
|
+
let docs = store.list({
|
|
18423
18464
|
type: args.type,
|
|
18424
18465
|
status: args.status,
|
|
18425
18466
|
tag: args.tag
|
|
18426
18467
|
});
|
|
18468
|
+
if (args.workStream) {
|
|
18469
|
+
const streamTag = `stream:${args.workStream}`;
|
|
18470
|
+
docs = docs.filter((d) => d.frontmatter.tags?.includes(streamTag));
|
|
18471
|
+
}
|
|
18427
18472
|
const summary = docs.map((d) => ({
|
|
18428
18473
|
id: d.frontmatter.id,
|
|
18429
18474
|
title: d.frontmatter.title,
|
|
@@ -21165,10 +21210,12 @@ function sprintSummaryPage(data, cached2) {
|
|
|
21165
21210
|
const isContribution = w.type === "contribution";
|
|
21166
21211
|
const rowClass = isContribution ? ' class="contribution-row"' : isChild ? ' class="child-row"' : "";
|
|
21167
21212
|
const indent = depth > 0 ? ` style="padding-left: ${0.75 + depth * 1}rem"` : "";
|
|
21213
|
+
const streamCell = w.workStream ? `<span class="badge badge-subtle">${escapeHtml(w.workStream)}</span>` : "";
|
|
21168
21214
|
const row = `
|
|
21169
21215
|
<tr${rowClass}>
|
|
21170
21216
|
<td${indent}><a href="/docs/${escapeHtml(w.type)}/${escapeHtml(w.id)}">${escapeHtml(w.id)}</a></td>
|
|
21171
21217
|
<td>${escapeHtml(w.title)}</td>
|
|
21218
|
+
<td>${streamCell}</td>
|
|
21172
21219
|
<td>${escapeHtml(typeLabel(w.type))}</td>
|
|
21173
21220
|
<td>${statusBadge(w.status)}</td>
|
|
21174
21221
|
</tr>`;
|
|
@@ -21183,7 +21230,7 @@ function sprintSummaryPage(data, cached2) {
|
|
|
21183
21230
|
`<div class="table-wrap">
|
|
21184
21231
|
<table>
|
|
21185
21232
|
<thead>
|
|
21186
|
-
<tr><th>ID</th><th>Title</th><th>Type</th><th>Status</th></tr>
|
|
21233
|
+
<tr><th>ID</th><th>Title</th><th>Stream</th><th>Type</th><th>Status</th></tr>
|
|
21187
21234
|
</thead>
|
|
21188
21235
|
<tbody>
|
|
21189
21236
|
${workItemRows.join("")}
|
|
@@ -26224,7 +26271,7 @@ function createProgram() {
|
|
|
26224
26271
|
const program2 = new Command();
|
|
26225
26272
|
program2.name("marvin").description(
|
|
26226
26273
|
"AI-powered product development assistant with Product Owner, Delivery Manager, and Technical Lead personas"
|
|
26227
|
-
).version("0.4.
|
|
26274
|
+
).version("0.4.9");
|
|
26228
26275
|
program2.command("init").description("Initialize a new Marvin project in the current directory").action(async () => {
|
|
26229
26276
|
await initCommand();
|
|
26230
26277
|
});
|