@yemi33/minions 0.1.33 → 0.1.35
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/CHANGELOG.md +11 -0
- package/dashboard/js/render-work-items.js +115 -1
- package/dashboard/pages/work.html +5 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.35 (2026-03-28)
|
|
4
|
+
|
|
5
|
+
### Dashboard
|
|
6
|
+
- dashboard/js/render-work-items.js
|
|
7
|
+
|
|
8
|
+
## 0.1.34 (2026-03-28)
|
|
9
|
+
|
|
10
|
+
### Dashboard
|
|
11
|
+
- dashboard/js/render-work-items.js
|
|
12
|
+
- dashboard/pages/work.html
|
|
13
|
+
|
|
3
14
|
## 0.1.33 (2026-03-28)
|
|
4
15
|
|
|
5
16
|
### Dashboard
|
|
@@ -14,7 +14,7 @@ function wiRow(item) {
|
|
|
14
14
|
const prLink = item._pr
|
|
15
15
|
? '<a class="pr-title" href="' + escHtml(item._prUrl || '#') + '" target="_blank" style="font-size:10px">' + escHtml(item._pr) + '</a>'
|
|
16
16
|
: '<span style="color:var(--muted)">—</span>';
|
|
17
|
-
return '<tr>' +
|
|
17
|
+
return '<tr style="cursor:pointer" onclick="openWorkItemDetail(\'' + escHtml(item.id) + '\')">' +
|
|
18
18
|
'<td><span class="pr-id">' + escHtml(item.id || '') + '</span></td>' +
|
|
19
19
|
'<td style="max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap" title="' + escHtml(item.description || item.title || '') + '">' + escHtml(item.title || '') + '</td>' +
|
|
20
20
|
'<td><span style="font-size:10px;color:var(--muted)">' + escHtml(item._source || '') + '</span>' +
|
|
@@ -273,6 +273,120 @@ async function submitFeedback(id, source) {
|
|
|
273
273
|
} catch (e) { alert('Error: ' + e.message); }
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
+
function openCreateWorkItemModal() {
|
|
277
|
+
const typeOpts = ['implement', 'fix', 'explore', 'test', 'review', 'ask', 'plan'].map(t =>
|
|
278
|
+
'<option value="' + t + '"' + (t === 'implement' ? ' selected' : '') + '>' + t + '</option>'
|
|
279
|
+
).join('');
|
|
280
|
+
const priOpts = ['high', 'medium', 'low'].map(p =>
|
|
281
|
+
'<option value="' + p + '"' + (p === 'medium' ? ' selected' : '') + '>' + p + '</option>'
|
|
282
|
+
).join('');
|
|
283
|
+
const agentOpts = (typeof cmdAgents !== 'undefined' ? cmdAgents : []).map(a =>
|
|
284
|
+
'<option value="' + escHtml(a.id) + '">' + escHtml(a.name) + '</option>'
|
|
285
|
+
).join('');
|
|
286
|
+
const projOpts = (typeof cmdProjects !== 'undefined' ? cmdProjects : []).map(p =>
|
|
287
|
+
'<option value="' + escHtml(p) + '">' + escHtml(p) + '</option>'
|
|
288
|
+
).join('');
|
|
289
|
+
const inputStyle = '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);font-family:inherit';
|
|
290
|
+
|
|
291
|
+
document.getElementById('modal-title').textContent = 'Create Work Item';
|
|
292
|
+
document.getElementById('modal-body').innerHTML =
|
|
293
|
+
'<div style="display:flex;flex-direction:column;gap:10px">' +
|
|
294
|
+
'<label style="color:var(--text);font-size:var(--text-md)">Title <input id="wi-new-title" style="' + inputStyle + '" placeholder="What needs to be done?"></label>' +
|
|
295
|
+
'<label style="color:var(--text);font-size:var(--text-md)">Description <textarea id="wi-new-desc" rows="3" style="' + inputStyle + ';resize:vertical" placeholder="Detailed description..."></textarea></label>' +
|
|
296
|
+
'<div style="display:flex;gap:8px">' +
|
|
297
|
+
'<label style="flex:1;color:var(--text);font-size:var(--text-md)">Type <select id="wi-new-type" style="' + inputStyle + '">' + typeOpts + '</select></label>' +
|
|
298
|
+
'<label style="flex:1;color:var(--text);font-size:var(--text-md)">Priority <select id="wi-new-priority" style="' + inputStyle + '">' + priOpts + '</select></label>' +
|
|
299
|
+
'</div>' +
|
|
300
|
+
'<div style="display:flex;gap:8px">' +
|
|
301
|
+
'<label style="flex:1;color:var(--text);font-size:var(--text-md)">Agent <select id="wi-new-agent" style="' + inputStyle + '"><option value="">Auto</option>' + agentOpts + '</select></label>' +
|
|
302
|
+
'<label style="flex:1;color:var(--text);font-size:var(--text-md)">Project <select id="wi-new-project" style="' + inputStyle + '"><option value="">Central</option>' + projOpts + '</select></label>' +
|
|
303
|
+
'</div>' +
|
|
304
|
+
'<label style="color:var(--text);font-size:var(--text-md)">Acceptance Criteria <textarea id="wi-new-ac" rows="2" style="' + inputStyle + ';resize:vertical" placeholder="One criterion per line (optional)"></textarea></label>' +
|
|
305
|
+
'<label style="color:var(--text);font-size:var(--text-md)">References <textarea id="wi-new-refs" rows="2" style="' + inputStyle + ';resize:vertical" placeholder="url | title | type — one per line (optional)"></textarea></label>' +
|
|
306
|
+
'<div style="display:flex;justify-content:flex-end;gap:8px;margin-top:4px">' +
|
|
307
|
+
'<button onclick="closeModal()" class="pr-pager-btn">Cancel</button>' +
|
|
308
|
+
'<button onclick="_submitCreateWorkItem()" style="padding:6px 16px;background:var(--blue);color:#fff;border:none;border-radius:var(--radius-sm);cursor:pointer">Create</button>' +
|
|
309
|
+
'</div>' +
|
|
310
|
+
'</div>';
|
|
311
|
+
document.getElementById('modal').classList.add('open');
|
|
312
|
+
setTimeout(() => document.getElementById('wi-new-title')?.focus(), 100);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
async function _submitCreateWorkItem() {
|
|
316
|
+
const title = document.getElementById('wi-new-title')?.value?.trim();
|
|
317
|
+
if (!title) { alert('Title is required'); return; }
|
|
318
|
+
const desc = document.getElementById('wi-new-desc')?.value || '';
|
|
319
|
+
const type = document.getElementById('wi-new-type')?.value || 'implement';
|
|
320
|
+
const priority = document.getElementById('wi-new-priority')?.value || 'medium';
|
|
321
|
+
const agent = document.getElementById('wi-new-agent')?.value || '';
|
|
322
|
+
const project = document.getElementById('wi-new-project')?.value || '';
|
|
323
|
+
const acRaw = document.getElementById('wi-new-ac')?.value || '';
|
|
324
|
+
const acceptanceCriteria = acRaw.split('\n').map(l => l.trim()).filter(Boolean);
|
|
325
|
+
const refsRaw = document.getElementById('wi-new-refs')?.value || '';
|
|
326
|
+
const references = refsRaw.split('\n').filter(l => l.trim()).map(l => {
|
|
327
|
+
const parts = l.split('|').map(s => s.trim());
|
|
328
|
+
return { url: parts[0], title: parts[1] || parts[0], type: parts[2] || 'link' };
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
try {
|
|
332
|
+
const body = { title, description: desc, type, priority };
|
|
333
|
+
if (agent) body.agents = [agent];
|
|
334
|
+
if (project) body.project = project;
|
|
335
|
+
if (acceptanceCriteria.length) body.acceptanceCriteria = acceptanceCriteria;
|
|
336
|
+
if (references.length && references[0].url) body.references = references;
|
|
337
|
+
|
|
338
|
+
const res = await fetch('/api/work-items', {
|
|
339
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
340
|
+
body: JSON.stringify(body)
|
|
341
|
+
});
|
|
342
|
+
const data = await res.json();
|
|
343
|
+
if (res.ok) {
|
|
344
|
+
try { closeModal(); } catch {}
|
|
345
|
+
wakeEngine();
|
|
346
|
+
refresh();
|
|
347
|
+
try { showToast('cmd-toast', 'Work item ' + (data.id || '') + ' created', true); } catch {}
|
|
348
|
+
} else {
|
|
349
|
+
alert('Failed: ' + (data.error || 'unknown'));
|
|
350
|
+
}
|
|
351
|
+
} catch (e) { alert('Error: ' + e.message); }
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function openWorkItemDetail(id) {
|
|
355
|
+
const item = allWorkItems.find(i => i.id === id);
|
|
356
|
+
if (!item) return;
|
|
357
|
+
|
|
358
|
+
const field = (label, value) => value ? '<div style="margin-bottom:8px"><span style="color:var(--muted);font-size:10px;text-transform:uppercase;letter-spacing:0.5px">' + label + '</span><div style="margin-top:2px">' + value + '</div></div>' : '';
|
|
359
|
+
const badge = (cls, text) => '<span class="pr-badge ' + cls + '">' + escHtml(text) + '</span>';
|
|
360
|
+
const statusCls = item.status === 'failed' ? 'rejected' : item.status === 'dispatched' ? 'building' : item.status === 'done' ? 'approved' : 'active';
|
|
361
|
+
|
|
362
|
+
let html = '<div style="display:flex;flex-direction:column;gap:4px;font-size:13px">';
|
|
363
|
+
html += '<div style="display:flex;gap:8px;align-items:center;margin-bottom:8px">' +
|
|
364
|
+
badge(statusCls, item.status || 'pending') + ' ' +
|
|
365
|
+
'<span class="dispatch-type ' + (item.type || 'implement') + '">' + escHtml(item.type || 'implement') + '</span>' +
|
|
366
|
+
'<span class="prd-item-priority ' + (item.priority || '') + '">' + escHtml(item.priority || 'medium') + '</span>' +
|
|
367
|
+
'</div>';
|
|
368
|
+
html += field('Description', '<div style="white-space:pre-wrap;font-size:12px">' + escHtml(item.description || item.title || '—') + '</div>');
|
|
369
|
+
html += field('Agent', escHtml(item.dispatched_to || item.agent || 'Auto'));
|
|
370
|
+
html += field('Source', escHtml(item._source || 'central'));
|
|
371
|
+
if (item.created) html += field('Created', escHtml(new Date(item.created).toLocaleString()));
|
|
372
|
+
if (item.dispatched_at) html += field('Dispatched', escHtml(new Date(item.dispatched_at).toLocaleString()) + ' to ' + escHtml(item.dispatched_to || '?'));
|
|
373
|
+
if (item.completedAt) html += field('Completed', escHtml(new Date(item.completedAt).toLocaleString()));
|
|
374
|
+
if (item.failReason) html += field('Failure Reason', '<span style="color:var(--red)">' + escHtml(item.failReason) + '</span>');
|
|
375
|
+
if (item._pendingReason) html += field('Pending Reason', escHtml(item._pendingReason.replace(/_/g, ' ')));
|
|
376
|
+
if (item.depends_on?.length) html += field('Depends On', item.depends_on.map(d => '<code>' + escHtml(d) + '</code>').join(', '));
|
|
377
|
+
if (item.acceptanceCriteria?.length) html += field('Acceptance Criteria', '<ul style="margin:0;padding-left:20px">' + item.acceptanceCriteria.map(c => '<li>' + escHtml(c) + '</li>').join('') + '</ul>');
|
|
378
|
+
if (item.references?.length) html += field('References', item.references.map(r => '<a href="' + escHtml(r.url) + '" target="_blank" style="color:var(--blue)">' + escHtml(r.title || r.url) + '</a>' + (r.type ? ' <span style="color:var(--muted);font-size:10px">(' + escHtml(r.type) + ')</span>' : '')).join('<br>'));
|
|
379
|
+
if (item._humanFeedback) html += field('Human Feedback', (item._humanFeedback.rating === 'up' ? '👍' : '👎') + (item._humanFeedback.comment ? ' — ' + escHtml(item._humanFeedback.comment) : ''));
|
|
380
|
+
if (item._pr) html += field('Pull Request', '<a href="' + escHtml(item._prUrl || '#') + '" target="_blank" style="color:var(--blue)">' + escHtml(item._pr) + '</a>');
|
|
381
|
+
html += '</div>';
|
|
382
|
+
|
|
383
|
+
document.getElementById('modal-title').textContent = item.title || item.id;
|
|
384
|
+
document.getElementById('modal-body').innerHTML = html;
|
|
385
|
+
document.getElementById('modal-body').style.fontFamily = "'Segoe UI', system-ui, sans-serif";
|
|
386
|
+
document.getElementById('modal-body').style.whiteSpace = 'normal';
|
|
387
|
+
document.getElementById('modal').classList.add('open');
|
|
388
|
+
}
|
|
389
|
+
|
|
276
390
|
function openAllWorkItems() {
|
|
277
391
|
document.getElementById('modal-title').textContent = 'All Work Items (' + allWorkItems.length + ')';
|
|
278
392
|
const html = '<div class="pr-table-wrap"><table class="pr-table"><thead><tr><th>ID</th><th>Title</th><th>Source</th><th>Type</th><th>Priority</th><th>Status</th><th>Agent</th><th>PR</th><th>Created</th><th></th><th></th></tr></thead><tbody>' +
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
<section id="work-items-section" style="overflow:visible">
|
|
2
|
-
<h2>Work Items <span class="count" id="wi-count">0</span>
|
|
3
|
-
|
|
2
|
+
<h2>Work Items <span class="count" id="wi-count">0</span>
|
|
3
|
+
<button class="pr-pager-btn" style="font-size:9px;padding:1px 6px;color:var(--green);border-color:var(--green);margin-left:8px" onclick="openCreateWorkItemModal()">+ New</button>
|
|
4
|
+
<button class="pr-pager-btn" style="font-size:9px;padding:2px 8px;margin-left:4px" onclick="toggleWorkItemArchive()">See Archive</button>
|
|
5
|
+
</h2>
|
|
6
|
+
<div id="work-items-content"><p class="empty">No work items yet.</p></div>
|
|
4
7
|
<div id="work-items-archive" style="display:none;margin-top:12px"></div>
|
|
5
8
|
</section>
|
package/package.json
CHANGED