mrvn-cli 0.5.24 → 0.5.25
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 +7464 -7278
- package/dist/index.js.map +1 -1
- package/dist/marvin-serve.js +195 -11
- package/dist/marvin-serve.js.map +1 -1
- package/dist/marvin.js +196 -12
- package/dist/marvin.js.map +1 -1
- package/package.json +1 -1
package/dist/marvin-serve.js
CHANGED
|
@@ -20841,20 +20841,38 @@ async function _assessArtifactRecursive(store, client, host, options, visited, d
|
|
|
20841
20841
|
}
|
|
20842
20842
|
}
|
|
20843
20843
|
if (options.applyUpdates) {
|
|
20844
|
-
const
|
|
20844
|
+
const newEntry = buildAssessmentSummary(
|
|
20845
20845
|
commentSummary,
|
|
20846
20846
|
commentAnalysisProgress,
|
|
20847
20847
|
signals,
|
|
20848
20848
|
children,
|
|
20849
20849
|
linkedIssues
|
|
20850
20850
|
);
|
|
20851
|
+
const existingHistory = Array.isArray(fm.assessmentHistory) ? fm.assessmentHistory : [];
|
|
20852
|
+
const legacySummary = fm.assessmentSummary;
|
|
20853
|
+
const allEntries = [newEntry, ...existingHistory];
|
|
20854
|
+
if (legacySummary?.generatedAt) {
|
|
20855
|
+
allEntries.push(legacySummary);
|
|
20856
|
+
}
|
|
20857
|
+
const MAX_HISTORY = 100;
|
|
20858
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20859
|
+
const assessmentHistory = allEntries.filter((entry) => {
|
|
20860
|
+
if (!entry.generatedAt) return false;
|
|
20861
|
+
if (seen.has(entry.generatedAt)) return false;
|
|
20862
|
+
seen.add(entry.generatedAt);
|
|
20863
|
+
return true;
|
|
20864
|
+
}).sort((a, b) => (b.generatedAt ?? "").localeCompare(a.generatedAt ?? "")).slice(0, MAX_HISTORY);
|
|
20851
20865
|
try {
|
|
20852
|
-
|
|
20853
|
-
|
|
20854
|
-
lastAssessedAt:
|
|
20855
|
-
}
|
|
20866
|
+
const payload = {
|
|
20867
|
+
assessmentHistory,
|
|
20868
|
+
lastAssessedAt: newEntry.generatedAt
|
|
20869
|
+
};
|
|
20870
|
+
if (fm.assessmentSummary !== void 0) {
|
|
20871
|
+
payload.assessmentSummary = void 0;
|
|
20872
|
+
}
|
|
20873
|
+
store.update(fm.id, payload);
|
|
20856
20874
|
} catch (err) {
|
|
20857
|
-
errors.push(`Failed to persist assessment
|
|
20875
|
+
errors.push(`Failed to persist assessment history: ${err instanceof Error ? err.message : String(err)}`);
|
|
20858
20876
|
}
|
|
20859
20877
|
}
|
|
20860
20878
|
return {
|
|
@@ -22981,8 +22999,30 @@ function inline(text) {
|
|
|
22981
22999
|
s = s.replace(/__([^_]+)__/g, "<strong>$1</strong>");
|
|
22982
23000
|
s = s.replace(/\*([^*]+)\*/g, "<em>$1</em>");
|
|
22983
23001
|
s = s.replace(/_([^_]+)_/g, "<em>$1</em>");
|
|
23002
|
+
s = linkArtifactIds(s);
|
|
22984
23003
|
return s;
|
|
22985
23004
|
}
|
|
23005
|
+
var ID_PREFIX_TO_TYPE = (() => {
|
|
23006
|
+
const entries = [];
|
|
23007
|
+
for (const [type, prefix] of Object.entries(CORE_ID_PREFIXES)) {
|
|
23008
|
+
entries.push([prefix, type]);
|
|
23009
|
+
}
|
|
23010
|
+
for (const reg of COMMON_REGISTRATIONS) {
|
|
23011
|
+
if (!entries.some(([p]) => p === reg.idPrefix)) {
|
|
23012
|
+
entries.push([reg.idPrefix, reg.type]);
|
|
23013
|
+
}
|
|
23014
|
+
}
|
|
23015
|
+
entries.sort((a, b) => b[0].length - a[0].length);
|
|
23016
|
+
return new Map(entries);
|
|
23017
|
+
})();
|
|
23018
|
+
function linkArtifactIds(html) {
|
|
23019
|
+
return html.replace(/\b([A-Z]{1,3})-(\d{3,})\b/g, (match, prefix, num) => {
|
|
23020
|
+
const type = ID_PREFIX_TO_TYPE.get(prefix);
|
|
23021
|
+
if (!type) return match;
|
|
23022
|
+
const id = `${prefix}-${num}`;
|
|
23023
|
+
return `<a href="/docs/${type}/${id}" class="artifact-link">${match}</a>`;
|
|
23024
|
+
});
|
|
23025
|
+
}
|
|
22986
23026
|
function layout(opts, body) {
|
|
22987
23027
|
const switcherHtml = opts.personaSwitcherHtml ?? "";
|
|
22988
23028
|
let navHtml;
|
|
@@ -23694,6 +23734,75 @@ tr:hover td {
|
|
|
23694
23734
|
margin: 0.75rem 0;
|
|
23695
23735
|
}
|
|
23696
23736
|
|
|
23737
|
+
/* Artifact cross-links */
|
|
23738
|
+
a.artifact-link {
|
|
23739
|
+
color: var(--accent);
|
|
23740
|
+
text-decoration: none;
|
|
23741
|
+
font-weight: 500;
|
|
23742
|
+
border-bottom: 1px dotted var(--accent);
|
|
23743
|
+
}
|
|
23744
|
+
a.artifact-link:hover {
|
|
23745
|
+
border-bottom-style: solid;
|
|
23746
|
+
}
|
|
23747
|
+
|
|
23748
|
+
/* Assessment timeline */
|
|
23749
|
+
.assessment-timeline {
|
|
23750
|
+
margin-top: 1.5rem;
|
|
23751
|
+
}
|
|
23752
|
+
.assessment-timeline h3 {
|
|
23753
|
+
font-size: 1rem;
|
|
23754
|
+
font-weight: 600;
|
|
23755
|
+
margin-bottom: 0.75rem;
|
|
23756
|
+
}
|
|
23757
|
+
.assessment-entry {
|
|
23758
|
+
background: var(--bg-card);
|
|
23759
|
+
border: 1px solid var(--border);
|
|
23760
|
+
border-radius: var(--radius);
|
|
23761
|
+
padding: 0.75rem 1rem;
|
|
23762
|
+
margin-bottom: 0.75rem;
|
|
23763
|
+
}
|
|
23764
|
+
.assessment-entry.assessment-latest {
|
|
23765
|
+
border-left: 3px solid var(--accent);
|
|
23766
|
+
}
|
|
23767
|
+
.assessment-header {
|
|
23768
|
+
display: flex;
|
|
23769
|
+
align-items: center;
|
|
23770
|
+
gap: 0.5rem;
|
|
23771
|
+
margin-bottom: 0.5rem;
|
|
23772
|
+
}
|
|
23773
|
+
.assessment-date {
|
|
23774
|
+
font-size: 0.8rem;
|
|
23775
|
+
color: var(--text-dim);
|
|
23776
|
+
font-family: var(--mono);
|
|
23777
|
+
}
|
|
23778
|
+
.assessment-comment {
|
|
23779
|
+
font-size: 0.875rem;
|
|
23780
|
+
line-height: 1.6;
|
|
23781
|
+
margin-bottom: 0.5rem;
|
|
23782
|
+
}
|
|
23783
|
+
.assessment-stat {
|
|
23784
|
+
font-size: 0.8rem;
|
|
23785
|
+
color: var(--text-dim);
|
|
23786
|
+
margin-bottom: 0.25rem;
|
|
23787
|
+
}
|
|
23788
|
+
.assessment-stat strong {
|
|
23789
|
+
color: var(--text);
|
|
23790
|
+
}
|
|
23791
|
+
.assessment-signals {
|
|
23792
|
+
list-style: none;
|
|
23793
|
+
padding: 0;
|
|
23794
|
+
margin: 0.5rem 0 0;
|
|
23795
|
+
}
|
|
23796
|
+
.assessment-signals li {
|
|
23797
|
+
font-size: 0.8rem;
|
|
23798
|
+
padding: 0.15rem 0;
|
|
23799
|
+
}
|
|
23800
|
+
.progress-bar-inline {
|
|
23801
|
+
font-family: var(--mono);
|
|
23802
|
+
font-size: 0.75rem;
|
|
23803
|
+
letter-spacing: -0.5px;
|
|
23804
|
+
}
|
|
23805
|
+
|
|
23697
23806
|
/* Filters */
|
|
23698
23807
|
.filters {
|
|
23699
23808
|
display: flex;
|
|
@@ -24858,23 +24967,33 @@ function documentsPage(data) {
|
|
|
24858
24967
|
function documentDetailPage(doc) {
|
|
24859
24968
|
const fm = doc.frontmatter;
|
|
24860
24969
|
const label = typeLabel(fm.type);
|
|
24861
|
-
const skipKeys = /* @__PURE__ */ new Set(["title", "type"]);
|
|
24970
|
+
const skipKeys = /* @__PURE__ */ new Set(["title", "type", "assessmentHistory", "assessmentSummary"]);
|
|
24862
24971
|
const entries = Object.entries(fm).filter(
|
|
24863
|
-
([key]) => !skipKeys.has(key) &&
|
|
24972
|
+
([key, value]) => !skipKeys.has(key) && value != null && typeof value !== "object"
|
|
24973
|
+
);
|
|
24974
|
+
const arrayEntries = Object.entries(fm).filter(
|
|
24975
|
+
([key, value]) => !skipKeys.has(key) && Array.isArray(value) && value.every((v) => typeof v === "string")
|
|
24864
24976
|
);
|
|
24865
|
-
const
|
|
24977
|
+
const allEntries = [
|
|
24978
|
+
...entries.filter(([, v]) => !Array.isArray(v)),
|
|
24979
|
+
...arrayEntries
|
|
24980
|
+
];
|
|
24981
|
+
const dtDd = allEntries.map(([key, value]) => {
|
|
24866
24982
|
let rendered;
|
|
24867
24983
|
if (key === "status") {
|
|
24868
24984
|
rendered = statusBadge(value);
|
|
24869
24985
|
} else if (key === "tags" && Array.isArray(value)) {
|
|
24870
24986
|
rendered = value.map((t) => `<span class="badge badge-default">${escapeHtml(t)}</span>`).join(" ");
|
|
24871
|
-
} else if (key === "created" || key === "updated") {
|
|
24987
|
+
} else if (key === "created" || key === "updated" || key === "lastAssessedAt" || key === "lastJiraSyncAt") {
|
|
24872
24988
|
rendered = formatDate(value);
|
|
24873
24989
|
} else {
|
|
24874
|
-
rendered = escapeHtml(String(value));
|
|
24990
|
+
rendered = linkArtifactIds(escapeHtml(String(value)));
|
|
24875
24991
|
}
|
|
24876
24992
|
return `<dt>${escapeHtml(key)}</dt><dd>${rendered}</dd>`;
|
|
24877
24993
|
}).join("\n ");
|
|
24994
|
+
const rawHistory = Array.isArray(fm.assessmentHistory) ? fm.assessmentHistory : fm.assessmentSummary && typeof fm.assessmentSummary === "object" ? [fm.assessmentSummary] : [];
|
|
24995
|
+
const assessmentHistory = rawHistory.filter(isValidAssessmentEntry).sort((a, b) => (b.generatedAt ?? "").localeCompare(a.generatedAt ?? ""));
|
|
24996
|
+
const timelineHtml = assessmentHistory.length > 0 ? renderAssessmentTimeline(assessmentHistory) : "";
|
|
24878
24997
|
return `
|
|
24879
24998
|
<div class="breadcrumb">
|
|
24880
24999
|
<a href="/">Overview</a><span class="sep">/</span>
|
|
@@ -24894,8 +25013,73 @@ function documentDetailPage(doc) {
|
|
|
24894
25013
|
</div>
|
|
24895
25014
|
|
|
24896
25015
|
${doc.content.trim() ? `<div class="detail-content">${renderMarkdown(doc.content)}</div>` : ""}
|
|
25016
|
+
|
|
25017
|
+
${timelineHtml}
|
|
24897
25018
|
`;
|
|
24898
25019
|
}
|
|
25020
|
+
function isValidAssessmentEntry(value) {
|
|
25021
|
+
if (typeof value !== "object" || value === null) return false;
|
|
25022
|
+
const obj = value;
|
|
25023
|
+
if (typeof obj.generatedAt !== "string") return false;
|
|
25024
|
+
if (obj.signals !== void 0 && !Array.isArray(obj.signals)) return false;
|
|
25025
|
+
return true;
|
|
25026
|
+
}
|
|
25027
|
+
function normalizeEntry(entry) {
|
|
25028
|
+
return {
|
|
25029
|
+
generatedAt: entry.generatedAt ?? "",
|
|
25030
|
+
commentSummary: typeof entry.commentSummary === "string" ? entry.commentSummary : null,
|
|
25031
|
+
commentAnalysisProgress: typeof entry.commentAnalysisProgress === "number" ? entry.commentAnalysisProgress : null,
|
|
25032
|
+
signals: Array.isArray(entry.signals) ? entry.signals.filter((s) => typeof s === "string") : [],
|
|
25033
|
+
childCount: typeof entry.childCount === "number" ? entry.childCount : 0,
|
|
25034
|
+
childDoneCount: typeof entry.childDoneCount === "number" ? entry.childDoneCount : 0,
|
|
25035
|
+
childRollupProgress: typeof entry.childRollupProgress === "number" ? entry.childRollupProgress : null,
|
|
25036
|
+
linkedIssueCount: typeof entry.linkedIssueCount === "number" ? entry.linkedIssueCount : 0
|
|
25037
|
+
};
|
|
25038
|
+
}
|
|
25039
|
+
function renderAssessmentTimeline(history) {
|
|
25040
|
+
const entries = history.map((raw, i) => {
|
|
25041
|
+
const entry = normalizeEntry(raw);
|
|
25042
|
+
const date5 = entry.generatedAt ? formatDate(entry.generatedAt) : "Unknown date";
|
|
25043
|
+
const time3 = entry.generatedAt?.slice(11, 16) ?? "";
|
|
25044
|
+
const isLatest = i === 0;
|
|
25045
|
+
const parts = [];
|
|
25046
|
+
if (entry.commentSummary) {
|
|
25047
|
+
parts.push(`<div class="assessment-comment">${linkArtifactIds(escapeHtml(entry.commentSummary))}</div>`);
|
|
25048
|
+
}
|
|
25049
|
+
if (entry.commentAnalysisProgress !== null) {
|
|
25050
|
+
parts.push(`<div class="assessment-stat">\u{1F4CA} Comment-derived progress: <strong>${entry.commentAnalysisProgress}%</strong></div>`);
|
|
25051
|
+
}
|
|
25052
|
+
if (entry.childCount > 0) {
|
|
25053
|
+
const bar = progressBarHtml(entry.childRollupProgress ?? 0);
|
|
25054
|
+
parts.push(`<div class="assessment-stat">\u{1F476} Children: ${entry.childDoneCount}/${entry.childCount} done ${bar} ${entry.childRollupProgress ?? 0}%</div>`);
|
|
25055
|
+
}
|
|
25056
|
+
if (entry.linkedIssueCount > 0) {
|
|
25057
|
+
parts.push(`<div class="assessment-stat">\u{1F517} Linked issues: ${entry.linkedIssueCount}</div>`);
|
|
25058
|
+
}
|
|
25059
|
+
if (entry.signals.length > 0) {
|
|
25060
|
+
const signalItems = entry.signals.map((s) => `<li>${linkArtifactIds(escapeHtml(s))}</li>`).join("");
|
|
25061
|
+
parts.push(`<ul class="assessment-signals">${signalItems}</ul>`);
|
|
25062
|
+
}
|
|
25063
|
+
return `
|
|
25064
|
+
<div class="assessment-entry${isLatest ? " assessment-latest" : ""}">
|
|
25065
|
+
<div class="assessment-header">
|
|
25066
|
+
<span class="assessment-date">${escapeHtml(date5)} ${escapeHtml(time3)}</span>
|
|
25067
|
+
${isLatest ? '<span class="badge badge-default">Latest</span>' : ""}
|
|
25068
|
+
</div>
|
|
25069
|
+
${parts.join("\n")}
|
|
25070
|
+
</div>`;
|
|
25071
|
+
});
|
|
25072
|
+
return `
|
|
25073
|
+
<div class="assessment-timeline">
|
|
25074
|
+
<h3>Assessment History</h3>
|
|
25075
|
+
${entries.join("\n")}
|
|
25076
|
+
</div>`;
|
|
25077
|
+
}
|
|
25078
|
+
function progressBarHtml(pct) {
|
|
25079
|
+
const filled = Math.round(Math.max(0, Math.min(100, pct)) / 10);
|
|
25080
|
+
const empty = 10 - filled;
|
|
25081
|
+
return `<span class="progress-bar-inline">${"\u2588".repeat(filled)}${"\u2591".repeat(empty)}</span>`;
|
|
25082
|
+
}
|
|
24899
25083
|
|
|
24900
25084
|
// src/web/persona-views.ts
|
|
24901
25085
|
var VIEWS = /* @__PURE__ */ new Map();
|