@yemi33/minions 0.1.2158 → 0.1.2159
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/dashboard/js/detail-panel.js +1 -1
- package/dashboard/js/fre.js +5 -12
- package/dashboard/js/qa.js +13 -13
- package/dashboard/js/render-agents.js +1 -1
- package/dashboard/js/render-inbox.js +1 -1
- package/dashboard/js/render-kb.js +1 -1
- package/dashboard/js/render-meetings.js +8 -8
- package/dashboard/js/render-other.js +5 -5
- package/dashboard/js/render-pinned.js +3 -3
- package/dashboard/js/render-pipelines.js +6 -6
- package/dashboard/js/render-plans.js +2 -2
- package/dashboard/js/render-prd.js +4 -4
- package/dashboard/js/render-prs.js +2 -2
- package/dashboard/js/render-schedules.js +3 -3
- package/dashboard/js/render-watches.js +5 -5
- package/dashboard/js/render-work-items.js +4 -4
- package/dashboard/js/settings.js +2 -4
- package/dashboard/layout.html +1 -1
- package/dashboard/pages/qa.html +1 -1
- package/dashboard/styles.css +170 -14
- package/package.json +1 -1
|
@@ -118,7 +118,7 @@ function renderDetailContent(detail, tab) {
|
|
|
118
118
|
el.innerHTML =
|
|
119
119
|
'<div style="display:flex;gap:6px;margin-bottom:8px">' +
|
|
120
120
|
'<button class="pr-pager-btn" id="charter-edit-btn" style="font-size:var(--text-sm);padding:2px 10px" onclick="_toggleCharterEdit()">Edit</button>' +
|
|
121
|
-
'<button class="
|
|
121
|
+
'<button class="modal-copy is-success" id="charter-save-btn" style="display:none" onclick="_saveCharter()">Save</button>' +
|
|
122
122
|
'<button class="pr-pager-btn" id="charter-cancel-btn" style="font-size:var(--text-sm);padding:2px 10px;display:none" onclick="_cancelCharterEdit()">Cancel</button>' +
|
|
123
123
|
'</div>' +
|
|
124
124
|
'<div id="charter-view" class="section">' + renderMd(charterContent || 'No charter found. Click Edit to create one.') + '</div>' +
|
package/dashboard/js/fre.js
CHANGED
|
@@ -120,17 +120,10 @@ function renderFre(statusOrProjects) {
|
|
|
120
120
|
'flex-shrink:0',
|
|
121
121
|
].join(';');
|
|
122
122
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
'border:none',
|
|
128
|
-
'border-radius:var(--radius-sm)',
|
|
129
|
-
'cursor:pointer',
|
|
130
|
-
'font-size:var(--text-md)',
|
|
131
|
-
'font-weight:600',
|
|
132
|
-
'margin-top:8px',
|
|
133
|
-
].join(';');
|
|
123
|
+
// W-mq57qetc0009ed48: blue-primary CTA inline blob removed; "+ Add Project"
|
|
124
|
+
// now uses the shared .btn-primary-solid primitive. Only the layout-only
|
|
125
|
+
// margin-top:8px stays inline.
|
|
126
|
+
const btnPrimaryMarginTop = 'margin-top:8px';
|
|
134
127
|
|
|
135
128
|
const btnGhost = [
|
|
136
129
|
'padding:6px 14px',
|
|
@@ -187,7 +180,7 @@ function renderFre(statusOrProjects) {
|
|
|
187
180
|
'<div style="color:var(--muted);font-size:var(--text-md);line-height:1.5">' +
|
|
188
181
|
'Projects map a local git worktree to a remote repo. Without a project, agents have nowhere to run.' +
|
|
189
182
|
'</div>' +
|
|
190
|
-
'<button onclick="addProject()" style="' +
|
|
183
|
+
'<button onclick="addProject()" class="btn-primary-solid" style="' + btnPrimaryMarginTop + '">+ Add Project</button>' +
|
|
191
184
|
'</div>' +
|
|
192
185
|
'</div>' +
|
|
193
186
|
|
package/dashboard/js/qa.js
CHANGED
|
@@ -229,8 +229,8 @@ async function loadQaRunbooks() {
|
|
|
229
229
|
'</div>' +
|
|
230
230
|
'</div>' +
|
|
231
231
|
'<div class="qa-runbook-actions" style="display:flex;gap:var(--space-2)">' +
|
|
232
|
-
'<button class="
|
|
233
|
-
'<button class="
|
|
232
|
+
'<button class="btn-primary-solid qa-runbook-run-btn" data-runbook-id="' + escHtml(id) + '" onclick="qaRunRunbook(this.dataset.runbookId)">Run</button>' +
|
|
233
|
+
'<button class="btn-ghost qa-btn-danger qa-runbook-delete-btn" data-runbook-id="' + escHtml(id) + '" onclick="qaDeleteRunbook(this.dataset.runbookId)">Delete</button>' +
|
|
234
234
|
'</div>' +
|
|
235
235
|
'</div>';
|
|
236
236
|
}).join('');
|
|
@@ -350,7 +350,7 @@ function _qaRenderRunRow(run) {
|
|
|
350
350
|
// to click.
|
|
351
351
|
let deleteBtn = '';
|
|
352
352
|
if (_qaIsTerminalStatus(status)) {
|
|
353
|
-
deleteBtn = '<button class="
|
|
353
|
+
deleteBtn = '<button class="btn-ghost qa-run-delete-btn" ' +
|
|
354
354
|
'data-run-id="' + escHtml(id) + '" ' +
|
|
355
355
|
'onclick="qaDeleteRun(this.dataset.runId)">Delete</button>';
|
|
356
356
|
}
|
|
@@ -731,14 +731,14 @@ function _qaRenderSessionCard(s) {
|
|
|
731
731
|
// - terminal → no actions
|
|
732
732
|
let actions = '';
|
|
733
733
|
if (state === 'awaiting-approval') {
|
|
734
|
-
actions += '<button class="
|
|
735
|
-
actions += '<button class="
|
|
736
|
-
actions += '<button class="
|
|
737
|
-
actions += '<button class="
|
|
734
|
+
actions += '<button class="btn-ghost" onclick="qaSessionReviewDraft(\'' + escHtml(id) + '\')">Review draft</button>';
|
|
735
|
+
actions += '<button class="btn-primary-solid" onclick="qaSessionApprove(\'' + escHtml(id) + '\')">Approve & run</button>';
|
|
736
|
+
actions += '<button class="btn-ghost" onclick="qaSessionEditPrompt(\'' + escHtml(id) + '\')">Edit</button>';
|
|
737
|
+
actions += '<button class="btn-ghost" onclick="qaSessionCancel(\'' + escHtml(id) + '\')">Cancel</button>';
|
|
738
738
|
}
|
|
739
739
|
if (!isTerminal) {
|
|
740
|
-
actions += '<button class="
|
|
741
|
-
actions += '<button class="
|
|
740
|
+
actions += '<button class="btn-ghost" onclick="qaSessionDismiss(\'' + escHtml(id) + '\')">Dismiss</button>';
|
|
741
|
+
actions += '<button class="btn-ghost qa-btn-danger" onclick="qaSessionKill(\'' + escHtml(id) + '\')">Kill spawn</button>';
|
|
742
742
|
}
|
|
743
743
|
|
|
744
744
|
let meta = '';
|
|
@@ -976,7 +976,7 @@ function _qaBuildModalShell(sessionId) {
|
|
|
976
976
|
header.appendChild(title);
|
|
977
977
|
const closeBtn = document.createElement('button');
|
|
978
978
|
closeBtn.type = 'button';
|
|
979
|
-
closeBtn.className = '
|
|
979
|
+
closeBtn.className = 'btn-ghost qa-modal-close';
|
|
980
980
|
closeBtn.setAttribute('aria-label', 'Close');
|
|
981
981
|
closeBtn.textContent = '×';
|
|
982
982
|
closeBtn.addEventListener('click', _qaModalClose);
|
|
@@ -1080,7 +1080,7 @@ function _qaModalRenderBody(payload) {
|
|
|
1080
1080
|
if (!payload.truncated) {
|
|
1081
1081
|
const approve = document.createElement('button');
|
|
1082
1082
|
approve.type = 'button';
|
|
1083
|
-
approve.className = '
|
|
1083
|
+
approve.className = 'btn-primary-solid';
|
|
1084
1084
|
approve.textContent = 'Approve & run';
|
|
1085
1085
|
approve.addEventListener('click', () => {
|
|
1086
1086
|
_qaModalClose();
|
|
@@ -1090,7 +1090,7 @@ function _qaModalRenderBody(payload) {
|
|
|
1090
1090
|
}
|
|
1091
1091
|
const editBtn = document.createElement('button');
|
|
1092
1092
|
editBtn.type = 'button';
|
|
1093
|
-
editBtn.className = '
|
|
1093
|
+
editBtn.className = 'btn-ghost';
|
|
1094
1094
|
editBtn.textContent = 'Request edit';
|
|
1095
1095
|
editBtn.addEventListener('click', () => {
|
|
1096
1096
|
_qaModalClose();
|
|
@@ -1099,7 +1099,7 @@ function _qaModalRenderBody(payload) {
|
|
|
1099
1099
|
footer.appendChild(editBtn);
|
|
1100
1100
|
const closeBtn = document.createElement('button');
|
|
1101
1101
|
closeBtn.type = 'button';
|
|
1102
|
-
closeBtn.className = '
|
|
1102
|
+
closeBtn.className = 'btn-ghost';
|
|
1103
1103
|
closeBtn.textContent = 'Close';
|
|
1104
1104
|
closeBtn.addEventListener('click', _qaModalClose);
|
|
1105
1105
|
footer.appendChild(closeBtn);
|
|
@@ -143,7 +143,7 @@ async function openAgentDetail(id) {
|
|
|
143
143
|
document.getElementById('detail-content').innerHTML =
|
|
144
144
|
'<div style="padding:24px;text-align:center">' +
|
|
145
145
|
'<div style="color:var(--red);margin-bottom:12px">Error loading agent detail: ' + escapeHtml(e.message) + '</div>' +
|
|
146
|
-
'<button data-agent-id="' + escapeHtml(id) + '" onclick="openAgentDetail(this.dataset.agentId)"
|
|
146
|
+
'<button data-agent-id="' + escapeHtml(id) + '" onclick="openAgentDetail(this.dataset.agentId)" class="btn-primary-lg">Retry</button>' +
|
|
147
147
|
' <button onclick="closeDetail()" style="padding:6px 16px;background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius-sm);cursor:pointer;font-size:var(--text-md);color:var(--text)">Close</button>' +
|
|
148
148
|
'</div>';
|
|
149
149
|
}
|
|
@@ -270,7 +270,7 @@ function openQuickNoteModal() {
|
|
|
270
270
|
'<textarea id="note-content" rows="6" style="display:block;width:100%;margin-top:4px;padding:6px 8px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);resize:vertical;font-family:inherit" placeholder="Write your note... Agents will see this after consolidation."></textarea></label>' +
|
|
271
271
|
'<div style="display:flex;justify-content:flex-end;gap:8px">' +
|
|
272
272
|
'<button onclick="closeModal()" class="pr-pager-btn">Cancel</button>' +
|
|
273
|
-
'<button onclick="submitQuickNote()"
|
|
273
|
+
'<button onclick="submitQuickNote()" class="btn-primary-lg">Save Note</button>' +
|
|
274
274
|
'</div>' +
|
|
275
275
|
'</div>';
|
|
276
276
|
document.getElementById('modal').classList.add('open');
|
|
@@ -222,7 +222,7 @@ function openCreateKbModal() {
|
|
|
222
222
|
'<textarea id="kb-new-content" rows="8" style="display:block;width:100%;margin-top:4px;padding:6px 8px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);resize:vertical;font-family:inherit" placeholder="Write your knowledge entry..."></textarea></label>' +
|
|
223
223
|
'<div style="display:flex;justify-content:flex-end;gap:8px">' +
|
|
224
224
|
'<button onclick="closeModal()" class="pr-pager-btn">Cancel</button>' +
|
|
225
|
-
'<button onclick="submitKbEntry(event)"
|
|
225
|
+
'<button onclick="submitKbEntry(event)" class="btn-primary-lg">Save</button>' +
|
|
226
226
|
'</div>' +
|
|
227
227
|
'</div>';
|
|
228
228
|
document.getElementById('modal').classList.add('open');
|
|
@@ -123,7 +123,7 @@ function renderMeetings(meetings, opts) {
|
|
|
123
123
|
(m.status === 'archived'
|
|
124
124
|
? '<button class="pr-pager-btn" style="font-size:var(--text-xs);padding:1px 6px" onclick="event.stopPropagation();_unarchiveMeeting(\'' + escHtml(m.id) + '\')">Unarchive</button>'
|
|
125
125
|
: (m.status === 'completed' ? '<button class="pr-pager-btn" style="font-size:var(--text-xs);padding:1px 6px" onclick="event.stopPropagation();_archiveMeeting(\'' + escHtml(m.id) + '\')">Archive</button>' : '')) +
|
|
126
|
-
'<button class="
|
|
126
|
+
'<button class="btn-destructive" onclick="event.stopPropagation();_deleteMeeting(\'' + escHtml(m.id) + '\')">Delete</button>' +
|
|
127
127
|
'</div>' +
|
|
128
128
|
'</div>' +
|
|
129
129
|
(timeStr ? '<div style="margin-top:4px;font-size:var(--text-sm);color:var(--muted)">' + escHtml(timeStr) + '</div>' : '') +
|
|
@@ -246,17 +246,17 @@ function _renderMeetingDetail(m) {
|
|
|
246
246
|
if (m.status === 'archived') {
|
|
247
247
|
html += '<div style="display:flex;gap:8px;border-top:1px solid var(--border);padding-top:8px">' +
|
|
248
248
|
'<button class="pr-pager-btn" style="font-size:var(--text-xs);padding:2px 8px" onclick="_unarchiveMeeting(\'' + escHtml(m.id) + '\')">Unarchive</button>' +
|
|
249
|
-
'<button class="
|
|
249
|
+
'<button class="btn-destructive btn-destructive-md" onclick="_deleteMeeting(\'' + escHtml(m.id) + '\')">Delete</button>' +
|
|
250
250
|
'</div>';
|
|
251
251
|
} else if (m.status === 'completed') {
|
|
252
252
|
const linkedPlan = _findLinkedPlan(m);
|
|
253
253
|
html += '<div style="display:flex;gap:8px;flex-wrap:wrap;border-top:1px solid var(--border);padding-top:8px">' +
|
|
254
254
|
(linkedPlan
|
|
255
255
|
? '<button class="pr-pager-btn" style="font-size:var(--text-xs);padding:2px 8px;color:var(--blue);border-color:var(--blue)" onclick="_viewPlanWithBack(\'' + escHtml(linkedPlan.file) + '\',\'' + escHtml(m.id) + '\')">View Plan</button>' +
|
|
256
|
-
'<button class="
|
|
257
|
-
: '<button class="
|
|
256
|
+
'<button class="btn-action btn-action-md" onclick="_createPlanFromMeeting(\'' + escHtml(m.id) + '\',this)">New Plan</button>'
|
|
257
|
+
: '<button class="btn-action btn-action-md" onclick="_createPlanFromMeeting(\'' + escHtml(m.id) + '\',this)">Create Plan from Meeting</button>') +
|
|
258
258
|
'<button class="pr-pager-btn" style="font-size:var(--text-xs);padding:2px 8px" onclick="_archiveMeeting(\'' + escHtml(m.id) + '\')">Archive</button>' +
|
|
259
|
-
'<button class="
|
|
259
|
+
'<button class="btn-destructive btn-destructive-md" onclick="_deleteMeeting(\'' + escHtml(m.id) + '\')">Delete</button>' +
|
|
260
260
|
'</div>' +
|
|
261
261
|
'<div id="meeting-plan-toast" class="cmd-toast cmd-toast-inline" style="margin-top:6px"></div>' +
|
|
262
262
|
'<div style="font-size:var(--text-xs);color:var(--muted);margin-top:4px">Use the Q&A below to discuss action items' + (linkedPlan ? '' : ', then create a plan to execute them') + '.</div>';
|
|
@@ -267,8 +267,8 @@ function _renderMeetingDetail(m) {
|
|
|
267
267
|
'</div>' +
|
|
268
268
|
'<div style="display:flex;gap:8px;margin-top:4px">' +
|
|
269
269
|
'<button class="pr-pager-btn" style="font-size:var(--text-xs);padding:2px 8px;color:var(--yellow);border-color:var(--yellow)" onclick="_advanceMeeting(\'' + escHtml(m.id) + '\',this)">Skip to Next Round</button>' +
|
|
270
|
-
'<button class="
|
|
271
|
-
'<button class="
|
|
270
|
+
'<button class="btn-destructive btn-destructive-md" onclick="_endMeeting(\'' + escHtml(m.id) + '\',this)">End Meeting</button>' +
|
|
271
|
+
'<button class="btn-destructive btn-destructive-md" onclick="_deleteMeeting(\'' + escHtml(m.id) + '\')">Delete</button>' +
|
|
272
272
|
'</div>';
|
|
273
273
|
}
|
|
274
274
|
|
|
@@ -347,7 +347,7 @@ function openCreateMeetingModal() {
|
|
|
347
347
|
'<div style="color:var(--text);font-size:var(--text-md)">Participants<div style="display:flex;flex-direction:column;gap:4px;margin-top:4px" id="mtg-participants">' + agentOpts + '</div></div>' +
|
|
348
348
|
'<div style="display:flex;justify-content:flex-end;gap:8px;margin-top:4px">' +
|
|
349
349
|
'<button onclick="closeModal()" class="pr-pager-btn">Cancel</button>' +
|
|
350
|
-
'<button onclick="_submitCreateMeeting(event)"
|
|
350
|
+
'<button onclick="_submitCreateMeeting(event)" class="btn-primary-lg">Start Meeting</button>' +
|
|
351
351
|
'</div>' +
|
|
352
352
|
'</div>';
|
|
353
353
|
document.getElementById('modal').classList.add('open');
|
|
@@ -5,8 +5,8 @@ function renderProjects(projects) {
|
|
|
5
5
|
const visible = (projects || []).filter(p => typeof isDeleted === 'function' ? !isDeleted('project:' + p.name) : true);
|
|
6
6
|
if (!visible.length) {
|
|
7
7
|
list.innerHTML = '<span style="color:var(--muted);font-style:italic">No projects linked.</span>' +
|
|
8
|
-
'<span onclick="addProject()"
|
|
9
|
-
'<span onclick="openScanProjectsModal()"
|
|
8
|
+
'<span onclick="addProject()" class="empty-state-add" style="margin-left:8px">+ Add Project</span>' +
|
|
9
|
+
'<span onclick="openScanProjectsModal()" class="empty-state-add empty-state-add-blue">Scan</span>';
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
12
|
// eslint-disable-next-line no-unsanitized/property -- reason: structural HTML is a string literal; all user data wrapped in escHtml() (fields: project name, path, branch metadata)
|
|
@@ -17,8 +17,8 @@ function renderProjects(projects) {
|
|
|
17
17
|
'<span onclick="event.stopPropagation();projectChipRemove(\'' + escHtml(p.name) + '\')" title="Remove project (cancels pending work, archives data dir)" style="color:var(--muted);font-weight:600;cursor:pointer;padding:0 2px;line-height:1" onmouseover="this.style.color=\'var(--red)\'" onmouseout="this.style.color=\'var(--muted)\'">×</span>' +
|
|
18
18
|
'</span>'
|
|
19
19
|
).join('') +
|
|
20
|
-
'<span onclick="addProject()"
|
|
21
|
-
'<span onclick="openScanProjectsModal()"
|
|
20
|
+
'<span onclick="addProject()" class="empty-state-add empty-state-add-muted">+ Add</span>' +
|
|
21
|
+
'<span onclick="openScanProjectsModal()" class="empty-state-add empty-state-add-blue">Scan</span>';
|
|
22
22
|
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -422,7 +422,7 @@ async function openScanProjectsModal() {
|
|
|
422
422
|
'<label style="width:60px;color:var(--text);font-size:var(--text-md)">Depth' +
|
|
423
423
|
'<input id="scan-depth" type="number" value="3" min="1" max="6" style="display:block;width:100%;margin-top:4px;padding:6px 8px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);font-size:var(--text-md)">' +
|
|
424
424
|
'</label>' +
|
|
425
|
-
'<button onclick="_runProjectScan()"
|
|
425
|
+
'<button onclick="_runProjectScan()" class="btn-primary-lg" style="white-space:nowrap">Scan</button>' +
|
|
426
426
|
'</div>' +
|
|
427
427
|
'<div id="scan-results" style="color:var(--muted);font-size:var(--text-md)">Click Scan to find git repos in the directory.</div>' +
|
|
428
428
|
'<div class="cmd-toast" id="scan-toast" style="margin-top:0"></div>' +
|
|
@@ -17,7 +17,7 @@ function renderPinned(entries) {
|
|
|
17
17
|
';border-radius:4px;cursor:pointer" onclick="if(shouldIgnoreSelectionClick(event))return;openPinnedView(' + i + ')">' +
|
|
18
18
|
'<div style="display:flex;justify-content:space-between;align-items:center">' +
|
|
19
19
|
'<strong style="font-size:var(--text-md)">' + escHtml(e.title) + '</strong>' +
|
|
20
|
-
'<button class="
|
|
20
|
+
'<button class="btn-destructive" data-pin-title="' + escHtml(e.title) + '" onclick="event.stopPropagation();removePinnedNote(this.dataset.pinTitle)">Unpin</button>' +
|
|
21
21
|
'</div>' +
|
|
22
22
|
'<div style="font-size:var(--text-sm);color:var(--muted);margin-top:4px">' + renderMd(e.content.slice(0, 200)) + (e.content.length > 200 ? '...' : '') + '</div>' +
|
|
23
23
|
'</div>'
|
|
@@ -44,7 +44,7 @@ function openPinNoteModal() {
|
|
|
44
44
|
'<label style="color:var(--text);font-size:var(--text-md)">Title<input id="pin-title" style="display:block;width:100%;margin-top:4px;padding:6px 8px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text)" placeholder="e.g. API freeze until Friday"></label>' +
|
|
45
45
|
'<label style="color:var(--text);font-size:var(--text-md)">Content<textarea id="pin-content" rows="4" style="display:block;width:100%;margin-top:4px;padding:6px 8px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);resize:vertical;font-family:inherit" placeholder="Context all agents should see..."></textarea></label>' +
|
|
46
46
|
'<label style="color:var(--text);font-size:var(--text-md)">Level<select id="pin-level" style="display:block;width:100%;margin-top:4px;padding:6px 8px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text)"><option value="info">Info</option><option value="warning">Warning</option><option value="critical">Critical</option></select></label>' +
|
|
47
|
-
'<div style="display:flex;justify-content:flex-end;gap:8px"><button onclick="closeModal()" class="pr-pager-btn">Cancel</button><button onclick="submitPinnedNote(event)"
|
|
47
|
+
'<div style="display:flex;justify-content:flex-end;gap:8px"><button onclick="closeModal()" class="pr-pager-btn">Cancel</button><button onclick="submitPinnedNote(event)" class="btn-primary-lg">Pin</button></div>' +
|
|
48
48
|
'</div>';
|
|
49
49
|
document.getElementById('modal').classList.add('open');
|
|
50
50
|
}
|
|
@@ -194,7 +194,7 @@ function openPinnedEdit(idx) {
|
|
|
194
194
|
cancelBtn.textContent = 'Cancel';
|
|
195
195
|
cancelBtn.onclick = function() { openPinnedView(idx); };
|
|
196
196
|
const saveBtn = document.createElement('button');
|
|
197
|
-
saveBtn.
|
|
197
|
+
saveBtn.className = 'btn-primary-lg';
|
|
198
198
|
saveBtn.textContent = 'Save';
|
|
199
199
|
saveBtn.onclick = function(ev) { submitPinnedEdit(originalTitle, ev); };
|
|
200
200
|
actions.appendChild(cancelBtn);
|
|
@@ -399,12 +399,12 @@ function openPipelineDetail(id) {
|
|
|
399
399
|
'<span style="font-size:var(--text-sm);color:var(--muted)">' + _renderPipelineTriggerLabel(p.trigger?.cron) + ' · ' + escHtml(_getPipelineStageLabel(p)) + '</span>' +
|
|
400
400
|
'<div style="display:flex;gap:6px">' +
|
|
401
401
|
(activeRun
|
|
402
|
-
? '<button class="
|
|
402
|
+
? '<button class="btn-destructive btn-destructive-md" onclick="_abortPipeline(\'' + escHtml(id) + '\',this)">Abort</button>' +
|
|
403
403
|
'<button class="pr-pager-btn" style="font-size:var(--text-xs);padding:2px 8px;color:var(--yellow);border-color:var(--yellow)" onclick="_retriggerPipeline(\'' + escHtml(id) + '\',this)">Retrigger</button>'
|
|
404
|
-
: '<button class="
|
|
404
|
+
: '<button class="btn-action btn-action-md" onclick="_triggerPipeline(\'' + escHtml(id) + '\',this)">Run Now</button>') +
|
|
405
405
|
'<button class="pr-pager-btn" style="font-size:var(--text-xs);padding:2px 8px;color:var(--blue);border-color:var(--blue)" onclick="openEditPipelineModal(\'' + escHtml(id) + '\')">Edit</button>' +
|
|
406
406
|
'<button class="pr-pager-btn' + (_pipelineToggleInFlight.has(id) ? ' disabled' : '') + '" style="font-size:var(--text-xs);padding:2px 8px" onclick="_togglePipelineEnabled(\'' + escHtml(id) + '\',' + !p.enabled + ',this)">' + (p.enabled !== false ? 'Disable' : 'Enable') + '</button>' +
|
|
407
|
-
'<button class="
|
|
407
|
+
'<button class="btn-destructive btn-destructive-md" onclick="_deletePipelineConfirm(\'' + escHtml(id) + '\')">Delete</button>' +
|
|
408
408
|
'</div>' +
|
|
409
409
|
'</div>';
|
|
410
410
|
|
|
@@ -454,7 +454,7 @@ function openPipelineDetail(id) {
|
|
|
454
454
|
_renderMonitoredResources(s.monitoredResources || []) +
|
|
455
455
|
_renderArtifactLinks(stageRun.artifacts, id) +
|
|
456
456
|
(stageRun.output ? '<div class="pipeline-stage-output" style="margin-top:6px;font-size:var(--text-base);max-height:150px;overflow-y:auto">' + renderMd(stageRun.output.slice(0, 500)) + '</div>' : '') +
|
|
457
|
-
(stageStatus === 'waiting-human' ? '<button class="
|
|
457
|
+
(stageStatus === 'waiting-human' ? '<button class="btn-action btn-action-md" style="margin-top:6px" onclick="_continuePipeline(\'' + escHtml(id) + '\',\'' + escHtml(s.id) + '\',this)">Continue</button>' : '') +
|
|
458
458
|
'</div>';
|
|
459
459
|
});
|
|
460
460
|
|
|
@@ -726,7 +726,7 @@ function openCreatePipelineModal() {
|
|
|
726
726
|
'<label style="color:var(--text);font-size:var(--text-md)">Stages (JSON array)<textarea id="pl-stages" rows="10" style="' + inputStyle + ';resize:vertical;font-family:Consolas,monospace" placeholder=\'[{"id":"audit","type":"task","title":"Audit codebase","taskType":"explore"},{"id":"discuss","type":"meeting","title":"Discuss findings","dependsOn":["audit"],"participants":["all"]}]\'></textarea></label>' +
|
|
727
727
|
'<div style="display:flex;justify-content:flex-end;gap:8px;margin-top:4px">' +
|
|
728
728
|
'<button onclick="closeModal()" class="pr-pager-btn">Cancel</button>' +
|
|
729
|
-
'<button onclick="_submitCreatePipeline()"
|
|
729
|
+
'<button onclick="_submitCreatePipeline()" class="btn-primary-lg">Create Pipeline</button>' +
|
|
730
730
|
'</div>' +
|
|
731
731
|
'</div>';
|
|
732
732
|
document.getElementById('modal').classList.add('open');
|
|
@@ -828,7 +828,7 @@ function openEditPipelineModal(id) {
|
|
|
828
828
|
'<label style="color:var(--text);font-size:var(--text-md)">Stages (JSON array)<textarea id="pl-stages" rows="10" style="' + inputStyle + ';resize:vertical;font-family:Consolas,monospace">' + escHtml(JSON.stringify(p.stages || [], null, 2)) + '</textarea></label>' +
|
|
829
829
|
'<div style="display:flex;justify-content:flex-end;gap:8px;margin-top:4px">' +
|
|
830
830
|
'<button onclick="closeModal()" class="pr-pager-btn">Cancel</button>' +
|
|
831
|
-
'<button onclick="_submitEditPipeline()"
|
|
831
|
+
'<button onclick="_submitEditPipeline()" class="btn-primary-lg">Save</button>' +
|
|
832
832
|
'</div>' +
|
|
833
833
|
'</div>';
|
|
834
834
|
document.getElementById('modal-body').style.whiteSpace = 'normal';
|
|
@@ -22,7 +22,7 @@ function openCreatePlanModal() {
|
|
|
22
22
|
'<div style="font-size:var(--text-base);color:var(--muted)">After creating, click Execute on the plan card to have an agent convert it into a PRD with work items.</div>' +
|
|
23
23
|
'<div style="display:flex;justify-content:flex-end;gap:8px;margin-top:4px">' +
|
|
24
24
|
'<button onclick="closeModal()" class="pr-pager-btn">Cancel</button>' +
|
|
25
|
-
'<button onclick="_submitCreatePlan(event)"
|
|
25
|
+
'<button onclick="_submitCreatePlan(event)" class="btn-primary-lg">Create Plan</button>' +
|
|
26
26
|
'</div>' +
|
|
27
27
|
'</div>';
|
|
28
28
|
document.getElementById('modal').classList.add('open');
|
|
@@ -468,7 +468,7 @@ function planReexecuteModal(file, project) {
|
|
|
468
468
|
'<div style="font-size:var(--text-base);color:var(--muted)">Leave blank to re-run without steering. The agent will read the existing PRD and rewrite it.</div>' +
|
|
469
469
|
'<div style="display:flex;justify-content:flex-end;gap:8px;margin-top:4px">' +
|
|
470
470
|
'<button onclick="closeModal()" class="pr-pager-btn">Cancel</button>' +
|
|
471
|
-
'<button onclick="planReexecuteSubmit(\'' + escapeHtml(file) + '\',\'' + escapeHtml(project || '') + '\')"
|
|
471
|
+
'<button onclick="planReexecuteSubmit(\'' + escapeHtml(file) + '\',\'' + escapeHtml(project || '') + '\')" class="btn-primary-lg">Re-execute</button>' +
|
|
472
472
|
'</div>' +
|
|
473
473
|
'</div>';
|
|
474
474
|
document.getElementById('modal').classList.add('open');
|
|
@@ -105,15 +105,15 @@ function renderPrd(prd, prog) {
|
|
|
105
105
|
let actions = '';
|
|
106
106
|
if (prdFile && !headerStale) {
|
|
107
107
|
if (effectiveStatus === 'awaiting-approval') {
|
|
108
|
-
actions = ' <button class="
|
|
108
|
+
actions = ' <button class="btn-action" style="margin-left:4px" onclick="planApprove(\'' + escHtml(prdFile) + '\',this)">Approve</button>';
|
|
109
109
|
} else if (effectiveStatus === 'completed') {
|
|
110
110
|
const hasVerifyWi = allWi.some(w => w.itemType === 'verify' && w.sourcePlan === prdFile);
|
|
111
|
-
actions = (hasVerifyWi ? '' : ' <button class="
|
|
111
|
+
actions = (hasVerifyWi ? '' : ' <button class="btn-action" style="margin-left:4px" onclick="triggerVerify(\'' + escHtml(prdFile) + '\',this)">Verify</button>') +
|
|
112
112
|
' <button class="pr-pager-btn" style="font-size:var(--text-xs);padding:1px 6px;margin-left:4px" onclick="planArchive(\'' + escHtml(prdFile) + '\',this)">Archive</button>';
|
|
113
113
|
} else if (effectiveStatus === 'dispatched') {
|
|
114
114
|
actions = ' <button class="pr-pager-btn" style="font-size:var(--text-xs);padding:1px 6px;color:var(--yellow);border-color:var(--yellow);margin-left:4px" onclick="planPause(\'' + escHtml(prdFile) + '\',this)">Pause</button>';
|
|
115
115
|
} else if (effectiveStatus === 'paused') {
|
|
116
|
-
actions = ' <button class="
|
|
116
|
+
actions = ' <button class="btn-action" style="margin-left:4px" onclick="planApprove(\'' + escHtml(prdFile) + '\',this)">Resume</button>' +
|
|
117
117
|
' <button class="pr-pager-btn" style="font-size:var(--text-xs);padding:1px 6px;margin-left:4px" onclick="planArchive(\'' + escHtml(prdFile) + '\',this)">Archive</button>';
|
|
118
118
|
}
|
|
119
119
|
}
|
|
@@ -823,7 +823,7 @@ async function prdItemEdit(source, itemId) {
|
|
|
823
823
|
'<label style="font-size:var(--text-base);color:var(--muted)">Description</label>' +
|
|
824
824
|
'<div style="display:flex;gap:6px">' +
|
|
825
825
|
'<button id="prd-desc-edit-btn" type="button" class="pr-pager-btn" aria-label="Edit description" style="font-size:var(--text-sm);padding:2px 10px" onclick="_togglePrdDescEdit()">Edit</button>' +
|
|
826
|
-
'<button id="prd-desc-save-btn" type="button" class="
|
|
826
|
+
'<button id="prd-desc-save-btn" type="button" class="btn-action btn-action-lg" aria-label="Save description" style="display:none" onclick="_savePrdDesc(\'' + escHtml(source) + '\',\'' + escHtml(itemId) + '\')">Save</button>' +
|
|
827
827
|
'<button id="prd-desc-cancel-btn" type="button" class="pr-pager-btn" aria-label="Cancel description edit" style="font-size:var(--text-sm);padding:2px 10px;display:none" onclick="_cancelPrdDescEdit()">Cancel</button>' +
|
|
828
828
|
'</div>' +
|
|
829
829
|
'</div>' +
|
|
@@ -204,7 +204,7 @@ function prRow(pr) {
|
|
|
204
204
|
'<td><span class="pr-badge ' + statusClass + '" title="' + escapeHtml(statusLabel) + '">' + escapeHtml(statusLabel) + '</span></td>' +
|
|
205
205
|
'<td>' + (observeBtn || '<span style="color:var(--muted);font-size:var(--text-base)">—</span>') + '</td>' +
|
|
206
206
|
'<td><span class="pr-date" title="' + escapeHtml(createdLabel) + '">' + escapeHtml(createdLabel) + '</span></td>' +
|
|
207
|
-
'<td><button class="
|
|
207
|
+
'<td><button class="btn-destructive" style="padding:1px 5px" data-pr-id="' + escapeHtml(String(prId)) + '" onclick="event.stopPropagation();unlinkPr(this.dataset.prId)" title="Remove from tracking">x</button></td>' +
|
|
208
208
|
'</tr>';
|
|
209
209
|
}
|
|
210
210
|
|
|
@@ -350,7 +350,7 @@ function openAddPrModal() {
|
|
|
350
350
|
'<div style="font-size:var(--text-base);color:var(--muted);margin-top:-4px;padding-left:24px">Off = context only (e.g. teammate\'s PR). On = agents actively monitor and fix issues.</div>' +
|
|
351
351
|
'<div style="display:flex;justify-content:flex-end;gap:8px;margin-top:8px">' +
|
|
352
352
|
'<button onclick="closeModal()" class="pr-pager-btn">Cancel</button>' +
|
|
353
|
-
'<button onclick="_submitLinkPr(event)"
|
|
353
|
+
'<button onclick="_submitLinkPr(event)" class="btn-primary-lg">Link PR</button>' +
|
|
354
354
|
'</div>' +
|
|
355
355
|
'</div>';
|
|
356
356
|
document.getElementById('modal').classList.add('open');
|
|
@@ -352,10 +352,10 @@ function renderSchedules(schedules, opts) {
|
|
|
352
352
|
'<td>' + enabledBadge + '</td>' +
|
|
353
353
|
'<td><span class="pr-date">' + escHtml(lastRun) + '</span></td>' +
|
|
354
354
|
'<td style="white-space:nowrap">' +
|
|
355
|
-
'<button class="
|
|
355
|
+
'<button class="btn-action" style="margin-right:4px" onclick="event.stopPropagation();runScheduleNow(\'' + escHtml(s.id) + '\',this)" title="Run now">Run now</button>' +
|
|
356
356
|
'<button class="pr-pager-btn' + (_schedToggleInFlight.has(s.id) ? ' disabled' : '') + '" style="font-size:var(--text-xs);padding:1px 6px;color:' + (s.enabled ? 'var(--yellow)' : 'var(--green)') + ';border-color:' + (s.enabled ? 'var(--yellow)' : 'var(--green)') + ';margin-right:4px" onclick="event.stopPropagation();toggleScheduleEnabled(\'' + escHtml(s.id) + '\',' + !s.enabled + ')" title="' + (s.enabled ? 'Disable' : 'Enable') + '">' + (s.enabled ? '⏸' : '▶') + '</button>' +
|
|
357
357
|
'<button class="pr-pager-btn" style="font-size:var(--text-xs);padding:1px 6px;color:var(--blue);border-color:var(--blue);margin-right:4px" onclick="event.stopPropagation();openEditScheduleModal(\'' + escHtml(s.id) + '\')" title="Edit">✎</button>' +
|
|
358
|
-
'<button class="
|
|
358
|
+
'<button class="btn-destructive" onclick="event.stopPropagation();deleteSchedule(\'' + escHtml(s.id) + '\')" title="Delete">✕</button>' +
|
|
359
359
|
'</td>' +
|
|
360
360
|
'</tr>';
|
|
361
361
|
}
|
|
@@ -515,7 +515,7 @@ function _scheduleFormHtml(sched, isEdit) {
|
|
|
515
515
|
'</label>' +
|
|
516
516
|
'<div style="display:flex;justify-content:flex-end;gap:8px;margin-top:8px">' +
|
|
517
517
|
'<button onclick="closeModal()" class="pr-pager-btn" style="padding:6px 16px;font-size:var(--text-md)">Cancel</button>' +
|
|
518
|
-
'<button onclick="submitSchedule(' + isEdit + ',event)"
|
|
518
|
+
'<button onclick="submitSchedule(' + isEdit + ',event)" class="btn-primary-lg">' + (isEdit ? 'Save' : 'Create') + '</button>' +
|
|
519
519
|
'</div>' +
|
|
520
520
|
'</div>';
|
|
521
521
|
}
|
|
@@ -216,11 +216,11 @@ function renderWatches(watchesData, opts) {
|
|
|
216
216
|
if (w.status === 'active') {
|
|
217
217
|
html += '<button class="pr-pager-btn' + pauseBusyCls + '" style="font-size:var(--text-xs);padding:1px 6px;color:var(--yellow);border-color:var(--yellow);margin-right:4px" onclick="event.stopPropagation();toggleWatchPause(\'' + escHtml(w.id) + '\',true)" title="Pause">⏸</button>';
|
|
218
218
|
} else if (w.status === 'paused') {
|
|
219
|
-
html += '<button class="
|
|
219
|
+
html += '<button class="btn-action' + pauseBusyCls + '" style="margin-right:4px" onclick="event.stopPropagation();toggleWatchPause(\'' + escHtml(w.id) + '\',false)" title="Resume">▶</button>';
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
// Delete button
|
|
223
|
-
html += '<button class="
|
|
223
|
+
html += '<button class="btn-destructive" onclick="event.stopPropagation();deleteWatch(\'' + escHtml(w.id) + '\')" title="Delete">✕</button>';
|
|
224
224
|
html += '</td></tr>';
|
|
225
225
|
}
|
|
226
226
|
|
|
@@ -548,7 +548,7 @@ function _addWatchStepRow(initial) {
|
|
|
548
548
|
row.innerHTML =
|
|
549
549
|
'<div style="display:flex;align-items:center;justify-content:space-between;gap:8px">' +
|
|
550
550
|
'<select id="watch-step-' + idx + '-type" style="' + inputStyle + ';margin-top:0;flex:1" onchange="_updateWatchStepParamsHint(' + idx + ')">' + actionOpts + '</select>' +
|
|
551
|
-
'<button type="button" class="
|
|
551
|
+
'<button type="button" class="btn-destructive btn-destructive-lg" onclick="_removeWatchStepRow(' + idx + ')">Remove</button>' +
|
|
552
552
|
'</div>' +
|
|
553
553
|
'<label style="color:var(--text);font-size:var(--text-base)">Params (JSON) <span style="font-size:var(--text-sm);color:var(--muted)" id="watch-step-' + idx + '-params-hint"></span>' +
|
|
554
554
|
'<textarea id="watch-step-' + idx + '-params" rows="3" placeholder=\'{"title": "Re-check {{target}} after merge"}\' style="' + inputStyle + ';font-family:monospace"></textarea>' +
|
|
@@ -612,7 +612,7 @@ function _addRequireRow(initial) {
|
|
|
612
612
|
'<label style="color:var(--text);font-size:var(--text-base);margin:0">Target<input id="watch-require-' + idx + '-target" placeholder="e.g. PR-123, pipeline-X" style="' + inputStyle + '"></label>' +
|
|
613
613
|
'<label style="color:var(--text);font-size:var(--text-base);margin:0">Target Type<select id="watch-require-' + idx + '-target-type" style="' + inputStyle + '" onchange="_updateRequireConditionOptions(' + idx + ')">' + ttOpts + '</select></label>' +
|
|
614
614
|
'<label style="color:var(--text);font-size:var(--text-base);margin:0">Condition<select id="watch-require-' + idx + '-condition" style="' + inputStyle + '"></select></label>' +
|
|
615
|
-
'<button type="button" class="
|
|
615
|
+
'<button type="button" class="btn-destructive btn-destructive-lg" style="padding:6px 8px" onclick="_removeRequireRow(' + idx + ')">Remove</button>';
|
|
616
616
|
container.appendChild(row);
|
|
617
617
|
if (initTarget) document.getElementById('watch-require-' + idx + '-target').value = initTarget;
|
|
618
618
|
if (initTT) document.getElementById('watch-require-' + idx + '-target-type').value = initTT;
|
|
@@ -655,7 +655,7 @@ function _updateWatchConditionOptions() {
|
|
|
655
655
|
|
|
656
656
|
function _renderCreateWatchModal() {
|
|
657
657
|
document.getElementById('modal-title').innerHTML = 'Create Watch' +
|
|
658
|
-
' <button class="
|
|
658
|
+
' <button class="btn-action btn-action-lg" style="padding:2px 12px;margin-left:8px" onclick="submitWatch()">Create</button>';
|
|
659
659
|
// eslint-disable-next-line no-unsanitized/property -- reason: structural HTML is a string literal; all user data wrapped in escHtml() by _watchFormHtml() (fields: target/action registries, project names, agent ids/names)
|
|
660
660
|
document.getElementById('modal-body').innerHTML = _watchFormHtml();
|
|
661
661
|
document.getElementById('modal-body').style.whiteSpace = 'normal';
|
|
@@ -246,9 +246,9 @@ function wiRow(item) {
|
|
|
246
246
|
'<td style="white-space:nowrap">' +
|
|
247
247
|
((item.status === 'pending' || item.status === 'failed') ? '<button class="pr-pager-btn" style="font-size:var(--text-xs);padding:1px 6px;color:var(--blue);border-color:var(--blue);margin-right:4px" onclick="event.stopPropagation();editWorkItem(\'' + escapeHtml(item.id) + '\',\'' + escapeHtml(item._source || '') + '\')" title="Edit work item">✎</button>' : '') +
|
|
248
248
|
((item.status === 'done' || item.status === 'failed') ? '<button class="pr-pager-btn" style="font-size:var(--text-xs);padding:1px 6px;color:var(--muted);border-color:var(--border);margin-right:4px" onclick="event.stopPropagation();archiveWorkItem(\'' + escapeHtml(item.id) + '\',\'' + escapeHtml(item._source || '') + '\')" title="Archive work item">📦</button>' : '') +
|
|
249
|
-
((item.status === 'done' || item.status === 'failed') && !item._humanFeedback ? '<button class="
|
|
249
|
+
((item.status === 'done' || item.status === 'failed') && !item._humanFeedback ? '<button class="btn-action" style="margin-right:4px" onclick="event.stopPropagation();feedbackWorkItem(\'' + escapeHtml(item.id) + '\',\'' + escapeHtml(item._source || '') + '\')" title="Give feedback">👍👎</button>' : (item._humanFeedback ? '<span style="font-size:var(--text-xs)" title="Feedback given">' + (item._humanFeedback.rating === 'up' ? '👍' : '👎') + '</span> ' : '')) +
|
|
250
250
|
((item.status === 'pending' || item.status === 'dispatched' || item.status === 'queued' || item.status === 'failed') ? '<button class="pr-pager-btn" style="font-size:var(--text-xs);padding:1px 6px;color:var(--orange);border-color:var(--orange);margin-right:4px" onclick="event.stopPropagation();cancelWorkItem(\'' + escapeHtml(item.id) + '\',\'' + escapeHtml(item._source || '') + '\')" title="Cancel work item and kill agent">🚫</button>' : '') +
|
|
251
|
-
'<button class="
|
|
251
|
+
'<button class="btn-destructive" onclick="event.stopPropagation();deleteWorkItem(\'' + escapeHtml(item.id) + '\',\'' + escapeHtml(item._source || '') + '\')" title="Delete work item and kill agent">✕</button>' +
|
|
252
252
|
'</td>' +
|
|
253
253
|
'</tr>';
|
|
254
254
|
}
|
|
@@ -380,7 +380,7 @@ async function editWorkItem(id, source) {
|
|
|
380
380
|
'</label>' +
|
|
381
381
|
'<div style="display:flex;justify-content:flex-end;gap:8px;margin-top:8px">' +
|
|
382
382
|
'<button onclick="closeModal()" class="pr-pager-btn" style="padding:6px 16px;font-size:var(--text-md)">Cancel</button>' +
|
|
383
|
-
'<button onclick="submitWorkItemEdit(\'' + escapeHtml(id) + '\',\'' + escapeHtml(source || '') + '\',event)"
|
|
383
|
+
'<button onclick="submitWorkItemEdit(\'' + escapeHtml(id) + '\',\'' + escapeHtml(source || '') + '\',event)" class="btn-primary-lg">Save</button>' +
|
|
384
384
|
'</div>' +
|
|
385
385
|
'</div>';
|
|
386
386
|
document.getElementById('modal').classList.add('open');
|
|
@@ -601,7 +601,7 @@ function openCreateWorkItemModal() {
|
|
|
601
601
|
'<label id="wi-new-skippr-row" style="color:var(--text);font-size:var(--text-md);display:flex;gap:8px;align-items:center;cursor:pointer"><input type="checkbox" id="wi-new-skippr"> Skip PR creation (push branch only)</label>' +
|
|
602
602
|
'<div style="display:flex;justify-content:flex-end;gap:8px;margin-top:4px">' +
|
|
603
603
|
'<button onclick="closeModal()" class="pr-pager-btn">Cancel</button>' +
|
|
604
|
-
'<button onclick="_submitCreateWorkItem(event)"
|
|
604
|
+
'<button onclick="_submitCreateWorkItem(event)" class="btn-primary-lg">Create</button>' +
|
|
605
605
|
'</div>' +
|
|
606
606
|
'</div>';
|
|
607
607
|
document.getElementById('modal').classList.add('open');
|
package/dashboard/js/settings.js
CHANGED
|
@@ -488,8 +488,7 @@ async function openSettings() {
|
|
|
488
488
|
if (!document.getElementById('modal-settings-reset')) {
|
|
489
489
|
const resetBtn = document.createElement('button');
|
|
490
490
|
resetBtn.id = 'modal-settings-reset';
|
|
491
|
-
resetBtn.className = 'modal-copy';
|
|
492
|
-
resetBtn.style.cssText = 'color:var(--red);border-color:var(--red)';
|
|
491
|
+
resetBtn.className = 'modal-copy is-danger';
|
|
493
492
|
resetBtn.textContent = 'Reset';
|
|
494
493
|
resetBtn.onclick = resetSettingsToDefaults;
|
|
495
494
|
actions.insertBefore(resetBtn, actions.lastElementChild);
|
|
@@ -497,8 +496,7 @@ async function openSettings() {
|
|
|
497
496
|
if (!document.getElementById('modal-settings-save')) {
|
|
498
497
|
const saveBtn = document.createElement('button');
|
|
499
498
|
saveBtn.id = 'modal-settings-save';
|
|
500
|
-
saveBtn.className = 'modal-copy';
|
|
501
|
-
saveBtn.style.cssText = 'color:var(--green);border-color:var(--green)';
|
|
499
|
+
saveBtn.className = 'modal-copy is-success';
|
|
502
500
|
saveBtn.innerHTML = '<svg width="12" height="12" viewBox="0 0 16 16" fill="currentColor"><path d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"/></svg> Save';
|
|
503
501
|
saveBtn.onclick = saveSettings;
|
|
504
502
|
actions.insertBefore(saveBtn, actions.lastElementChild);
|
package/dashboard/layout.html
CHANGED
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
<h3 id="modal-title">—</h3>
|
|
123
123
|
<div class="modal-header-actions">
|
|
124
124
|
<button class="modal-copy" id="modal-edit-btn" onclick="modalToggleEdit()" title="Edit" style="display:none"><svg width="12" height="12" viewBox="0 0 16 16" fill="currentColor"><path d="M11.013 1.427a1.75 1.75 0 012.474 0l1.086 1.086a1.75 1.75 0 010 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 01-.927-.928l.929-3.25c.081-.286.235-.547.445-.758l8.61-8.61zM12.9 2.97L4.288 11.58l-.537 1.878 1.878-.537L14.242 4.31 12.9 2.97z"/></svg> Edit</button>
|
|
125
|
-
<button class="modal-copy" id="modal-save-btn" onclick="modalSaveEdit()" title="Save" style="display:none
|
|
125
|
+
<button class="modal-copy is-success" id="modal-save-btn" onclick="modalSaveEdit()" title="Save" style="display:none"><svg width="12" height="12" viewBox="0 0 16 16" fill="currentColor"><path d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"/></svg> Save</button>
|
|
126
126
|
<button class="modal-copy" id="modal-cancel-edit-btn" onclick="modalCancelEdit()" title="Cancel edit" style="display:none">Cancel</button>
|
|
127
127
|
<button class="modal-copy pin-btn" id="modal-pin-btn" onclick="toggleModalPin()" title="Pin to top" style="display:none">Pin</button>
|
|
128
128
|
<button class="modal-copy" id="modal-copy-btn" onclick="copyModalContent()" title="Copy to clipboard"><svg width="12" height="12" viewBox="0 0 16 16" fill="currentColor"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25z"/><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25z"/></svg> Copy</button>
|
package/dashboard/pages/qa.html
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
</ul>
|
|
16
16
|
</div>
|
|
17
17
|
<div style="display:flex;gap:var(--space-3);align-items:center;margin-top:var(--space-2)">
|
|
18
|
-
<button type="button" id="qa-cc-pitch-open" class="
|
|
18
|
+
<button type="button" id="qa-cc-pitch-open" class="btn-primary-solid" onclick="qaFocusCommandCenter()">Open Command Center →</button>
|
|
19
19
|
<a href="/state/docs/qa-runbook-lifecycle.md" target="_blank" rel="noopener" class="qa-cc-pitch-docs" style="color:var(--blue);font-size:var(--text-base)">Docs →</a>
|
|
20
20
|
</div>
|
|
21
21
|
</div>
|
package/dashboard/styles.css
CHANGED
|
@@ -488,6 +488,170 @@
|
|
|
488
488
|
.btn-add.disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
|
|
489
489
|
.btn-add.btn-add-lg { font-size: var(--text-sm); padding: 2px 8px; }
|
|
490
490
|
|
|
491
|
+
/* W-mq57qetc0009ed48 — green-bordered action button family WITHOUT a
|
|
492
|
+
leading "+" glyph (Approve / Verify / Resume / Save / Run Now /
|
|
493
|
+
Continue / Create / New Plan / Trigger Verify / etc). Sibling to
|
|
494
|
+
.btn-add — same green/surface2 visual identity, but semantically a
|
|
495
|
+
verb-action rather than a creator. Three padding+size variants cover
|
|
496
|
+
every callsite that was previously inline `style="font-size:…;
|
|
497
|
+
padding:…;color:var(--green);border-color:var(--green)"` on top of
|
|
498
|
+
.pr-pager-btn:
|
|
499
|
+
.btn-action — compact text-xs / 1px 6px (inline PRD
|
|
500
|
+
chips, work-item feedback)
|
|
501
|
+
.btn-action.btn-action-md — text-xs / 2px 8px (meetings, pipelines,
|
|
502
|
+
watches resume, schedule run-now chip)
|
|
503
|
+
.btn-action.btn-action-lg — text-sm / 2px 10px (modal Save, watch
|
|
504
|
+
Create, charter Save, schedule modal Run
|
|
505
|
+
now)
|
|
506
|
+
Positional/layout-only inline styles (e.g. margin-left:8px, margin-
|
|
507
|
+
right:4px, margin-top:6px) stay at the callsite. Do NOT re-create the
|
|
508
|
+
green inline blob — extend this primitive instead. */
|
|
509
|
+
.btn-action {
|
|
510
|
+
background: var(--surface2);
|
|
511
|
+
border: 1px solid var(--green);
|
|
512
|
+
color: var(--green);
|
|
513
|
+
font-size: var(--text-xs);
|
|
514
|
+
padding: 1px 6px;
|
|
515
|
+
border-radius: var(--radius-sm);
|
|
516
|
+
cursor: pointer;
|
|
517
|
+
transition: background var(--transition-base);
|
|
518
|
+
}
|
|
519
|
+
.btn-action:hover { background: rgba(63,185,80,0.1); }
|
|
520
|
+
.btn-action:focus-visible { outline: 2px solid var(--green); outline-offset: 1px; }
|
|
521
|
+
.btn-action:disabled,
|
|
522
|
+
.btn-action.disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
|
|
523
|
+
.btn-action.btn-action-md { padding: 2px 8px; }
|
|
524
|
+
.btn-action.btn-action-lg { font-size: var(--text-sm); padding: 2px 10px; }
|
|
525
|
+
|
|
526
|
+
/* W-mq57qetc0009ed48 — red-bordered destructive button family (Delete /
|
|
527
|
+
Abort / Remove / Unpin / unlink-x). Visual sibling to .btn-action —
|
|
528
|
+
same surface2 background, same padding scale, same hover-tint pattern,
|
|
529
|
+
just swapped to var(--red). Three size variants:
|
|
530
|
+
.btn-destructive — compact text-xs / 1px 6px (work-item
|
|
531
|
+
delete, watch delete, schedule delete,
|
|
532
|
+
unpin, unlink-x in PR row)
|
|
533
|
+
.btn-destructive.btn-destructive-md — text-xs / 2px 8px (pipelines
|
|
534
|
+
Abort + Delete)
|
|
535
|
+
.btn-destructive.btn-destructive-lg — text-sm / 2px 10px (watch
|
|
536
|
+
builder Remove step / Remove
|
|
537
|
+
requirement)
|
|
538
|
+
Positional / outlier inline overrides (padding:1px 5px on the PR
|
|
539
|
+
unlink-x chip, padding:6px 8px on the requirement-row Remove) stay
|
|
540
|
+
at the callsite. Do NOT re-create the red inline blob — extend this
|
|
541
|
+
primitive instead. */
|
|
542
|
+
.btn-destructive {
|
|
543
|
+
background: var(--surface2);
|
|
544
|
+
border: 1px solid var(--red);
|
|
545
|
+
color: var(--red);
|
|
546
|
+
font-size: var(--text-xs);
|
|
547
|
+
padding: 1px 6px;
|
|
548
|
+
border-radius: var(--radius-sm);
|
|
549
|
+
cursor: pointer;
|
|
550
|
+
transition: background var(--transition-base);
|
|
551
|
+
}
|
|
552
|
+
.btn-destructive:hover { background: rgba(248,81,73,0.1); }
|
|
553
|
+
.btn-destructive:focus-visible { outline: 2px solid var(--red); outline-offset: 1px; }
|
|
554
|
+
.btn-destructive:disabled,
|
|
555
|
+
.btn-destructive.disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
|
|
556
|
+
.btn-destructive.btn-destructive-md { padding: 2px 8px; }
|
|
557
|
+
.btn-destructive.btn-destructive-lg { font-size: var(--text-sm); padding: 2px 10px; }
|
|
558
|
+
|
|
559
|
+
/* W-mq57qetc0009ed48 — solid-blue primary CTA. Single source of truth
|
|
560
|
+
for the filled-blue rectangle that gates submission flows (QA "Start
|
|
561
|
+
QA Session", "+ New runbook", "Save" in the QA runbook editor, FRE
|
|
562
|
+
"+ Add Project"). Replaces the standalone .qa-btn-primary (now
|
|
563
|
+
removed — all callsites migrated) and the ad-hoc
|
|
564
|
+
`background:var(--blue);color:#fff;border:none;…` style blob in
|
|
565
|
+
fre.js. */
|
|
566
|
+
.btn-primary-solid {
|
|
567
|
+
background: var(--blue);
|
|
568
|
+
color: #fff;
|
|
569
|
+
border: none;
|
|
570
|
+
border-radius: var(--radius-sm);
|
|
571
|
+
padding: var(--space-3) var(--space-7);
|
|
572
|
+
font-size: var(--text-md);
|
|
573
|
+
font-weight: 600;
|
|
574
|
+
cursor: pointer;
|
|
575
|
+
transition: opacity var(--transition-base);
|
|
576
|
+
}
|
|
577
|
+
.btn-primary-solid:hover { opacity: 0.9; }
|
|
578
|
+
.btn-primary-solid:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
|
|
579
|
+
.btn-primary-solid:disabled,
|
|
580
|
+
.btn-primary-solid.disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
|
|
581
|
+
|
|
582
|
+
/* W-mq57qetc0009ed48 — solid-blue modal CTA. Lighter-weight sibling to
|
|
583
|
+
.btn-primary-solid: same filled-blue rectangle, padding:6px 16px, but
|
|
584
|
+
without the font-weight:600 used by qa/fre primary CTAs. Used for the
|
|
585
|
+
"Save" / "Create Plan" / "Re-execute" / "Save Note" buttons inside
|
|
586
|
+
dashboard modals (render-inbox, render-kb, render-plans) and the
|
|
587
|
+
"Retry" button in the agent-detail error state. Replaces the ad-hoc
|
|
588
|
+
`background:var(--blue);color:#fff;border:none;border-radius:sm;
|
|
589
|
+
padding:6px 16px` blob that was duplicated across five callsites. */
|
|
590
|
+
.btn-primary-lg {
|
|
591
|
+
background: var(--blue);
|
|
592
|
+
color: #fff;
|
|
593
|
+
border: none;
|
|
594
|
+
border-radius: var(--radius-sm);
|
|
595
|
+
padding: 6px 16px;
|
|
596
|
+
font-size: var(--text-md);
|
|
597
|
+
cursor: pointer;
|
|
598
|
+
transition: opacity var(--transition-base);
|
|
599
|
+
}
|
|
600
|
+
.btn-primary-lg:hover { opacity: 0.9; }
|
|
601
|
+
.btn-primary-lg:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
|
|
602
|
+
.btn-primary-lg:disabled,
|
|
603
|
+
.btn-primary-lg.disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
|
|
604
|
+
|
|
605
|
+
/* W-mq57qetc0009ed48 — muted ghost button. Transparent background,
|
|
606
|
+
bordered, muted text. Used for secondary actions next to a primary
|
|
607
|
+
CTA (QA Cancel / Edit / Dismiss / "− remove artifact row" / "+ Add
|
|
608
|
+
artifact"). Replaces the standalone .qa-btn-ghost (now removed —
|
|
609
|
+
all callsites migrated). */
|
|
610
|
+
.btn-ghost {
|
|
611
|
+
background: transparent;
|
|
612
|
+
color: var(--muted);
|
|
613
|
+
border: 1px solid var(--border);
|
|
614
|
+
border-radius: var(--radius-sm);
|
|
615
|
+
padding: var(--space-2) var(--space-5);
|
|
616
|
+
font-size: var(--text-base);
|
|
617
|
+
cursor: pointer;
|
|
618
|
+
transition: color var(--transition-base), background var(--transition-base);
|
|
619
|
+
}
|
|
620
|
+
.btn-ghost:hover { color: var(--text); background: var(--surface); }
|
|
621
|
+
.btn-ghost:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
|
|
622
|
+
.btn-ghost:disabled,
|
|
623
|
+
.btn-ghost.disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
|
|
624
|
+
|
|
625
|
+
/* W-mq57qetc0009ed48 — dashed empty-state chip ("+ Add Project" in
|
|
626
|
+
the projects empty-state). Same chip footprint as the project chips
|
|
627
|
+
in render-other.js, but with a dashed border + green text to read as
|
|
628
|
+
a placeholder/call-to-action. */
|
|
629
|
+
.empty-state-add {
|
|
630
|
+
display: inline-block;
|
|
631
|
+
background: var(--surface2);
|
|
632
|
+
border: 1px dashed var(--border);
|
|
633
|
+
color: var(--green);
|
|
634
|
+
font-weight: 500;
|
|
635
|
+
padding: 3px 10px;
|
|
636
|
+
border-radius: var(--radius-sm);
|
|
637
|
+
cursor: pointer;
|
|
638
|
+
transition: background var(--transition-base);
|
|
639
|
+
}
|
|
640
|
+
.empty-state-add:hover { background: rgba(63,185,80,0.1); }
|
|
641
|
+
.empty-state-add:focus-visible { outline: 2px solid var(--green); outline-offset: 1px; }
|
|
642
|
+
.empty-state-add:disabled,
|
|
643
|
+
.empty-state-add.disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
|
|
644
|
+
/* Muted variant used when the chip sits next to existing project chips
|
|
645
|
+
(so it reads as a secondary "add another" affordance rather than the
|
|
646
|
+
primary empty-state CTA). */
|
|
647
|
+
.empty-state-add.empty-state-add-muted { color: var(--muted); }
|
|
648
|
+
.empty-state-add.empty-state-add-muted:hover { background: var(--surface); }
|
|
649
|
+
/* Blue variant used for the "Scan" affordance that sits next to "+ Add
|
|
650
|
+
Project" in the projects empty-state — same dashed chip, but text-sm and
|
|
651
|
+
blue text instead of green. */
|
|
652
|
+
.empty-state-add.empty-state-add-blue { color: var(--blue); font-size: var(--text-sm); }
|
|
653
|
+
.empty-state-add.empty-state-add-blue:hover { background: rgba(88,166,255,0.1); }
|
|
654
|
+
|
|
491
655
|
/* Badge — unified badge/pill base */
|
|
492
656
|
.badge {
|
|
493
657
|
font-size: var(--text-sm); font-weight: 600;
|
|
@@ -796,6 +960,8 @@
|
|
|
796
960
|
.modal-copy { background: var(--surface2); border: 1px solid var(--border); color: var(--muted); font-size: var(--text-base); cursor: pointer; padding: var(--space-2) var(--space-5); border-radius: var(--radius-sm); display: flex; align-items: center; gap: var(--space-2); transition: all var(--transition-base); }
|
|
797
961
|
.modal-copy:hover { color: var(--text); border-color: var(--text); }
|
|
798
962
|
.modal-copy.copied { color: var(--green); border-color: var(--green); }
|
|
963
|
+
.modal-copy.is-success { color: var(--green); border-color: var(--green); }
|
|
964
|
+
.modal-copy.is-danger { color: var(--red); border-color: var(--red); }
|
|
799
965
|
.modal-close { background: none; border: none; color: var(--muted); font-size: var(--text-2xl); cursor: pointer; padding: var(--space-2) var(--space-4); }
|
|
800
966
|
.modal-close:hover { color: var(--text); }
|
|
801
967
|
|
|
@@ -1019,20 +1185,10 @@
|
|
|
1019
1185
|
.qa-add-artifact-btn { align-self: flex-start; margin-top: var(--space-2); }
|
|
1020
1186
|
.qa-form-actions { flex-direction: row; align-items: center; gap: var(--space-4); }
|
|
1021
1187
|
.qa-form-msg { font-size: var(--text-base); margin-left: var(--space-3); }
|
|
1022
|
-
.qa-btn-primary
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
}
|
|
1027
|
-
.qa-btn-primary:hover { opacity: 0.9; }
|
|
1028
|
-
.qa-btn-primary:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
1029
|
-
.qa-btn-ghost {
|
|
1030
|
-
background: transparent; color: var(--muted);
|
|
1031
|
-
border: 1px solid var(--border); border-radius: var(--radius-sm);
|
|
1032
|
-
padding: var(--space-2) var(--space-5); font-size: var(--text-base);
|
|
1033
|
-
cursor: pointer;
|
|
1034
|
-
}
|
|
1035
|
-
.qa-btn-ghost:hover { color: var(--text); background: var(--surface); }
|
|
1188
|
+
/* .qa-btn-primary and .qa-btn-ghost were removed in W-mq57qetc0009ed48
|
|
1189
|
+
(PR #80 follow-up). All callsites migrated to the shared .btn-primary-solid
|
|
1190
|
+
and .btn-ghost primitives defined near .btn-add. .qa-btn-danger is kept
|
|
1191
|
+
as a color-only modifier composable with .btn-ghost. */
|
|
1036
1192
|
|
|
1037
1193
|
.qa-runbooks-list { display: flex; flex-direction: column; gap: var(--space-3); }
|
|
1038
1194
|
.qa-runbook-row {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2159",
|
|
4
4
|
"description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
|
|
5
5
|
"bin": {
|
|
6
6
|
"minions": "bin/minions.js"
|