agent-tasks 1.9.10 → 1.9.12
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/README.md +11 -13
- package/agent-desk-plugin.json +1 -1
- package/dist/domain/rules.js +13 -16
- package/dist/domain/rules.js.map +1 -1
- package/dist/transport/mcp-handlers.d.ts +0 -6
- package/dist/transport/mcp-handlers.d.ts.map +1 -1
- package/dist/transport/mcp-handlers.js +68 -107
- package/dist/transport/mcp-handlers.js.map +1 -1
- package/dist/transport/mcp.d.ts.map +1 -1
- package/dist/transport/mcp.js +47 -155
- package/dist/transport/mcp.js.map +1 -1
- package/dist/transport/rest.d.ts.map +1 -1
- package/dist/transport/rest.js +15 -0
- package/dist/transport/rest.js.map +1 -1
- package/dist/ui/panel.js +174 -8
- package/dist/ui/styles.css +182 -0
- package/package.json +1 -1
package/dist/ui/panel.js
CHANGED
|
@@ -189,14 +189,19 @@ function renderPanelContent(task) {
|
|
|
189
189
|
<span class="panel-task-id">#${task.id}</span>
|
|
190
190
|
<span class="panel-stage-badge ${stageClass}">${esc(task.stage)}</span>
|
|
191
191
|
</div>
|
|
192
|
-
<
|
|
193
|
-
<
|
|
194
|
-
|
|
192
|
+
<div class="panel-header-right">
|
|
193
|
+
<button class="panel-delete-btn" data-action="delete-task" data-task-id="${task.id}" aria-label="Delete task" title="Delete task">
|
|
194
|
+
<span class="material-symbols-outlined">delete</span>
|
|
195
|
+
</button>
|
|
196
|
+
<button class="panel-close-btn" data-action="close-panel" aria-label="Close panel">
|
|
197
|
+
<span class="material-symbols-outlined">close</span>
|
|
198
|
+
</button>
|
|
199
|
+
</div>`;
|
|
195
200
|
|
|
196
201
|
const deps = state.dependencies.filter((d) => d.task_id === task.id);
|
|
197
202
|
const blocking = state.dependencies.filter((d) => d.depends_on === task.id);
|
|
198
203
|
|
|
199
|
-
let html = `<div class="panel-title">${esc(task.title)}</div>`;
|
|
204
|
+
let html = `<div class="panel-title" data-action="edit-panel-title" data-task-id="${task.id}" title="Click to edit">${esc(task.title)}</div>`;
|
|
200
205
|
|
|
201
206
|
html += '<div class="panel-section">';
|
|
202
207
|
html +=
|
|
@@ -235,13 +240,17 @@ function renderPanelContent(task) {
|
|
|
235
240
|
|
|
236
241
|
html += '</div></div>';
|
|
237
242
|
|
|
243
|
+
html += '<div class="panel-section">';
|
|
244
|
+
html +=
|
|
245
|
+
'<div class="panel-section-title"><span class="material-symbols-outlined">notes</span> Description' +
|
|
246
|
+
`<button class="panel-edit-btn" data-action="edit-description" data-task-id="${task.id}" title="Edit description">` +
|
|
247
|
+
'<span class="material-symbols-outlined">edit</span></button></div>';
|
|
238
248
|
if (task.description) {
|
|
239
|
-
html += '<div class="panel-section">';
|
|
240
|
-
html +=
|
|
241
|
-
'<div class="panel-section-title"><span class="material-symbols-outlined">notes</span> Description</div>';
|
|
242
249
|
html += `<div class="panel-description">${renderMarkdown(task.description)}</div>`;
|
|
243
|
-
|
|
250
|
+
} else {
|
|
251
|
+
html += '<div class="panel-description panel-description-empty">No description</div>';
|
|
244
252
|
}
|
|
253
|
+
html += '</div>';
|
|
245
254
|
|
|
246
255
|
if (task.result) {
|
|
247
256
|
html += '<div class="panel-section">';
|
|
@@ -516,6 +525,145 @@ function initPanelResize() {
|
|
|
516
525
|
|
|
517
526
|
// ---- Panel event delegation ----
|
|
518
527
|
|
|
528
|
+
function startPanelTitleEdit(titleEl) {
|
|
529
|
+
var taskId = parseInt(titleEl.dataset.taskId, 10);
|
|
530
|
+
var task = TaskBoard.state.tasks.find(function (t) {
|
|
531
|
+
return t.id === taskId;
|
|
532
|
+
});
|
|
533
|
+
if (!task) return;
|
|
534
|
+
|
|
535
|
+
titleEl.setAttribute('contenteditable', 'true');
|
|
536
|
+
titleEl.focus();
|
|
537
|
+
|
|
538
|
+
var range = document.createRange();
|
|
539
|
+
range.selectNodeContents(titleEl);
|
|
540
|
+
var sel = window.getSelection();
|
|
541
|
+
sel.removeAllRanges();
|
|
542
|
+
sel.addRange(range);
|
|
543
|
+
|
|
544
|
+
var finish = function () {
|
|
545
|
+
titleEl.removeAttribute('contenteditable');
|
|
546
|
+
var newTitle = titleEl.textContent.trim();
|
|
547
|
+
if (newTitle && newTitle !== task.title) {
|
|
548
|
+
TaskBoard.updateTask(taskId, { title: newTitle });
|
|
549
|
+
} else {
|
|
550
|
+
titleEl.textContent = task.title;
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
titleEl.addEventListener('blur', finish, { once: true });
|
|
555
|
+
titleEl.addEventListener(
|
|
556
|
+
'keydown',
|
|
557
|
+
function (ev) {
|
|
558
|
+
if (ev.key === 'Enter') {
|
|
559
|
+
ev.preventDefault();
|
|
560
|
+
ev.stopPropagation();
|
|
561
|
+
titleEl.blur();
|
|
562
|
+
} else if (ev.key === 'Escape') {
|
|
563
|
+
ev.preventDefault();
|
|
564
|
+
ev.stopPropagation();
|
|
565
|
+
titleEl.textContent = task.title;
|
|
566
|
+
titleEl.removeAttribute('contenteditable');
|
|
567
|
+
}
|
|
568
|
+
},
|
|
569
|
+
{ once: true },
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
function startDescriptionEdit(taskId) {
|
|
574
|
+
var esc = TaskBoard.esc;
|
|
575
|
+
var task = TaskBoard.state.tasks.find(function (t) {
|
|
576
|
+
return t.id === taskId;
|
|
577
|
+
});
|
|
578
|
+
if (!task) return;
|
|
579
|
+
|
|
580
|
+
var descEl = TaskBoard._root.querySelector('.panel-description');
|
|
581
|
+
if (!descEl) return;
|
|
582
|
+
|
|
583
|
+
var editor = document.createElement('div');
|
|
584
|
+
editor.className = 'panel-description-editor';
|
|
585
|
+
editor.innerHTML =
|
|
586
|
+
'<textarea class="panel-desc-textarea" rows="6">' +
|
|
587
|
+
esc(task.description || '') +
|
|
588
|
+
'</textarea>' +
|
|
589
|
+
'<div class="panel-desc-actions">' +
|
|
590
|
+
'<button class="panel-desc-save" data-task-id="' +
|
|
591
|
+
taskId +
|
|
592
|
+
'">Save</button>' +
|
|
593
|
+
'<button class="panel-desc-cancel">Cancel</button>' +
|
|
594
|
+
'</div>';
|
|
595
|
+
|
|
596
|
+
descEl.replaceWith(editor);
|
|
597
|
+
editor.querySelector('.panel-desc-textarea').focus();
|
|
598
|
+
|
|
599
|
+
editor.querySelector('.panel-desc-save').addEventListener('click', function () {
|
|
600
|
+
var newDesc = editor.querySelector('.panel-desc-textarea').value.trim();
|
|
601
|
+
TaskBoard.updateTask(taskId, { description: newDesc || null });
|
|
602
|
+
setTimeout(function () {
|
|
603
|
+
openPanel(taskId);
|
|
604
|
+
}, 300);
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
editor.querySelector('.panel-desc-cancel').addEventListener('click', function () {
|
|
608
|
+
openPanel(taskId);
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
function deleteTask(taskId) {
|
|
613
|
+
var task = TaskBoard.state.tasks.find(function (t) {
|
|
614
|
+
return t.id === taskId;
|
|
615
|
+
});
|
|
616
|
+
if (!task) return;
|
|
617
|
+
|
|
618
|
+
var overlay = document.createElement('div');
|
|
619
|
+
overlay.className = 'confirm-overlay';
|
|
620
|
+
overlay.innerHTML =
|
|
621
|
+
'<div class="confirm-dialog">' +
|
|
622
|
+
'<div class="confirm-title">Delete task #' +
|
|
623
|
+
taskId +
|
|
624
|
+
'?</div>' +
|
|
625
|
+
'<div class="confirm-body">' +
|
|
626
|
+
TaskBoard.esc(task.title) +
|
|
627
|
+
'</div>' +
|
|
628
|
+
'<div class="confirm-actions">' +
|
|
629
|
+
'<button class="confirm-cancel">Cancel</button>' +
|
|
630
|
+
'<button class="confirm-delete">Delete</button>' +
|
|
631
|
+
'</div></div>';
|
|
632
|
+
|
|
633
|
+
var root =
|
|
634
|
+
TaskBoard._root === document
|
|
635
|
+
? document.body
|
|
636
|
+
: TaskBoard._root.querySelector('[class*="wrapper"]') || TaskBoard._root;
|
|
637
|
+
root.appendChild(overlay);
|
|
638
|
+
|
|
639
|
+
overlay.querySelector('.confirm-cancel').addEventListener('click', function () {
|
|
640
|
+
overlay.remove();
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
overlay.querySelector('.confirm-delete').addEventListener('click', function () {
|
|
644
|
+
overlay.remove();
|
|
645
|
+
TaskBoard._fetch('/api/tasks/' + taskId, { method: 'DELETE' })
|
|
646
|
+
.then(function (r) {
|
|
647
|
+
return r.json();
|
|
648
|
+
})
|
|
649
|
+
.then(function (result) {
|
|
650
|
+
if (result.error) {
|
|
651
|
+
TaskBoard.showToast('Delete failed', result.error, 'error');
|
|
652
|
+
} else {
|
|
653
|
+
TaskBoard.showToast('Deleted', 'Task #' + taskId + ' deleted', 'success');
|
|
654
|
+
closePanel();
|
|
655
|
+
}
|
|
656
|
+
})
|
|
657
|
+
.catch(function () {
|
|
658
|
+
TaskBoard.showToast('Delete failed', 'Network error', 'error');
|
|
659
|
+
});
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
overlay.addEventListener('click', function (ev) {
|
|
663
|
+
if (ev.target === overlay) overlay.remove();
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
|
|
519
667
|
function initPanelEvents() {
|
|
520
668
|
TaskBoard._root.getElementById('side-panel').addEventListener('click', (e) => {
|
|
521
669
|
const closeBtn = e.target.closest('[data-action="close-panel"]');
|
|
@@ -524,6 +672,24 @@ function initPanelEvents() {
|
|
|
524
672
|
return;
|
|
525
673
|
}
|
|
526
674
|
|
|
675
|
+
const editTitle = e.target.closest('[data-action="edit-panel-title"]');
|
|
676
|
+
if (editTitle && !editTitle.hasAttribute('contenteditable')) {
|
|
677
|
+
startPanelTitleEdit(editTitle);
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
const editDesc = e.target.closest('[data-action="edit-description"]');
|
|
682
|
+
if (editDesc) {
|
|
683
|
+
startDescriptionEdit(parseInt(editDesc.dataset.taskId, 10));
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
const delBtn = e.target.closest('[data-action="delete-task"]');
|
|
688
|
+
if (delBtn) {
|
|
689
|
+
deleteTask(parseInt(delBtn.dataset.taskId, 10));
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
|
|
527
693
|
const subtask = e.target.closest('[data-subtask-id]');
|
|
528
694
|
if (subtask) {
|
|
529
695
|
openPanel(parseInt(subtask.dataset.subtaskId, 10));
|
package/dist/ui/styles.css
CHANGED
|
@@ -1661,14 +1661,196 @@ header {
|
|
|
1661
1661
|
line-height: 1.35;
|
|
1662
1662
|
margin-bottom: 16px;
|
|
1663
1663
|
word-break: break-word;
|
|
1664
|
+
user-select: text;
|
|
1664
1665
|
}
|
|
1665
1666
|
|
|
1667
|
+
.panel-title[data-action='edit-panel-title'] {
|
|
1668
|
+
cursor: text;
|
|
1669
|
+
border-radius: var(--radius-sm);
|
|
1670
|
+
padding: 2px 4px;
|
|
1671
|
+
margin: -2px -4px 16px;
|
|
1672
|
+
transition: background var(--transition-fast);
|
|
1673
|
+
}
|
|
1674
|
+
.panel-title[data-action='edit-panel-title']:hover {
|
|
1675
|
+
background: var(--bg-hover);
|
|
1676
|
+
}
|
|
1666
1677
|
.panel-title[contenteditable='true'] {
|
|
1667
1678
|
outline: none;
|
|
1679
|
+
background: var(--bg-surface);
|
|
1668
1680
|
border-bottom: 2px solid var(--accent);
|
|
1669
1681
|
cursor: text;
|
|
1670
1682
|
}
|
|
1671
1683
|
|
|
1684
|
+
.panel-header-right {
|
|
1685
|
+
display: flex;
|
|
1686
|
+
align-items: center;
|
|
1687
|
+
gap: 4px;
|
|
1688
|
+
flex-shrink: 0;
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
.panel-delete-btn {
|
|
1692
|
+
background: none;
|
|
1693
|
+
border: none;
|
|
1694
|
+
cursor: pointer;
|
|
1695
|
+
color: var(--text-dim);
|
|
1696
|
+
padding: 4px;
|
|
1697
|
+
border-radius: var(--radius-sm);
|
|
1698
|
+
display: flex;
|
|
1699
|
+
align-items: center;
|
|
1700
|
+
justify-content: center;
|
|
1701
|
+
transition: all var(--transition-fast);
|
|
1702
|
+
}
|
|
1703
|
+
.panel-delete-btn:hover {
|
|
1704
|
+
color: var(--red);
|
|
1705
|
+
background: var(--red-dim);
|
|
1706
|
+
}
|
|
1707
|
+
.panel-delete-btn .material-symbols-outlined {
|
|
1708
|
+
font-size: 18px;
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
.panel-edit-btn {
|
|
1712
|
+
background: none;
|
|
1713
|
+
border: none;
|
|
1714
|
+
color: var(--text-dim);
|
|
1715
|
+
cursor: pointer;
|
|
1716
|
+
padding: 2px;
|
|
1717
|
+
border-radius: 4px;
|
|
1718
|
+
margin-left: auto;
|
|
1719
|
+
opacity: 0;
|
|
1720
|
+
transition:
|
|
1721
|
+
opacity var(--transition-fast),
|
|
1722
|
+
color var(--transition-fast);
|
|
1723
|
+
display: flex;
|
|
1724
|
+
align-items: center;
|
|
1725
|
+
}
|
|
1726
|
+
.panel-section-title:hover .panel-edit-btn {
|
|
1727
|
+
opacity: 1;
|
|
1728
|
+
}
|
|
1729
|
+
.panel-edit-btn:hover {
|
|
1730
|
+
color: var(--accent);
|
|
1731
|
+
background: var(--bg-hover);
|
|
1732
|
+
}
|
|
1733
|
+
.panel-edit-btn .material-symbols-outlined {
|
|
1734
|
+
font-size: 16px;
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
.panel-description-empty {
|
|
1738
|
+
color: var(--text-dim);
|
|
1739
|
+
font-style: italic;
|
|
1740
|
+
font-size: 12px;
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
.panel-description-editor {
|
|
1744
|
+
display: flex;
|
|
1745
|
+
flex-direction: column;
|
|
1746
|
+
gap: 8px;
|
|
1747
|
+
}
|
|
1748
|
+
.panel-desc-textarea {
|
|
1749
|
+
width: 100%;
|
|
1750
|
+
min-height: 120px;
|
|
1751
|
+
padding: 10px 12px;
|
|
1752
|
+
background: var(--bg-surface);
|
|
1753
|
+
border: 1px solid var(--border);
|
|
1754
|
+
border-radius: var(--radius-sm);
|
|
1755
|
+
color: var(--text);
|
|
1756
|
+
font-family: var(--font-mono);
|
|
1757
|
+
font-size: 12px;
|
|
1758
|
+
line-height: 1.6;
|
|
1759
|
+
resize: vertical;
|
|
1760
|
+
}
|
|
1761
|
+
.panel-desc-textarea:focus {
|
|
1762
|
+
outline: none;
|
|
1763
|
+
border-color: var(--accent);
|
|
1764
|
+
box-shadow: 0 0 0 2px var(--focus-ring);
|
|
1765
|
+
}
|
|
1766
|
+
.panel-desc-actions {
|
|
1767
|
+
display: flex;
|
|
1768
|
+
gap: 8px;
|
|
1769
|
+
justify-content: flex-end;
|
|
1770
|
+
}
|
|
1771
|
+
.panel-desc-save,
|
|
1772
|
+
.panel-desc-cancel {
|
|
1773
|
+
padding: 4px 12px;
|
|
1774
|
+
border-radius: 4px;
|
|
1775
|
+
font-size: 12px;
|
|
1776
|
+
cursor: pointer;
|
|
1777
|
+
border: 1px solid var(--border);
|
|
1778
|
+
background: var(--bg-surface);
|
|
1779
|
+
color: var(--text);
|
|
1780
|
+
transition: all var(--transition-fast);
|
|
1781
|
+
}
|
|
1782
|
+
.panel-desc-save {
|
|
1783
|
+
background: var(--accent);
|
|
1784
|
+
color: #fff;
|
|
1785
|
+
border-color: var(--accent);
|
|
1786
|
+
}
|
|
1787
|
+
.panel-desc-save:hover {
|
|
1788
|
+
background: var(--accent-hover);
|
|
1789
|
+
}
|
|
1790
|
+
.panel-desc-cancel:hover {
|
|
1791
|
+
background: var(--bg-hover);
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1794
|
+
.confirm-overlay {
|
|
1795
|
+
position: fixed;
|
|
1796
|
+
inset: 0;
|
|
1797
|
+
background: rgba(0, 0, 0, 0.5);
|
|
1798
|
+
display: flex;
|
|
1799
|
+
align-items: center;
|
|
1800
|
+
justify-content: center;
|
|
1801
|
+
z-index: 9999;
|
|
1802
|
+
}
|
|
1803
|
+
.confirm-dialog {
|
|
1804
|
+
background: var(--bg-surface);
|
|
1805
|
+
border: 1px solid var(--border);
|
|
1806
|
+
border-radius: var(--radius);
|
|
1807
|
+
padding: 20px;
|
|
1808
|
+
min-width: 320px;
|
|
1809
|
+
max-width: 480px;
|
|
1810
|
+
box-shadow: var(--shadow-3);
|
|
1811
|
+
}
|
|
1812
|
+
.confirm-title {
|
|
1813
|
+
font-size: 14px;
|
|
1814
|
+
font-weight: 700;
|
|
1815
|
+
margin-bottom: 8px;
|
|
1816
|
+
}
|
|
1817
|
+
.confirm-body {
|
|
1818
|
+
font-size: 13px;
|
|
1819
|
+
color: var(--text-muted);
|
|
1820
|
+
margin-bottom: 16px;
|
|
1821
|
+
word-break: break-word;
|
|
1822
|
+
}
|
|
1823
|
+
.confirm-actions {
|
|
1824
|
+
display: flex;
|
|
1825
|
+
gap: 8px;
|
|
1826
|
+
justify-content: flex-end;
|
|
1827
|
+
}
|
|
1828
|
+
.confirm-cancel,
|
|
1829
|
+
.confirm-delete {
|
|
1830
|
+
padding: 6px 16px;
|
|
1831
|
+
border-radius: var(--radius-sm);
|
|
1832
|
+
font-size: 12px;
|
|
1833
|
+
font-weight: 600;
|
|
1834
|
+
cursor: pointer;
|
|
1835
|
+
border: 1px solid var(--border);
|
|
1836
|
+
transition: all var(--transition-fast);
|
|
1837
|
+
}
|
|
1838
|
+
.confirm-cancel {
|
|
1839
|
+
background: var(--bg-elevated);
|
|
1840
|
+
color: var(--text);
|
|
1841
|
+
}
|
|
1842
|
+
.confirm-cancel:hover {
|
|
1843
|
+
background: var(--bg-hover);
|
|
1844
|
+
}
|
|
1845
|
+
.confirm-delete {
|
|
1846
|
+
background: var(--red);
|
|
1847
|
+
color: #fff;
|
|
1848
|
+
border-color: var(--red);
|
|
1849
|
+
}
|
|
1850
|
+
.confirm-delete:hover {
|
|
1851
|
+
opacity: 0.9;
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1672
1854
|
.panel-section {
|
|
1673
1855
|
margin-bottom: 20px;
|
|
1674
1856
|
}
|
package/package.json
CHANGED