mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-05 15:09:42 +02:00
feat(ultracode): master-detail tab for Workflow/ultracode run visualization
Opt-in (showUltracodeAgents, default OFF) panel that visualizes ultracode / Workflow-tool runs like Claude Code's "working agents" TUI: LEFT = runs + phases (selectable tasks), RIGHT = each run's agents with model, live state, tokens burned, and tool calls. Standalone — ZERO edits to subagent-watcher.ts. A new workflow-run-watcher.ts singleton globs the run-state tree (~/.claude/projects/*/*/workflows/wf_*.json, disjoint from the transcript tree), strips the heavy script/scriptPath/result/logs fields (174KB -> ~25KB/run), and emits workflow:run_* SSE events. The LEFT list ships lightweight summaries (getLightState replay + SSE); the RIGHT pane fetches the full run (with agents[]) via GET /api/workflows/:runId on selection. Backend: workflow-run-watcher.ts, types/workflow-run.ts, config/workflow-config.ts, 3 SSE events, getLightState workflowRuns replay, GET /api/workflows[/:runId], showUltracodeAgents schema key + boot-gate (default OFF) + live toggleService. Frontend: ultracode-panel.js (debounced master-detail render, run/phase select), header launcher (btn-ultracode-agents--hidden marker -> mobile-guard-exempt), App Settings toggle (SYNCED, deliberately not in displayKeys). Agent states on disk are start|progress|done (start=queued; done has durationMs/resultPreview). Tests: workflow-run-watcher (9), workflow-routes (3). Verified: tsc/lint/prettier/frontend-syntax/public-assets/mobile-header-guard clean; full test:ci green (2986 passed); live server + Playwright e2e against 25 real runs (28-agent grid, phase filter, OFF hides launcher). Design: docs/ultracode-agent-viz-plan.md (rev. 3). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8355,6 +8355,200 @@ kbd {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* "Ultracode Agents" header launcher — opt-in (App Settings → Display), hidden by
|
||||
default everywhere (so the mobile-header-buttons-policy guard auto-excludes it).
|
||||
Base inline-flex !important + a more-specific marker rule to hide. */
|
||||
.btn-ultracode-agents {
|
||||
display: inline-flex !important;
|
||||
}
|
||||
.btn-ultracode-agents.btn-ultracode-agents--hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* ===== Ultracode / Workflow agents master-detail panel ===== */
|
||||
/* Reuses .subagents-panel dock behavior but anchors LEFT so it never overlaps the
|
||||
bottom-right subagents panel when both are open. */
|
||||
.ultracode-agents-panel {
|
||||
right: auto;
|
||||
left: 0.5rem;
|
||||
width: 640px;
|
||||
}
|
||||
@media (max-width: 700px) {
|
||||
.ultracode-agents-panel {
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* LEFT pane: run rows */
|
||||
.ultracode-run-item {
|
||||
padding: 0.45rem 0.5rem;
|
||||
border-radius: 6px;
|
||||
background: var(--bg-input);
|
||||
margin-bottom: 0.4rem;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s;
|
||||
}
|
||||
.ultracode-run-item:hover {
|
||||
background: var(--bg-card);
|
||||
}
|
||||
.ultracode-run-item.selected {
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--accent);
|
||||
}
|
||||
.ultracode-run-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
.ultracode-run-name {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.ultracode-run-stats {
|
||||
font-size: 0.65rem;
|
||||
color: var(--text-dim);
|
||||
}
|
||||
.ultracode-status {
|
||||
font-size: 0.58rem;
|
||||
padding: 0.05rem 0.3rem;
|
||||
border-radius: 4px;
|
||||
margin-left: auto;
|
||||
text-transform: lowercase;
|
||||
background: var(--text-muted);
|
||||
color: white;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.ultracode-status.completed {
|
||||
background: var(--success);
|
||||
}
|
||||
.ultracode-status.active {
|
||||
background: var(--warning);
|
||||
color: black;
|
||||
}
|
||||
.ultracode-status.failed {
|
||||
background: var(--error, #b3261e);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* LEFT pane: phase chips for the selected run */
|
||||
.ultracode-phase-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.25rem;
|
||||
margin-top: 0.4rem;
|
||||
}
|
||||
.ultracode-phase-chip {
|
||||
font-size: 0.62rem;
|
||||
padding: 0.1rem 0.4rem;
|
||||
border-radius: 10px;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text-muted);
|
||||
cursor: pointer;
|
||||
}
|
||||
.ultracode-phase-chip:hover {
|
||||
color: var(--text);
|
||||
}
|
||||
.ultracode-phase-chip.selected {
|
||||
background: var(--accent);
|
||||
border-color: var(--accent);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* RIGHT pane: per-phase header + agent cards */
|
||||
.ultracode-phase-header {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
margin: 0.5rem 0 0.3rem;
|
||||
padding-bottom: 0.2rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.ultracode-phase-sub {
|
||||
font-size: 0.62rem;
|
||||
font-weight: 400;
|
||||
color: var(--text-dim);
|
||||
}
|
||||
.ultracode-agent-card {
|
||||
background: var(--bg-input);
|
||||
border-radius: 6px;
|
||||
padding: 0.4rem 0.5rem;
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
.ultracode-agent-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.ultracode-agent-label {
|
||||
font-size: 0.72rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
font-family: var(--font-mono);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.ultracode-agent-state {
|
||||
font-size: 0.56rem;
|
||||
padding: 0.05rem 0.3rem;
|
||||
border-radius: 4px;
|
||||
margin-left: auto;
|
||||
flex-shrink: 0;
|
||||
background: var(--text-muted);
|
||||
color: white;
|
||||
}
|
||||
.ultracode-agent-state.completed {
|
||||
background: var(--success);
|
||||
}
|
||||
.ultracode-agent-state.active {
|
||||
background: var(--warning);
|
||||
color: black;
|
||||
}
|
||||
.ultracode-agent-state.idle {
|
||||
background: var(--bg-card);
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.ultracode-agent-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.3rem;
|
||||
}
|
||||
.ultracode-chip {
|
||||
font-size: 0.62rem;
|
||||
padding: 0.05rem 0.35rem;
|
||||
border-radius: 4px;
|
||||
background: var(--bg-card);
|
||||
color: var(--text-muted);
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
.ultracode-chip-tok {
|
||||
color: var(--accent);
|
||||
}
|
||||
.ultracode-chip-tool {
|
||||
color: var(--text);
|
||||
}
|
||||
.ultracode-agent-sub {
|
||||
font-size: 0.62rem;
|
||||
color: var(--text-dim);
|
||||
margin-top: 0.25rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Plan-usage chip (App Settings → Display → "Plan Usage Limits"). Shows the
|
||||
live 5-hour + weekly plan limits parsed from the Claude statusline. Hidden by
|
||||
default via the marker class below; the server strips it at render when the
|
||||
|
||||
Reference in New Issue
Block a user