mrvn-cli 0.5.18 → 0.5.20

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.
@@ -14586,7 +14586,7 @@ function createActionTools(store) {
14586
14586
  tags: external_exports.array(external_exports.string()).optional().describe("Replace all tags. When provided with sprints, sprint tags are merged into this array."),
14587
14587
  sprints: external_exports.array(external_exports.string()).optional().describe("Sprint IDs to assign (replaces existing sprint tags). E.g. ['SP-001']."),
14588
14588
  workFocus: external_exports.string().optional().describe("Work focus name (e.g. 'Budget UX'). Replaces existing focus:<value> tag."),
14589
- progress: external_exports.number().optional().describe("Explicit progress percentage (0-100).")
14589
+ progress: external_exports.number().nullable().optional().describe("Explicit progress percentage (0-100). Pass null to clear the override and revert to auto-calculation from children.")
14590
14590
  },
14591
14591
  async (args) => {
14592
14592
  const { id, content, sprints, tags, workFocus, progress, owner, assignee, ...updates } = args;
@@ -14629,6 +14629,8 @@ function createActionTools(store) {
14629
14629
  if (typeof progress === "number") {
14630
14630
  updates.progress = Math.max(0, Math.min(100, Math.round(progress)));
14631
14631
  updates.progressOverride = true;
14632
+ } else if (progress === null) {
14633
+ updates.progressOverride = false;
14632
14634
  }
14633
14635
  const doc = store.update(id, updates, content);
14634
14636
  if (args.status !== void 0 || typeof progress === "number") {
@@ -17865,7 +17867,7 @@ function createTaskTools(store) {
17865
17867
  priority: external_exports.enum(["critical", "high", "medium", "low"]).optional().describe("New priority"),
17866
17868
  tags: external_exports.array(external_exports.string()).optional().describe("Replace tags (e.g. remove old tags, add new ones)"),
17867
17869
  workFocus: external_exports.string().optional().describe("Work focus name (e.g. 'Budget UX'). Replaces existing focus:<value> tag."),
17868
- progress: external_exports.number().optional().describe("Explicit progress percentage (0-100). Overrides auto-calculation from child contributions.")
17870
+ progress: external_exports.number().nullable().optional().describe("Explicit progress percentage (0-100). Overrides auto-calculation from child contributions. Pass null to clear the override and revert to auto-calculation.")
17869
17871
  },
17870
17872
  async (args) => {
17871
17873
  const { id, content, linkedEpic: rawLinkedEpic, tags: userTags, workFocus, progress, ...updates } = args;
@@ -17898,6 +17900,8 @@ function createTaskTools(store) {
17898
17900
  if (typeof progress === "number") {
17899
17901
  updates.progress = Math.max(0, Math.min(100, Math.round(progress)));
17900
17902
  updates.progressOverride = true;
17903
+ } else if (progress === null) {
17904
+ updates.progressOverride = false;
17901
17905
  }
17902
17906
  const doc = store.update(id, updates, content);
17903
17907
  if (args.status !== void 0 || typeof progress === "number") {
@@ -20750,16 +20754,34 @@ async function _assessArtifactRecursive(store, client, host, options, visited, d
20750
20754
  );
20751
20755
  children.push(childReport);
20752
20756
  }
20757
+ if (children.length > 0) {
20758
+ const rolledUpProgress = Math.round(
20759
+ children.reduce((s, c) => s + c.marvinProgress, 0) / children.length
20760
+ );
20761
+ if (rolledUpProgress !== currentProgress) {
20762
+ proposedUpdates.push({
20763
+ artifactId: fm.id,
20764
+ field: "progress",
20765
+ currentValue: currentProgress,
20766
+ proposedValue: rolledUpProgress,
20767
+ reason: `Rolled up from ${children.length} children (average ${rolledUpProgress}%)`
20768
+ });
20769
+ }
20770
+ }
20753
20771
  const signals = buildSignals(commentSignals, linkedIssues, statusDrift, proposedMarvinStatus);
20754
20772
  const appliedUpdates = [];
20755
20773
  if (options.applyUpdates && proposedUpdates.length > 0) {
20756
20774
  for (const update of proposedUpdates) {
20757
20775
  if (update.field === "review") continue;
20758
20776
  try {
20759
- store.update(update.artifactId, {
20777
+ const updatePayload = {
20760
20778
  [update.field]: update.proposedValue,
20761
20779
  lastJiraSyncAt: (/* @__PURE__ */ new Date()).toISOString()
20762
- });
20780
+ };
20781
+ if (update.field === "progress") {
20782
+ updatePayload.progressOverride = false;
20783
+ }
20784
+ store.update(update.artifactId, updatePayload);
20763
20785
  const updatedDoc = store.get(update.artifactId);
20764
20786
  if (updatedDoc) {
20765
20787
  if (updatedDoc.frontmatter.type === "task") {
@@ -20994,11 +21016,9 @@ function formatArtifactReport(report) {
20994
21016
  }
20995
21017
  if (report.children.length > 0) {
20996
21018
  const doneCount = report.children.filter((c) => DONE_STATUSES6.has(c.marvinStatus)).length;
20997
- const childWeights = report.children.map((c) => {
20998
- const { weight } = resolveWeight(void 0);
20999
- return { weight, progress: c.marvinProgress };
21000
- });
21001
- const childProgress = childWeights.length > 0 ? Math.round(childWeights.reduce((s, c) => s + c.weight * c.progress, 0) / childWeights.reduce((s, c) => s + c.weight, 0)) : 0;
21019
+ const childProgress = Math.round(
21020
+ report.children.reduce((s, c) => s + c.marvinProgress, 0) / report.children.length
21021
+ );
21002
21022
  const bar = progressBar(childProgress);
21003
21023
  parts.push(`## Children (${doneCount}/${report.children.length} done) ${bar} ${childProgress}%`);
21004
21024
  for (const child of report.children) {