mrvn-cli 0.5.10 → 0.5.11
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 +79 -6
- package/dist/index.js.map +1 -1
- package/dist/marvin-serve.js +78 -5
- package/dist/marvin-serve.js.map +1 -1
- package/dist/marvin.js +79 -6
- package/dist/marvin.js.map +1 -1
- package/package.json +1 -1
package/dist/marvin-serve.js
CHANGED
|
@@ -15709,7 +15709,9 @@ function collectSprintSummaryData(store, sprintId) {
|
|
|
15709
15709
|
progress: getEffectiveProgress(doc.frontmatter),
|
|
15710
15710
|
owner: doc.frontmatter.owner,
|
|
15711
15711
|
workFocus: focusTag ? focusTag.slice(6) : void 0,
|
|
15712
|
-
aboutArtifact: about
|
|
15712
|
+
aboutArtifact: about,
|
|
15713
|
+
jiraKey: doc.frontmatter.jiraKey,
|
|
15714
|
+
jiraUrl: doc.frontmatter.jiraUrl
|
|
15713
15715
|
};
|
|
15714
15716
|
allItemsById.set(item.id, item);
|
|
15715
15717
|
if (about && sprintItemIds.has(about)) {
|
|
@@ -19833,6 +19835,58 @@ function createJiraTools(store, projectConfig) {
|
|
|
19833
19835
|
},
|
|
19834
19836
|
{ annotations: { readOnlyHint: true } }
|
|
19835
19837
|
),
|
|
19838
|
+
// --- Jira search (read-only) ---
|
|
19839
|
+
tool20(
|
|
19840
|
+
"search_jira",
|
|
19841
|
+
"Search Jira issues via JQL query. Read-only \u2014 returns results without creating any local documents. Use this to preview before importing or to find issues for linking.",
|
|
19842
|
+
{
|
|
19843
|
+
jql: external_exports.string().describe(`JQL query (e.g. 'project = PROJ AND status = "In Progress"')`),
|
|
19844
|
+
maxResults: external_exports.number().optional().describe("Max issues to return (default 20)")
|
|
19845
|
+
},
|
|
19846
|
+
async (args) => {
|
|
19847
|
+
const jira = createJiraClient(jiraUserConfig);
|
|
19848
|
+
if (!jira) return jiraNotConfiguredError();
|
|
19849
|
+
const result = await jira.client.searchIssuesV3(
|
|
19850
|
+
args.jql,
|
|
19851
|
+
["summary", "status", "issuetype", "priority", "assignee", "labels"],
|
|
19852
|
+
args.maxResults ?? 20
|
|
19853
|
+
);
|
|
19854
|
+
const allDocs = store.registeredTypes.flatMap((t) => store.list({ type: t }));
|
|
19855
|
+
const jiraKeyToArtifact = /* @__PURE__ */ new Map();
|
|
19856
|
+
for (const doc of allDocs) {
|
|
19857
|
+
const jk = doc.frontmatter.jiraKey;
|
|
19858
|
+
if (jk) jiraKeyToArtifact.set(jk, doc.frontmatter.id);
|
|
19859
|
+
}
|
|
19860
|
+
const issues = result.issues.map((issue2) => {
|
|
19861
|
+
const marvinId = jiraKeyToArtifact.get(issue2.key);
|
|
19862
|
+
return {
|
|
19863
|
+
key: issue2.key,
|
|
19864
|
+
summary: issue2.fields.summary,
|
|
19865
|
+
status: issue2.fields.status.name,
|
|
19866
|
+
issueType: issue2.fields.issuetype.name,
|
|
19867
|
+
priority: issue2.fields.priority?.name ?? "None",
|
|
19868
|
+
assignee: issue2.fields.assignee?.displayName ?? "unassigned",
|
|
19869
|
+
labels: issue2.fields.labels ?? [],
|
|
19870
|
+
marvinArtifact: marvinId ?? null
|
|
19871
|
+
};
|
|
19872
|
+
});
|
|
19873
|
+
const parts = [
|
|
19874
|
+
`Found ${result.total ?? issues.length} issues (showing ${issues.length}).`,
|
|
19875
|
+
""
|
|
19876
|
+
];
|
|
19877
|
+
for (const issue2 of issues) {
|
|
19878
|
+
const linked = issue2.marvinArtifact ? ` \u2192 ${issue2.marvinArtifact}` : " (not linked)";
|
|
19879
|
+
parts.push(`${issue2.key} \u2014 ${issue2.summary} [${issue2.status}]${linked}`);
|
|
19880
|
+
parts.push(` Type: ${issue2.issueType} | Priority: ${issue2.priority} | Assignee: ${issue2.assignee}`);
|
|
19881
|
+
}
|
|
19882
|
+
parts.push("");
|
|
19883
|
+
parts.push("This is read-only. Use link_to_jira to link issues to Marvin artifacts, or pull_jira_issue to import as JI-xxx documents.");
|
|
19884
|
+
return {
|
|
19885
|
+
content: [{ type: "text", text: parts.join("\n") }]
|
|
19886
|
+
};
|
|
19887
|
+
},
|
|
19888
|
+
{ annotations: { readOnlyHint: true } }
|
|
19889
|
+
),
|
|
19836
19890
|
// --- Jira → Local tools ---
|
|
19837
19891
|
tool20(
|
|
19838
19892
|
"pull_jira_issue",
|
|
@@ -20437,6 +20491,7 @@ var COMMON_TOOLS = `**Available tools:**
|
|
|
20437
20491
|
- \`fetch_jira_status\` \u2014 **read-only**: fetch current Jira status, subtask progress, and linked issues for Jira-linked actions/tasks. Returns proposed changes without applying them.
|
|
20438
20492
|
- \`fetch_jira_daily\` \u2014 **read-only**: fetch a daily/range summary of all Jira changes \u2014 status transitions, comments, linked Confluence pages, and cross-references with Marvin artifacts. Returns proposed actions (status updates, unlinked issues, question candidates, Confluence pages to review).
|
|
20439
20493
|
- \`fetch_jira_statuses\` \u2014 **read-only**: discover all Jira statuses in a project and show their Marvin mappings (mapped vs unmapped).
|
|
20494
|
+
- \`search_jira\` \u2014 **read-only**: search Jira via JQL and return results with Marvin cross-references. No documents created \u2014 use to preview before importing or find issues for linking.
|
|
20440
20495
|
- \`pull_jira_issue\` / \`pull_jira_issues_jql\` \u2014 import Jira issues as local JI-xxx documents (for Jira-originated items with no existing Marvin artifact).
|
|
20441
20496
|
- \`list_jira_issues\` / \`get_jira_issue\` \u2014 browse locally imported JI-xxx documents.
|
|
20442
20497
|
- \`sync_jira_issue\` \u2014 bidirectional sync of a local JI-xxx with Jira.
|
|
@@ -21133,6 +21188,12 @@ function formatDate(iso) {
|
|
|
21133
21188
|
function typeLabel(type) {
|
|
21134
21189
|
return type.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
21135
21190
|
}
|
|
21191
|
+
function jiraIcon(jiraKey, jiraUrl) {
|
|
21192
|
+
if (!jiraKey) return "";
|
|
21193
|
+
const href = jiraUrl ?? "#";
|
|
21194
|
+
const title = escapeHtml(jiraKey);
|
|
21195
|
+
return `<a href="${escapeHtml(href)}" target="_blank" rel="noopener" title="Jira: ${title}" class="jira-link"><svg class="jira-icon" viewBox="0 0 24 24" width="14" height="14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12.005 2L6.5 7.505l5.505 5.505L17.51 7.505 12.005 2z" fill="#2684FF"/><path d="M6.5 7.505L1 13.01l5.505 5.505L12.01 13.01 6.5 7.505z" fill="url(#jira-g1)"/><path d="M17.51 7.505L12.005 13.01l5.505 5.505L23.015 13.01 17.51 7.505z" fill="url(#jira-g2)"/><path d="M12.005 13.01L6.5 18.515l5.505 5.505 5.505-5.505-5.505-5.505z" fill="#2684FF"/><defs><linearGradient id="jira-g1" x1="9.25" y1="7.51" x2="3.85" y2="12.91" gradientUnits="userSpaceOnUse"><stop stop-color="#0052CC"/><stop offset="1" stop-color="#2684FF"/></linearGradient><linearGradient id="jira-g2" x1="14.76" y1="7.51" x2="20.16" y2="12.91" gradientUnits="userSpaceOnUse"><stop stop-color="#0052CC"/><stop offset="1" stop-color="#2684FF"/></linearGradient></defs></svg></a>`;
|
|
21196
|
+
}
|
|
21136
21197
|
function renderMarkdown(md) {
|
|
21137
21198
|
const lines = md.split("\n");
|
|
21138
21199
|
const out = [];
|
|
@@ -22998,6 +23059,18 @@ tr:hover td {
|
|
|
22998
23059
|
.owner-badge-dm { background: rgba(52, 211, 153, 0.18); color: #34d399; }
|
|
22999
23060
|
.owner-badge-other { background: rgba(139, 143, 164, 0.12); color: var(--text-dim); }
|
|
23000
23061
|
|
|
23062
|
+
/* Jira link icon */
|
|
23063
|
+
.jira-link {
|
|
23064
|
+
display: inline-flex;
|
|
23065
|
+
align-items: center;
|
|
23066
|
+
vertical-align: middle;
|
|
23067
|
+
margin-left: 0.35rem;
|
|
23068
|
+
opacity: 0.7;
|
|
23069
|
+
transition: opacity 0.15s;
|
|
23070
|
+
}
|
|
23071
|
+
.jira-link:hover { opacity: 1; }
|
|
23072
|
+
.jira-icon { vertical-align: middle; }
|
|
23073
|
+
|
|
23001
23074
|
/* Group header rows (PO dashboard decisions/deps) */
|
|
23002
23075
|
.group-header-row td {
|
|
23003
23076
|
background: var(--bg-hover);
|
|
@@ -23022,7 +23095,7 @@ function documentsPage(data) {
|
|
|
23022
23095
|
(doc) => `
|
|
23023
23096
|
<tr>
|
|
23024
23097
|
<td><a href="/docs/${data.type}/${doc.frontmatter.id}">${escapeHtml(doc.frontmatter.id)}</a></td>
|
|
23025
|
-
<td><a href="/docs/${data.type}/${doc.frontmatter.id}">${escapeHtml(doc.frontmatter.title)}</a
|
|
23098
|
+
<td><a href="/docs/${data.type}/${doc.frontmatter.id}">${escapeHtml(doc.frontmatter.title)}</a>${jiraIcon(doc.frontmatter.jiraKey, doc.frontmatter.jiraUrl)}</td>
|
|
23026
23099
|
<td>${statusBadge(doc.frontmatter.status)}</td>
|
|
23027
23100
|
<td>${escapeHtml(doc.frontmatter.owner ?? "\u2014")}</td>
|
|
23028
23101
|
<td>${doc.frontmatter.priority ? `<span class="priority-${doc.frontmatter.priority.toLowerCase()}">${escapeHtml(doc.frontmatter.priority)}</span>` : "\u2014"}</td>
|
|
@@ -23111,7 +23184,7 @@ function documentDetailPage(doc) {
|
|
|
23111
23184
|
</div>
|
|
23112
23185
|
|
|
23113
23186
|
<div class="page-header">
|
|
23114
|
-
<h2>${escapeHtml(fm.title)}</h2>
|
|
23187
|
+
<h2>${escapeHtml(fm.title)}${jiraIcon(fm.jiraKey, fm.jiraUrl)}</h2>
|
|
23115
23188
|
<div class="subtitle">${escapeHtml(fm.id)} · ${escapeHtml(label)}</div>
|
|
23116
23189
|
</div>
|
|
23117
23190
|
|
|
@@ -24542,7 +24615,7 @@ function renderItemRows(items, borderColor, showOwner, depth = 0) {
|
|
|
24542
24615
|
const row = `
|
|
24543
24616
|
<tr class="${classes.join(" ")}" style="--focus-color: ${borderColor}">
|
|
24544
24617
|
<td${indent}><a href="/docs/${escapeHtml(w.type)}/${escapeHtml(w.id)}">${escapeHtml(w.id)}</a></td>
|
|
24545
|
-
<td>${escapeHtml(w.title)}</td>
|
|
24618
|
+
<td>${escapeHtml(w.title)}${jiraIcon(w.jiraKey, w.jiraUrl)}</td>
|
|
24546
24619
|
${ownerCell}
|
|
24547
24620
|
<td>${statusBadge(w.status)}</td>
|
|
24548
24621
|
<td>${progressCell}</td>
|
|
@@ -26167,7 +26240,7 @@ function boardPage(data, basePath = "/board") {
|
|
|
26167
26240
|
<div class="board-card">
|
|
26168
26241
|
<a href="/docs/${doc.frontmatter.type}/${doc.frontmatter.id}">
|
|
26169
26242
|
<div class="bc-id">${escapeHtml(doc.frontmatter.id)}</div>
|
|
26170
|
-
<div class="bc-title">${escapeHtml(doc.frontmatter.title)}</div>
|
|
26243
|
+
<div class="bc-title">${escapeHtml(doc.frontmatter.title)}${jiraIcon(doc.frontmatter.jiraKey, doc.frontmatter.jiraUrl)}</div>
|
|
26171
26244
|
${doc.frontmatter.owner ? `<div class="bc-owner">${escapeHtml(doc.frontmatter.owner)}</div>` : ""}
|
|
26172
26245
|
</a>
|
|
26173
26246
|
</div>`
|