claude-autopm 3.22.0 → 3.22.1
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.
|
@@ -132,8 +132,7 @@ function generateEpicFlowDiagram() {
|
|
|
132
132
|
}
|
|
133
133
|
} catch {}
|
|
134
134
|
if (epics.length === 0 && prds.length === 0) {
|
|
135
|
-
|
|
136
|
-
return lines.join('\n');
|
|
135
|
+
return { mermaid: '', hasData: false };
|
|
137
136
|
}
|
|
138
137
|
let nodeId = 0;
|
|
139
138
|
for (const prd of prds) {
|
|
@@ -159,7 +158,7 @@ function generateEpicFlowDiagram() {
|
|
|
159
158
|
lines.push(` ${eid} --> ${tid}["${t.name} ${t.icon}"]`);
|
|
160
159
|
}
|
|
161
160
|
}
|
|
162
|
-
return lines.join('\n');
|
|
161
|
+
return { mermaid: lines.join('\n'), hasData: true };
|
|
163
162
|
}
|
|
164
163
|
|
|
165
164
|
function generatePluginGraph() {
|
|
@@ -263,8 +262,10 @@ function getProjectDiagrams() {
|
|
|
263
262
|
}
|
|
264
263
|
|
|
265
264
|
function getDiagramsData() {
|
|
265
|
+
const epic = generateEpicFlowDiagram();
|
|
266
266
|
return {
|
|
267
|
-
epicFlow:
|
|
267
|
+
epicFlow: epic.mermaid,
|
|
268
|
+
epicFlowHasData: epic.hasData,
|
|
268
269
|
projectDiagrams: getProjectDiagrams(),
|
|
269
270
|
pluginGraph: generatePluginGraph(),
|
|
270
271
|
agentTree: generateAgentTree()
|
|
@@ -364,6 +365,42 @@ function renderHTML() {
|
|
|
364
365
|
.toast.ok { background: #238636; }
|
|
365
366
|
.toast.err { background: #da3633; }
|
|
366
367
|
footer { margin-top: 24px; text-align: center; color: #484f58; font-size: 12px; }
|
|
368
|
+
/* Diagram cards */
|
|
369
|
+
.diagram-card { position: relative; }
|
|
370
|
+
.diagram-card .diagram-toolbar { display: flex; gap: 6px; position: absolute; top: 12px; right: 12px; z-index: 2; }
|
|
371
|
+
.diagram-card .diagram-toolbar button {
|
|
372
|
+
background: #21262d; color: #8b949e; border: 1px solid #30363d;
|
|
373
|
+
padding: 4px 10px; border-radius: 4px; cursor: pointer; font-size: 12px;
|
|
374
|
+
}
|
|
375
|
+
.diagram-card .diagram-toolbar button:hover { background: #30363d; color: #c9d1d9; }
|
|
376
|
+
.diagram-card .mermaid-wrap { overflow: auto; max-height: 400px; cursor: pointer; }
|
|
377
|
+
.diagram-card .mermaid-wrap:hover { outline: 1px solid #30363d; border-radius: 4px; }
|
|
378
|
+
/* Fullscreen modal */
|
|
379
|
+
.diagram-modal {
|
|
380
|
+
display: none; position: fixed; inset: 0; z-index: 1000;
|
|
381
|
+
background: rgba(0,0,0,0.85); justify-content: center; align-items: center;
|
|
382
|
+
}
|
|
383
|
+
.diagram-modal.open { display: flex; }
|
|
384
|
+
.diagram-modal .modal-inner {
|
|
385
|
+
background: #161b22; border: 1px solid #30363d; border-radius: 12px;
|
|
386
|
+
width: 95vw; height: 92vh; display: flex; flex-direction: column; position: relative;
|
|
387
|
+
}
|
|
388
|
+
.diagram-modal .modal-header {
|
|
389
|
+
display: flex; justify-content: space-between; align-items: center;
|
|
390
|
+
padding: 12px 20px; border-bottom: 1px solid #30363d;
|
|
391
|
+
}
|
|
392
|
+
.diagram-modal .modal-header h3 { color: #c9d1d9; font-size: 14px; }
|
|
393
|
+
.diagram-modal .modal-header .modal-actions { display: flex; gap: 8px; }
|
|
394
|
+
.diagram-modal .modal-header button {
|
|
395
|
+
background: #21262d; color: #8b949e; border: 1px solid #30363d;
|
|
396
|
+
padding: 6px 14px; border-radius: 4px; cursor: pointer; font-size: 12px;
|
|
397
|
+
}
|
|
398
|
+
.diagram-modal .modal-header button:hover { background: #30363d; color: #c9d1d9; }
|
|
399
|
+
.diagram-modal .modal-body {
|
|
400
|
+
flex: 1; overflow: auto; padding: 20px; display: flex;
|
|
401
|
+
justify-content: center; align-items: flex-start;
|
|
402
|
+
}
|
|
403
|
+
.diagram-modal .modal-body svg { max-width: 100%; height: auto; }
|
|
367
404
|
</style>
|
|
368
405
|
</head>
|
|
369
406
|
<body>
|
|
@@ -494,15 +531,33 @@ function renderHTML() {
|
|
|
494
531
|
|
|
495
532
|
<!-- Diagrams Tab -->
|
|
496
533
|
<div id="tab-diagrams" class="tab-content">
|
|
497
|
-
<div class="
|
|
498
|
-
<
|
|
499
|
-
|
|
534
|
+
<div id="diagram-epic-card" class="card diagram-card" style="display:none;">
|
|
535
|
+
<h3>Epic Flow <span style="color:#8b949e;font-size:11px;font-weight:normal;margin-left:8px;">PRD → Epic → Tasks workflow</span></h3>
|
|
536
|
+
<div class="diagram-toolbar">
|
|
537
|
+
<button onclick="downloadMermaid('diagram-epic')">↓ .mmd</button>
|
|
538
|
+
<button onclick="openDiagramModal('diagram-epic','Epic Flow')">⤢ Fullscreen</button>
|
|
539
|
+
</div>
|
|
540
|
+
<div class="mermaid-wrap" onclick="openDiagramModal('diagram-epic','Epic Flow')">
|
|
500
541
|
<pre class="mermaid" id="diagram-epic"></pre>
|
|
501
542
|
</div>
|
|
502
543
|
</div>
|
|
503
544
|
<div id="project-diagrams"></div>
|
|
504
545
|
</div>
|
|
505
546
|
|
|
547
|
+
<!-- Diagram fullscreen modal -->
|
|
548
|
+
<div class="diagram-modal" id="diagram-modal" role="dialog" aria-modal="true" aria-labelledby="modal-diagram-title" onclick="if(event.target===this)closeDiagramModal()">
|
|
549
|
+
<div class="modal-inner">
|
|
550
|
+
<div class="modal-header">
|
|
551
|
+
<h3 id="modal-diagram-title"></h3>
|
|
552
|
+
<div class="modal-actions">
|
|
553
|
+
<button onclick="downloadMermaid(currentModalDiagram)">↓ Download .mmd</button>
|
|
554
|
+
<button onclick="closeDiagramModal()">✕ Close</button>
|
|
555
|
+
</div>
|
|
556
|
+
</div>
|
|
557
|
+
<div class="modal-body" id="modal-diagram-body"></div>
|
|
558
|
+
</div>
|
|
559
|
+
</div>
|
|
560
|
+
|
|
506
561
|
<!-- Tests Tab -->
|
|
507
562
|
<div id="tab-tests" class="tab-content">
|
|
508
563
|
<div class="card">
|
|
@@ -542,26 +597,68 @@ function showTab(name, btn) {
|
|
|
542
597
|
}
|
|
543
598
|
|
|
544
599
|
let diagramsRendered = false;
|
|
600
|
+
const diagramSources = {};
|
|
601
|
+
const diagramNames = {};
|
|
602
|
+
let currentModalDiagram = null;
|
|
603
|
+
|
|
545
604
|
function renderMermaid() {
|
|
546
605
|
if (diagramsRendered) return;
|
|
547
606
|
fetch('/api/diagrams', { headers: { 'Authorization': 'Bearer ' + TOKEN } })
|
|
548
607
|
.then(r => r.json())
|
|
549
608
|
.then(data => {
|
|
550
|
-
|
|
609
|
+
// Epic Flow — only show if there are actual epics/PRDs
|
|
610
|
+
const epicCard = document.getElementById('diagram-epic-card');
|
|
611
|
+
const epicEl = document.getElementById('diagram-epic');
|
|
612
|
+
if (data.epicFlowHasData) {
|
|
613
|
+
epicCard.style.display = '';
|
|
614
|
+
epicEl.className = 'mermaid';
|
|
615
|
+
epicEl.textContent = data.epicFlow;
|
|
616
|
+
diagramSources['diagram-epic'] = data.epicFlow;
|
|
617
|
+
diagramNames['diagram-epic'] = 'epic-flow';
|
|
618
|
+
} else {
|
|
619
|
+
epicCard.style.display = 'none';
|
|
620
|
+
epicEl.className = '';
|
|
621
|
+
epicEl.textContent = '';
|
|
622
|
+
}
|
|
551
623
|
document.getElementById('diagram-plugins').textContent = data.pluginGraph;
|
|
552
624
|
document.getElementById('diagram-agents').textContent = data.agentTree;
|
|
625
|
+
diagramSources['diagram-plugins'] = data.pluginGraph;
|
|
626
|
+
diagramSources['diagram-agents'] = data.agentTree;
|
|
627
|
+
diagramNames['diagram-plugins'] = 'plugins';
|
|
628
|
+
diagramNames['diagram-agents'] = 'agents';
|
|
553
629
|
// Render project diagrams dynamically
|
|
554
630
|
const container = document.getElementById('project-diagrams');
|
|
555
631
|
container.innerHTML = '';
|
|
556
632
|
if (data.projectDiagrams && data.projectDiagrams.length > 0) {
|
|
557
|
-
data.projectDiagrams.forEach(d => {
|
|
633
|
+
data.projectDiagrams.forEach((d, i) => {
|
|
634
|
+
const id = 'proj-diagram-' + i;
|
|
635
|
+
diagramSources[id] = d.content;
|
|
636
|
+
diagramNames[id] = d.name;
|
|
558
637
|
const card = document.createElement('div');
|
|
559
|
-
card.className = 'card';
|
|
560
|
-
|
|
638
|
+
card.className = 'card diagram-card';
|
|
639
|
+
const h3 = document.createElement('h3');
|
|
640
|
+
h3.textContent = d.name;
|
|
641
|
+
card.appendChild(h3);
|
|
642
|
+
const toolbar = document.createElement('div');
|
|
643
|
+
toolbar.className = 'diagram-toolbar';
|
|
644
|
+
const dlBtn = document.createElement('button');
|
|
645
|
+
dlBtn.textContent = '↓ .mmd';
|
|
646
|
+
dlBtn.onclick = function(e) { e.stopPropagation(); downloadMermaid(id); };
|
|
647
|
+
const fsBtn = document.createElement('button');
|
|
648
|
+
fsBtn.textContent = '⤢ Fullscreen';
|
|
649
|
+
fsBtn.onclick = function(e) { e.stopPropagation(); openDiagramModal(id, d.name); };
|
|
650
|
+
toolbar.appendChild(dlBtn);
|
|
651
|
+
toolbar.appendChild(fsBtn);
|
|
652
|
+
card.appendChild(toolbar);
|
|
653
|
+
const wrap = document.createElement('div');
|
|
654
|
+
wrap.className = 'mermaid-wrap';
|
|
655
|
+
wrap.onclick = function() { openDiagramModal(id, d.name); };
|
|
561
656
|
const pre = document.createElement('pre');
|
|
562
657
|
pre.className = 'mermaid';
|
|
658
|
+
pre.id = id;
|
|
563
659
|
pre.textContent = d.content;
|
|
564
|
-
|
|
660
|
+
wrap.appendChild(pre);
|
|
661
|
+
card.appendChild(wrap);
|
|
565
662
|
container.appendChild(card);
|
|
566
663
|
});
|
|
567
664
|
} else {
|
|
@@ -586,6 +683,59 @@ function renderMermaid() {
|
|
|
586
683
|
});
|
|
587
684
|
}
|
|
588
685
|
|
|
686
|
+
function openDiagramModal(diagramId, title) {
|
|
687
|
+
currentModalDiagram = diagramId;
|
|
688
|
+
document.getElementById('modal-diagram-title').textContent = title || diagramId;
|
|
689
|
+
const body = document.getElementById('modal-diagram-body');
|
|
690
|
+
body.textContent = '';
|
|
691
|
+
const source = diagramSources[diagramId];
|
|
692
|
+
if (source) {
|
|
693
|
+
const pre = document.createElement('pre');
|
|
694
|
+
pre.className = 'mermaid';
|
|
695
|
+
pre.textContent = source;
|
|
696
|
+
body.appendChild(pre);
|
|
697
|
+
if (typeof mermaid !== 'undefined' && mermaid.run) {
|
|
698
|
+
mermaid.run({ nodes: body.querySelectorAll('.mermaid') });
|
|
699
|
+
}
|
|
700
|
+
} else {
|
|
701
|
+
body.textContent = 'Diagram not available.';
|
|
702
|
+
}
|
|
703
|
+
const modal = document.getElementById('diagram-modal');
|
|
704
|
+
modal.classList.add('open');
|
|
705
|
+
modalPrevFocus = document.activeElement;
|
|
706
|
+
const closeBtn = modal.querySelector('.modal-actions button:last-child');
|
|
707
|
+
if (closeBtn) closeBtn.focus();
|
|
708
|
+
document.addEventListener('keydown', modalEscHandler);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
let modalPrevFocus = null;
|
|
712
|
+
function closeDiagramModal() {
|
|
713
|
+
document.getElementById('diagram-modal').classList.remove('open');
|
|
714
|
+
document.removeEventListener('keydown', modalEscHandler);
|
|
715
|
+
currentModalDiagram = null;
|
|
716
|
+
if (modalPrevFocus) { modalPrevFocus.focus(); modalPrevFocus = null; }
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
function modalEscHandler(e) { if (e.key === 'Escape') closeDiagramModal(); }
|
|
720
|
+
|
|
721
|
+
function downloadMermaid(diagramId) {
|
|
722
|
+
const src = diagramSources[diagramId];
|
|
723
|
+
if (!src) return;
|
|
724
|
+
const label = diagramNames[diagramId] || diagramId.replace('proj-diagram-', 'diagram-').replace('diagram-', '');
|
|
725
|
+
const safeName = label.replace(/[^a-zA-Z0-9_-]/g, '_') + '.mmd';
|
|
726
|
+
const blob = new Blob([src], { type: 'text/plain' });
|
|
727
|
+
const a = document.createElement('a');
|
|
728
|
+
const url = URL.createObjectURL(blob);
|
|
729
|
+
a.href = url;
|
|
730
|
+
a.download = safeName;
|
|
731
|
+
a.style.display = 'none';
|
|
732
|
+
document.body.appendChild(a);
|
|
733
|
+
try { a.click(); } finally {
|
|
734
|
+
document.body.removeChild(a);
|
|
735
|
+
setTimeout(function() { URL.revokeObjectURL(url); }, 100);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
589
739
|
function renderTestPlan(md) {
|
|
590
740
|
if (!md) { document.getElementById('test-plan-content').textContent = 'No test plan found. Run /pm:test-plan to generate.'; return; }
|
|
591
741
|
const lines = md.split('\\n');
|
|
@@ -963,7 +1113,22 @@ function addEnvSuggestion(key, val, hint) {
|
|
|
963
1113
|
addEnvRow(key, val);
|
|
964
1114
|
}
|
|
965
1115
|
|
|
1116
|
+
// Pause auto-refresh while user is editing MCP or env forms
|
|
1117
|
+
let editingLock = false;
|
|
1118
|
+
document.addEventListener('focusin', function(e) {
|
|
1119
|
+
if (e.target.closest('#mcp-list, #env-list, .mcp-entry, .env-row')) editingLock = true;
|
|
1120
|
+
});
|
|
1121
|
+
document.addEventListener('focusout', function(e) {
|
|
1122
|
+
if (e.target.closest('#mcp-list, #env-list, .mcp-entry, .env-row')) {
|
|
1123
|
+
setTimeout(function() {
|
|
1124
|
+
const active = document.activeElement;
|
|
1125
|
+
if (!active || !active.closest('#mcp-list, #env-list, .mcp-entry, .env-row')) editingLock = false;
|
|
1126
|
+
}, 200);
|
|
1127
|
+
}
|
|
1128
|
+
});
|
|
1129
|
+
|
|
966
1130
|
async function refresh() {
|
|
1131
|
+
if (editingLock) return;
|
|
967
1132
|
try {
|
|
968
1133
|
const data = await api('GET', '/api/status');
|
|
969
1134
|
loadStatus(data);
|
package/package.json
CHANGED