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 CHANGED
@@ -14557,7 +14557,8 @@ function createActionTools(store) {
14557
14557
  priority: external_exports.string().optional().describe("Priority (high, medium, low)"),
14558
14558
  tags: external_exports.array(external_exports.string()).optional().describe("Tags for categorization"),
14559
14559
  dueDate: external_exports.string().optional().describe("Due date in ISO format (e.g. '2026-03-15')"),
14560
- sprints: external_exports.array(external_exports.string()).optional().describe("Sprint IDs to assign (e.g. ['SP-001']). Adds sprint:SP-xxx tags.")
14560
+ sprints: external_exports.array(external_exports.string()).optional().describe("Sprint IDs to assign (e.g. ['SP-001']). Adds sprint:SP-xxx tags."),
14561
+ workStream: external_exports.string().optional().describe("Work stream name (e.g. 'Budget UX'). Adds a stream:<value> tag.")
14561
14562
  },
14562
14563
  async (args) => {
14563
14564
  const tags = [...args.tags ?? []];
@@ -14567,6 +14568,9 @@ function createActionTools(store) {
14567
14568
  if (!tags.includes(tag)) tags.push(tag);
14568
14569
  }
14569
14570
  }
14571
+ if (args.workStream) {
14572
+ tags.push(`stream:${args.workStream}`);
14573
+ }
14570
14574
  const doc = store.create(
14571
14575
  "action",
14572
14576
  {
@@ -14604,10 +14608,11 @@ function createActionTools(store) {
14604
14608
  priority: external_exports.string().optional().describe("New priority"),
14605
14609
  dueDate: external_exports.string().optional().describe("Due date in ISO format (e.g. '2026-03-15')"),
14606
14610
  tags: external_exports.array(external_exports.string()).optional().describe("Replace all tags. When provided with sprints, sprint tags are merged into this array."),
14607
- sprints: external_exports.array(external_exports.string()).optional().describe("Sprint IDs to assign (replaces existing sprint tags). E.g. ['SP-001'].")
14611
+ sprints: external_exports.array(external_exports.string()).optional().describe("Sprint IDs to assign (replaces existing sprint tags). E.g. ['SP-001']."),
14612
+ workStream: external_exports.string().optional().describe("Work stream name (e.g. 'Budget UX'). Replaces existing stream:<value> tag.")
14608
14613
  },
14609
14614
  async (args) => {
14610
- const { id, content, sprints, tags, ...updates } = args;
14615
+ const { id, content, sprints, tags, workStream, ...updates } = args;
14611
14616
  if (tags !== void 0) {
14612
14617
  const merged = [...tags];
14613
14618
  if (sprints) {
@@ -14616,8 +14621,14 @@ function createActionTools(store) {
14616
14621
  if (!merged.includes(tag)) merged.push(tag);
14617
14622
  }
14618
14623
  }
14619
- updates.tags = merged;
14620
- } else if (sprints !== void 0) {
14624
+ if (workStream !== void 0) {
14625
+ const filtered = merged.filter((t) => !t.startsWith("stream:"));
14626
+ filtered.push(`stream:${workStream}`);
14627
+ updates.tags = filtered;
14628
+ } else {
14629
+ updates.tags = merged;
14630
+ }
14631
+ } else if (sprints !== void 0 || workStream !== void 0) {
14621
14632
  const existing = store.get(id);
14622
14633
  if (!existing) {
14623
14634
  return {
@@ -14625,10 +14636,16 @@ function createActionTools(store) {
14625
14636
  isError: true
14626
14637
  };
14627
14638
  }
14628
- const existingTags = existing.frontmatter.tags ?? [];
14629
- const nonSprintTags = existingTags.filter((t) => !t.startsWith("sprint:"));
14630
- const newSprintTags = sprints.map((s) => `sprint:${s}`);
14631
- updates.tags = [...nonSprintTags, ...newSprintTags];
14639
+ let existingTags = existing.frontmatter.tags ?? [];
14640
+ if (sprints !== void 0) {
14641
+ existingTags = existingTags.filter((t) => !t.startsWith("sprint:"));
14642
+ existingTags.push(...sprints.map((s) => `sprint:${s}`));
14643
+ }
14644
+ if (workStream !== void 0) {
14645
+ existingTags = existingTags.filter((t) => !t.startsWith("stream:"));
14646
+ existingTags.push(`stream:${workStream}`);
14647
+ }
14648
+ updates.tags = existingTags;
14632
14649
  }
14633
14650
  const doc = store.update(id, updates, content);
14634
14651
  return {
@@ -14793,14 +14810,19 @@ function createDocumentTools(store) {
14793
14810
  {
14794
14811
  type: external_exports.string().optional().describe(`Filter by document type (registered types: ${store.registeredTypes.join(", ")})`),
14795
14812
  status: external_exports.string().optional().describe("Filter by status"),
14796
- tag: external_exports.string().optional().describe("Filter by tag")
14813
+ tag: external_exports.string().optional().describe("Filter by tag"),
14814
+ workStream: external_exports.string().optional().describe("Filter by work stream name (matches stream:<value> tag)")
14797
14815
  },
14798
14816
  async (args) => {
14799
- const docs = store.list({
14817
+ let docs = store.list({
14800
14818
  type: args.type,
14801
14819
  status: args.status,
14802
14820
  tag: args.tag
14803
14821
  });
14822
+ if (args.workStream) {
14823
+ const streamTag = `stream:${args.workStream}`;
14824
+ docs = docs.filter((d) => d.frontmatter.tags?.includes(streamTag));
14825
+ }
14804
14826
  const summary = docs.map((d) => ({
14805
14827
  id: d.frontmatter.id,
14806
14828
  title: d.frontmatter.title,
@@ -15493,11 +15515,13 @@ function collectSprintSummaryData(store, sprintId) {
15493
15515
  const sprintItemIds = new Set(workItemDocs.map((d) => d.frontmatter.id));
15494
15516
  for (const doc of workItemDocs) {
15495
15517
  const about = doc.frontmatter.aboutArtifact;
15518
+ const streamTag = (doc.frontmatter.tags ?? []).find((t) => t.startsWith("stream:"));
15496
15519
  const item = {
15497
15520
  id: doc.frontmatter.id,
15498
15521
  title: doc.frontmatter.title,
15499
15522
  type: doc.frontmatter.type,
15500
15523
  status: doc.frontmatter.status,
15524
+ workStream: streamTag ? streamTag.slice(7) : void 0,
15501
15525
  aboutArtifact: about
15502
15526
  };
15503
15527
  allItemsById.set(item.id, item);
@@ -18196,10 +18220,12 @@ function sprintSummaryPage(data, cached2) {
18196
18220
  const isContribution = w.type === "contribution";
18197
18221
  const rowClass = isContribution ? ' class="contribution-row"' : isChild ? ' class="child-row"' : "";
18198
18222
  const indent = depth > 0 ? ` style="padding-left: ${0.75 + depth * 1}rem"` : "";
18223
+ const streamCell = w.workStream ? `<span class="badge badge-subtle">${escapeHtml(w.workStream)}</span>` : "";
18199
18224
  const row = `
18200
18225
  <tr${rowClass}>
18201
18226
  <td${indent}><a href="/docs/${escapeHtml(w.type)}/${escapeHtml(w.id)}">${escapeHtml(w.id)}</a></td>
18202
18227
  <td>${escapeHtml(w.title)}</td>
18228
+ <td>${streamCell}</td>
18203
18229
  <td>${escapeHtml(typeLabel(w.type))}</td>
18204
18230
  <td>${statusBadge(w.status)}</td>
18205
18231
  </tr>`;
@@ -18214,7 +18240,7 @@ function sprintSummaryPage(data, cached2) {
18214
18240
  `<div class="table-wrap">
18215
18241
  <table>
18216
18242
  <thead>
18217
- <tr><th>ID</th><th>Title</th><th>Type</th><th>Status</th></tr>
18243
+ <tr><th>ID</th><th>Title</th><th>Stream</th><th>Type</th><th>Status</th></tr>
18218
18244
  </thead>
18219
18245
  <tbody>
18220
18246
  ${workItemRows.join("")}
@@ -19513,7 +19539,8 @@ function createContributionTools(store) {
19513
19539
  contributionType: external_exports.string().describe("Type of contribution (e.g. 'action-result', 'risk-finding')"),
19514
19540
  aboutArtifact: external_exports.string().describe("Artifact ID this contribution relates to (e.g. 'A-001', 'T-003')"),
19515
19541
  status: external_exports.string().optional().describe("Status (default: 'done')"),
19516
- tags: external_exports.array(external_exports.string()).optional().describe("Tags for categorization")
19542
+ tags: external_exports.array(external_exports.string()).optional().describe("Tags for categorization"),
19543
+ workStream: external_exports.string().optional().describe("Work stream name (e.g. 'Budget UX'). Adds a stream:<value> tag.")
19517
19544
  },
19518
19545
  async (args) => {
19519
19546
  const frontmatter = {
@@ -19523,7 +19550,9 @@ function createContributionTools(store) {
19523
19550
  contributionType: args.contributionType
19524
19551
  };
19525
19552
  frontmatter.aboutArtifact = args.aboutArtifact;
19526
- if (args.tags) frontmatter.tags = args.tags;
19553
+ const tags = [...args.tags ?? []];
19554
+ if (args.workStream) tags.push(`stream:${args.workStream}`);
19555
+ if (tags.length > 0) frontmatter.tags = tags;
19527
19556
  const doc = store.create("contribution", frontmatter, args.content);
19528
19557
  return {
19529
19558
  content: [
@@ -19542,10 +19571,18 @@ function createContributionTools(store) {
19542
19571
  id: external_exports.string().describe("Contribution ID to update"),
19543
19572
  title: external_exports.string().optional().describe("New title"),
19544
19573
  status: external_exports.string().optional().describe("New status"),
19545
- content: external_exports.string().optional().describe("New content")
19574
+ content: external_exports.string().optional().describe("New content"),
19575
+ workStream: external_exports.string().optional().describe("Work stream name (e.g. 'Budget UX'). Replaces existing stream:<value> tag.")
19546
19576
  },
19547
19577
  async (args) => {
19548
- const { id, content, ...updates } = args;
19578
+ const { id, content, workStream, ...updates } = args;
19579
+ if (workStream !== void 0) {
19580
+ const existing = store.get(id);
19581
+ const existingTags = existing?.frontmatter.tags ?? [];
19582
+ const filtered = existingTags.filter((t) => !t.startsWith("stream:"));
19583
+ filtered.push(`stream:${workStream}`);
19584
+ updates.tags = filtered;
19585
+ }
19549
19586
  const doc = store.update(id, updates, content);
19550
19587
  return {
19551
19588
  content: [
@@ -20013,7 +20050,8 @@ function createTaskTools(store) {
20013
20050
  estimatedPoints: external_exports.number().optional().describe("Story point estimate"),
20014
20051
  complexity: external_exports.enum(["trivial", "simple", "moderate", "complex", "very-complex"]).optional().describe("Task complexity"),
20015
20052
  priority: external_exports.enum(["critical", "high", "medium", "low"]).optional().describe("Task priority"),
20016
- tags: external_exports.array(external_exports.string()).optional().describe("Additional tags")
20053
+ tags: external_exports.array(external_exports.string()).optional().describe("Additional tags"),
20054
+ workStream: external_exports.string().optional().describe("Work stream name (e.g. 'Budget UX'). Adds a stream:<value> tag.")
20017
20055
  },
20018
20056
  async (args) => {
20019
20057
  const linkedEpics = normalizeLinkedEpics(args.linkedEpic);
@@ -20026,11 +20064,13 @@ function createTaskTools(store) {
20026
20064
  warnings.push(`Warning: ${epicId} is a ${epic.frontmatter.type}, not an epic`);
20027
20065
  }
20028
20066
  }
20067
+ const baseTags = [...generateEpicTags(linkedEpics), ...args.tags ?? []];
20068
+ if (args.workStream) baseTags.push(`stream:${args.workStream}`);
20029
20069
  const frontmatter = {
20030
20070
  title: args.title,
20031
20071
  status: args.status ?? "backlog",
20032
20072
  linkedEpic: linkedEpics,
20033
- tags: [...generateEpicTags(linkedEpics), ...args.tags ?? []]
20073
+ tags: baseTags
20034
20074
  };
20035
20075
  if (args.aboutArtifact) frontmatter.aboutArtifact = args.aboutArtifact;
20036
20076
  if (args.acceptanceCriteria) frontmatter.acceptanceCriteria = args.acceptanceCriteria;
@@ -20065,10 +20105,11 @@ function createTaskTools(store) {
20065
20105
  estimatedPoints: external_exports.number().optional().describe("New story point estimate"),
20066
20106
  complexity: external_exports.enum(["trivial", "simple", "moderate", "complex", "very-complex"]).optional().describe("New complexity"),
20067
20107
  priority: external_exports.enum(["critical", "high", "medium", "low"]).optional().describe("New priority"),
20068
- tags: external_exports.array(external_exports.string()).optional().describe("Replace tags (e.g. remove old tags, add new ones)")
20108
+ tags: external_exports.array(external_exports.string()).optional().describe("Replace tags (e.g. remove old tags, add new ones)"),
20109
+ workStream: external_exports.string().optional().describe("Work stream name (e.g. 'Budget UX'). Replaces existing stream:<value> tag.")
20069
20110
  },
20070
20111
  async (args) => {
20071
- const { id, content, linkedEpic: rawLinkedEpic, tags: userTags, ...updates } = args;
20112
+ const { id, content, linkedEpic: rawLinkedEpic, tags: userTags, workStream, ...updates } = args;
20072
20113
  const warnings = [];
20073
20114
  if (rawLinkedEpic !== void 0) {
20074
20115
  const linkedEpics = normalizeLinkedEpics(rawLinkedEpic);
@@ -20089,6 +20130,12 @@ function createTaskTools(store) {
20089
20130
  } else if (userTags !== void 0) {
20090
20131
  updates.tags = userTags;
20091
20132
  }
20133
+ if (workStream !== void 0) {
20134
+ const currentTags = updates.tags ?? store.get(id)?.frontmatter.tags ?? [];
20135
+ const filtered = currentTags.filter((t) => !t.startsWith("stream:"));
20136
+ filtered.push(`stream:${workStream}`);
20137
+ updates.tags = filtered;
20138
+ }
20092
20139
  const doc = store.update(id, updates, content);
20093
20140
  const parts = [`Updated task ${doc.frontmatter.id}: ${doc.frontmatter.title}`];
20094
20141
  if (warnings.length > 0) {
@@ -26230,7 +26277,7 @@ function createProgram() {
26230
26277
  const program = new Command();
26231
26278
  program.name("marvin").description(
26232
26279
  "AI-powered product development assistant with Product Owner, Delivery Manager, and Technical Lead personas"
26233
- ).version("0.4.8");
26280
+ ).version("0.4.9");
26234
26281
  program.command("init").description("Initialize a new Marvin project in the current directory").action(async () => {
26235
26282
  await initCommand();
26236
26283
  });