mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-06-12 11:13:11 +08:00
feat: add dynamic workflow team orchestration surface
Adds dynamic workflow/team orchestration skills, the content pack, and control-pane work-item/Kanban state DB support. Includes reviewer hardening for state-db CLI validation, optional state DB failure handling, and mergeStateStatus projection.
This commit is contained in:
@@ -215,6 +215,7 @@ function renderControlPaneHtml() {
|
||||
|
||||
.result,
|
||||
.connector,
|
||||
.work-item,
|
||||
.action {
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(52, 64, 56, 0.7);
|
||||
@@ -224,10 +225,42 @@ function renderControlPaneHtml() {
|
||||
|
||||
.result:last-child,
|
||||
.connector:last-child,
|
||||
.work-item:last-child,
|
||||
.action:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.kanban {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(52, 64, 56, 0.7);
|
||||
}
|
||||
|
||||
.kanban-lane {
|
||||
min-width: 0;
|
||||
padding: 9px;
|
||||
border: 1px solid rgba(52, 64, 56, 0.8);
|
||||
border-radius: 6px;
|
||||
background: #141917;
|
||||
}
|
||||
|
||||
.kanban-lane span {
|
||||
display: block;
|
||||
color: var(--muted);
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.kanban-lane strong {
|
||||
display: block;
|
||||
margin-top: 6px;
|
||||
font-size: 20px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -310,6 +343,7 @@ function renderControlPaneHtml() {
|
||||
@media (max-width: 560px) {
|
||||
main { padding: 12px; }
|
||||
.metrics { grid-template-columns: 1fr; }
|
||||
.kanban { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
||||
.query { flex-direction: column; }
|
||||
th:nth-child(4), td:nth-child(4) { display: none; }
|
||||
}
|
||||
@@ -338,6 +372,13 @@ function renderControlPaneHtml() {
|
||||
</div>
|
||||
<div id="sessions"></div>
|
||||
</section>
|
||||
<section>
|
||||
<div class="section-head">
|
||||
<h2>Work Items</h2>
|
||||
<span class="subtle" id="work-item-count"></span>
|
||||
</div>
|
||||
<div id="work-items"></div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="stack">
|
||||
<section>
|
||||
@@ -413,7 +454,13 @@ function renderControlPaneHtml() {
|
||||
|
||||
function statePill(stateName) {
|
||||
const state = String(stateName || 'unknown');
|
||||
const klass = state === 'running' ? 'good' : state === 'failed' ? 'bad' : state === 'pending' ? 'warn' : 'blue';
|
||||
const klass = ['running', 'done'].includes(state)
|
||||
? 'good'
|
||||
: ['failed', 'blocked'].includes(state)
|
||||
? 'bad'
|
||||
: ['pending', 'ready'].includes(state)
|
||||
? 'warn'
|
||||
: 'blue';
|
||||
return '<span class="pill ' + klass + '">' + escapeHtml(state) + '</span>';
|
||||
}
|
||||
|
||||
@@ -446,6 +493,37 @@ function renderControlPaneHtml() {
|
||||
'</tbody></table>';
|
||||
}
|
||||
|
||||
function renderWorkItems(workItems) {
|
||||
const summary = workItems || { totalCount: 0, openCount: 0, blockedCount: 0, doneCount: 0, kanban: {}, items: [] };
|
||||
const items = Array.isArray(summary.items) ? summary.items : [];
|
||||
const kanban = summary.kanban || {};
|
||||
$('#work-item-count').textContent = summary.openCount + ' open / ' + summary.blockedCount + ' blocked';
|
||||
|
||||
const lanes = ['ready', 'running', 'blocked', 'done'];
|
||||
const laneHtml = '<div class="kanban">' + lanes.map(lane =>
|
||||
'<div class="kanban-lane"><span>' + escapeHtml(lane) + '</span><strong>' + escapeHtml(kanban[lane] || 0) + '</strong></div>'
|
||||
).join('') + '</div>';
|
||||
|
||||
if (!items.length) {
|
||||
$('#work-items').innerHTML = laneHtml + '<div class="empty">No agent work items found.</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
$('#work-items').innerHTML = laneHtml + items.slice(0, 8).map(item => {
|
||||
const branch = item.branch || (item.metadata && item.metadata.branch) || '';
|
||||
const mergeGate = item.mergeGate || (item.metadata && item.metadata.mergeGate) || '';
|
||||
const blocker = item.blocker || (item.metadata && item.metadata.blocker) || '';
|
||||
const owner = item.owner || item.source || 'unassigned';
|
||||
return '<div class="work-item">' +
|
||||
'<div class="row"><strong>' + escapeHtml(item.title || item.id) + '</strong>' + statePill(item.kanbanState || item.status) + '</div>' +
|
||||
'<div class="subtle">' + escapeHtml(owner) + ' - ' + escapeHtml(item.source || 'manual') + (item.priority ? ' - ' + escapeHtml(item.priority) : '') + '</div>' +
|
||||
(branch ? '<div class="subtle">branch: ' + escapeHtml(branch) + '</div>' : '') +
|
||||
(mergeGate ? '<div class="subtle">merge gate: ' + escapeHtml(mergeGate) + '</div>' : '') +
|
||||
(blocker ? '<div class="subtle">blocker: ' + escapeHtml(blocker) + '</div>' : '') +
|
||||
'</div>';
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function renderKnowledge(knowledge) {
|
||||
$('#knowledge-count').textContent = knowledge.entityCount + ' entities';
|
||||
if (!knowledge.results.length) {
|
||||
@@ -526,6 +604,7 @@ function renderControlPaneHtml() {
|
||||
$('#action-status').textContent = snapshot.execution.allowActions ? 'local allowlist' : 'read-only';
|
||||
renderMetrics(snapshot.summary);
|
||||
renderSessions(snapshot.sessions);
|
||||
renderWorkItems(snapshot.workItems);
|
||||
renderKnowledge(snapshot.knowledge);
|
||||
renderConnectors(snapshot.connectors);
|
||||
renderActions(snapshot.actions.map(action => ({
|
||||
|
||||
Reference in New Issue
Block a user