agent-teams-dashboard 0.3.0 → 0.3.1
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.
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--bg-primary: #1a1a2e;--bg-secondary: #16213e;--bg-sidebar: #0f0f1a;--bg-sidebar-2: #111122;--bg-card: #16213e;--bg-hover: #1f2b47;--bg-active: #253350;--border-primary: #2a2a3e;--border-subtle: #222236;--text-primary: #e0e0e0;--text-secondary: #aaa;--text-muted: #777;--accent-blue: #58a6ff;--accent-green: #00ff88;--accent-yellow: #ffd700;--accent-red: #ff4444;--accent-purple: #bc8cff;--accent-cyan: #00d4ff;--font-mono: "JetBrains Mono", "Fira Code", Consolas, monospace;--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;--radius-sm: 4px;--radius-md: 6px;--radius-lg: 8px;--transition-fast: .15s ease}*,*:before,*:after{margin:0;padding:0;box-sizing:border-box}body{font-family:var(--font-mono);font-size:14px;line-height:1.5;color:var(--text-primary);background:var(--bg-primary);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.app-container{display:flex;height:100vh;overflow:hidden}.resize-handle{width:4px;cursor:col-resize;background:transparent;flex-shrink:0;position:relative;z-index:10;transition:background var(--transition-fast)}.resize-handle:hover,.resize-handle:active{background:var(--accent-cyan)}.teams-panel{background:var(--bg-sidebar);display:flex;flex-direction:column;overflow:hidden;flex-shrink:0}.teams-panel__header{padding:14px 12px;border-bottom:1px solid var(--border-primary)}.teams-panel__title{font-size:13px;font-weight:700;color:var(--text-primary);letter-spacing:.04em;text-transform:uppercase}.teams-panel__conn-dot{font-size:10px}.sidebar-mode-toggle{display:flex;background:var(--bg-secondary);border:1px solid var(--border-primary);border-radius:var(--radius-md);padding:2px;gap:2px}.sidebar-mode-toggle__btn{padding:4px 10px;border:none;background:transparent;color:var(--text-muted);font-family:var(--font-mono);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;cursor:pointer;border-radius:var(--radius-sm);transition:all var(--transition-fast);line-height:1}.sidebar-mode-toggle__btn:hover{color:var(--text-primary);background:var(--bg-hover)}.sidebar-mode-toggle__btn--active{background:var(--bg-active);color:var(--accent-cyan);box-shadow:0 0 0 1px #00d4ff4d}.teams-panel__nav{flex:1;overflow-y:auto;padding:6px}.teams-panel__nav-item{display:flex;align-items:center;gap:8px;width:100%;padding:8px 10px;border:none;background:transparent;color:var(--text-secondary);font-family:var(--font-mono);font-size:12px;cursor:pointer;border-radius:var(--radius-sm);transition:all var(--transition-fast);text-align:left}.teams-panel__nav-item:hover{background:var(--bg-hover);color:var(--text-primary)}.teams-panel__nav-item--active{background:var(--bg-active);color:var(--accent-cyan)}.teams-panel__nav-icon{font-size:14px}.teams-panel__divider{height:1px;background:var(--border-subtle);margin:6px 4px}.teams-panel__team{display:flex;flex-direction:column;gap:3px;width:100%;padding:8px 10px;margin-bottom:2px;border:none;background:transparent;color:var(--text-primary);font-family:var(--font-mono);font-size:14px;cursor:pointer;border-radius:var(--radius-sm);border-left:3px solid transparent;transition:all var(--transition-fast);text-align:left}.teams-panel__team:hover{background:var(--bg-hover)}.teams-panel__team--active{background:var(--bg-active);border-left-color:var(--accent-cyan)}.teams-panel__team-row{display:flex;align-items:center;gap:6px}.teams-panel__team-dot{font-size:10px;flex-shrink:0;line-height:1}.teams-panel__team-name{flex:1;min-width:0}.teams-panel__team-progress{display:flex;align-items:center;gap:6px;padding-left:16px}.teams-panel__team-bar{flex:1;height:3px;background:var(--border-primary);border-radius:2px;overflow:hidden}.teams-panel__team-bar-fill{height:100%;background:var(--accent-green);border-radius:2px;transition:width .3s ease}.teams-panel__team-pct{flex-shrink:0;white-space:nowrap}.teams-panel__footer{padding:10px 12px;border-top:1px solid var(--border-primary)}.teams-panel__footer-stats{display:flex;gap:10px}.agents-panel{background:var(--bg-sidebar-2);display:flex;flex-direction:column;overflow:hidden;flex-shrink:0}.agents-panel__header{padding:14px 12px;border-bottom:1px solid var(--border-primary);display:flex;align-items:center;justify-content:space-between;gap:8px}.agents-panel__title{font-size:13px;font-weight:700;color:var(--text-primary);min-width:0}.agents-panel__task-summary{flex-shrink:0;white-space:nowrap}.agents-panel__empty{flex:1;display:flex;align-items:center;justify-content:center}.agents-panel__actions{padding:8px;border-bottom:1px solid var(--border-subtle)}.agents-panel__tasks-btn{display:flex;align-items:center;gap:6px;width:100%;padding:6px 10px;border:1px solid var(--border-primary);background:transparent;color:var(--text-secondary);font-family:var(--font-mono);font-size:12px;cursor:pointer;border-radius:var(--radius-sm);transition:all var(--transition-fast)}.agents-panel__tasks-btn:hover{background:var(--bg-hover);color:var(--text-primary);border-color:var(--text-muted)}.agents-panel__tasks-btn--active{background:var(--bg-active);color:var(--accent-cyan);border-color:var(--accent-cyan)}.agents-panel__list{flex:1;overflow-y:auto;padding:6px}.agents-panel__agent{margin-bottom:2px}.agents-panel__agent-btn{display:flex;align-items:center;gap:6px;width:100%;padding:7px 10px;border:none;background:transparent;color:var(--text-primary);font-family:var(--font-mono);font-size:14px;cursor:pointer;border-radius:var(--radius-sm);transition:all var(--transition-fast);text-align:left;border-left:3px solid transparent}.agents-panel__agent-btn:hover{background:var(--bg-hover)}.agents-panel__agent-btn--active{background:var(--bg-active);border-left-color:var(--accent-cyan);color:var(--accent-cyan)}.agents-panel__agent-dot{font-size:10px;flex-shrink:0;line-height:1}.agents-panel__agent-name{flex:1;min-width:0}.agents-panel__agent-type{flex-shrink:0}.agents-panel__agent-meta{display:flex;align-items:center;gap:8px;padding:2px 10px 4px 26px}.agents-panel__session-toggle{border:none;background:transparent;color:var(--text-muted);font-family:var(--font-mono);font-size:13px;cursor:pointer;padding:0;transition:color var(--transition-fast)}.agents-panel__session-toggle:hover{color:var(--text-secondary)}.agents-panel__sessions{padding:2px 10px 6px 26px}.agents-panel__session-id{font-size:13px;color:var(--accent-purple);font-family:var(--font-mono)}.agents-panel__session-time{font-size:13px;color:var(--text-muted)}.agents-panel__session-count{font-size:12px;color:var(--text-muted);background:var(--bg-hover);padding:0 4px;border-radius:3px}.main-panel{flex:1;overflow:hidden;display:flex;flex-direction:column}.main-panel>.overview-grid,.main-panel>.task-board__columns,.main-panel--padded{padding:16px;overflow-y:auto}.placeholder{display:flex;align-items:center;justify-content:center;height:100%;color:var(--text-muted);font-size:14px}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border-primary);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--text-muted)}*{scrollbar-width:thin;scrollbar-color:var(--border-primary) transparent}.text-primary{color:var(--text-primary)}.text-secondary{color:var(--text-secondary)}.text-muted{color:var(--text-muted)}.text-blue{color:var(--accent-blue)}.text-green{color:var(--accent-green)}.text-yellow{color:var(--accent-yellow)}.text-red{color:var(--accent-red)}.text-purple{color:var(--accent-purple)}.text-cyan{color:var(--accent-cyan)}.bg-card{background:var(--bg-card)}.bg-hover{background:var(--bg-hover)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-md{border-radius:var(--radius-md)}.rounded-lg{border-radius:var(--radius-lg)}.flex{display:flex}.flex-col{flex-direction:column}.flex-1{flex:1}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-1{gap:4px}.gap-2{gap:8px}.gap-3{gap:12px}.gap-4{gap:16px}.p-1{padding:4px}.p-2{padding:8px}.p-3{padding:12px}.p-4{padding:16px}.px-2{padding-left:8px;padding-right:8px}.px-3{padding-left:12px;padding-right:12px}.py-1{padding-top:4px;padding-bottom:4px}.py-2{padding-top:8px;padding-bottom:8px}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.font-bold{font-weight:600}.text-sm{font-size:14px}.text-xs{font-size:13px}.border{border:1px solid var(--border-primary)}.border-b{border-bottom:1px solid var(--border-primary)}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;user-select:none}.transition{transition:all var(--transition-fast)}.panel-title{font-size:16px;font-weight:600;color:var(--text-primary);margin-bottom:16px}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;text-align:center}.empty-state__icon{font-size:48px}.empty-state__title{font-size:16px;font-weight:600;color:var(--text-secondary)}.empty-state__text{max-width:400px;line-height:1.6}.overview-panel{padding:16px;overflow-y:auto;height:100%}.overview-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:12px}.overview-card{background:var(--bg-card);border:1px solid var(--border-primary);border-left:3px solid var(--text-muted);border-radius:var(--radius-md);padding:16px;transition:all var(--transition-fast)}.overview-card:hover{border-color:var(--accent-cyan);border-left-color:inherit;background:var(--bg-hover)}.overview-card--active{border-left-color:var(--accent-green)}.overview-card--idle{border-left-color:var(--accent-yellow)}.overview-card--done{border-left-color:var(--accent-cyan)}.overview-card--inactive{border-left-color:var(--text-muted)}.overview-card__header{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}.overview-card__meta{margin-bottom:12px}.overview-card__progress{display:flex;align-items:center;gap:8px;margin-bottom:8px}.progress-bar{flex:1;height:4px;background:var(--border-primary);border-radius:2px;overflow:hidden}.progress-bar__fill{height:100%;background:var(--accent-green);border-radius:2px;transition:width .3s ease}.overview-card__footer{text-align:right}.pulse-dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--accent-green);animation:pulse 2s ease-in-out infinite;flex-shrink:0}@keyframes pulse{0%,to{opacity:1;box-shadow:0 0 #0f86}50%{opacity:.7;box-shadow:0 0 0 6px #0f80}}.task-board{padding:16px;overflow-y:auto;height:100%}.task-board__columns{display:flex;gap:12px}.task-board__column{flex:1;min-width:0}.task-board__column-header{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;margin-bottom:8px;border-bottom:2px solid var(--border-primary);font-weight:600;font-size:12px;color:var(--text-secondary)}.task-card{background:var(--bg-card);border:1px solid var(--border-primary);border-radius:var(--radius-md);padding:12px;margin-bottom:8px;border-left:3px solid var(--text-muted)}.task-card--in-progress{border-left-color:var(--accent-yellow)}.task-card--completed{border-left-color:var(--accent-green)}.task-card--pending{border-left-color:var(--text-muted)}.task-card__subject{font-size:12px;margin-bottom:4px;color:var(--text-primary)}.task-card__desc{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;margin-bottom:8px;line-height:1.4}.task-card__meta{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.task-card__owner{display:inline-block;padding:2px 6px;background:#00d4ff26;color:var(--accent-cyan);border-radius:var(--radius-sm);font-size:11px}.task-card__blocked{color:var(--accent-yellow)}.chat-panel{display:flex;flex-direction:column;height:100%;position:relative}.chat-panel__header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 16px;border-bottom:1px solid var(--border-primary);background:var(--bg-secondary);flex-shrink:0}.chat-panel__header-left{display:flex;align-items:center;gap:8px;min-width:0}.chat-panel__header-right{display:flex;align-items:center;gap:12px;flex-shrink:0}.chat-panel__agent-name{font-size:14px;font-weight:700;color:var(--accent-cyan);font-family:var(--font-mono)}.chat-panel__session-tag{font-size:11px;padding:2px 6px;background:#bc8cff26;color:var(--accent-purple);border-radius:var(--radius-sm);font-family:var(--font-mono)}.chat-panel__team{white-space:nowrap}.chat-panel__feed{flex:1;overflow-y:auto;padding:8px 0}.chat-panel__empty{display:flex;align-items:center;justify-content:center;height:100%}.chat-panel__scroll-btn{position:absolute;bottom:12px;right:16px;padding:6px 12px;background:var(--bg-active);border:1px solid var(--accent-cyan);color:var(--accent-cyan);font-family:var(--font-mono);font-size:11px;border-radius:var(--radius-sm);cursor:pointer;transition:all var(--transition-fast);z-index:10}.chat-panel__scroll-btn:hover{background:var(--bg-hover)}.chat-msg{padding:6px 16px;border-left:3px solid transparent;transition:background var(--transition-fast)}.chat-msg:hover{background:#ffffff05}.chat-msg--user{border-left-color:var(--accent-green);background:#00ff8808}.chat-msg--assistant{border-left-color:var(--accent-cyan)}.chat-msg--tool-use{border-left-color:var(--accent-yellow);background:#ffd70008}.chat-msg--tool-result{border-left-color:var(--text-secondary);background:#aaaaaa08}.chat-msg__meta{display:flex;align-items:center;gap:8px;margin-bottom:4px}.chat-msg__role{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;font-family:var(--font-mono)}.chat-msg--user .chat-msg__role{color:var(--accent-green)}.chat-msg--assistant .chat-msg__role{color:var(--accent-cyan)}.chat-msg--tool-use .chat-msg__role{color:var(--accent-yellow)}.chat-msg--tool-result .chat-msg__role{color:var(--text-secondary)}.chat-msg__time{font-size:12px;color:var(--text-secondary);font-family:var(--font-mono)}.chat-msg__body{font-size:14px;line-height:1.6;word-break:break-word}.msg-prose{color:var(--text-primary);white-space:pre-wrap}.chat-msg--assistant .msg-prose{color:var(--text-primary)}.msg-code{background:var(--bg-secondary);border:1px solid var(--border-subtle);border-radius:var(--radius-sm);padding:8px 10px;font-size:13px;white-space:pre-wrap;overflow-x:auto;color:var(--text-primary);margin-top:2px}.msg-expand-btn{border:none;background:transparent;color:var(--text-muted);font-family:var(--font-mono);font-size:11px;cursor:pointer;padding:2px 0;margin-top:4px;transition:color var(--transition-fast)}.msg-expand-btn:hover{color:var(--text-secondary)}.msg-tool-use{margin-top:2px}.msg-tool-header{display:flex;align-items:center;gap:6px;border:none;background:transparent;cursor:pointer;padding:3px 0;font-family:var(--font-mono)}.msg-tool-name{display:inline-block;padding:2px 8px;background:#ffd7001f;border:1px solid rgba(255,215,0,.3);color:var(--accent-yellow);border-radius:var(--radius-sm);font-size:13px;font-weight:600;font-family:var(--font-mono)}.msg-tool-toggle{font-size:11px;color:var(--text-muted)}.msg-tool-body{background:var(--bg-secondary);border:1px solid rgba(255,215,0,.15);border-radius:var(--radius-sm);padding:8px 10px;font-size:13px;white-space:pre-wrap;overflow-x:auto;color:var(--text-secondary);margin-top:4px;max-height:300px;overflow-y:auto}.msg-tool-result{margin-top:2px}.msg-error-badge{display:inline-block;padding:1px 5px;background:#ff444426;color:var(--accent-red);border-radius:var(--radius-sm);font-size:12px;font-weight:700;margin-bottom:4px;font-family:var(--font-mono)}.msg-result-body{font-size:13px;white-space:pre-wrap;overflow-x:auto;color:var(--text-secondary);line-height:1.5;max-height:400px;overflow-y:auto}.msg-tool-result--error .msg-result-body{color:#ff4444b3}.agents-panel__session{display:flex;align-items:center;gap:8px;padding:3px 8px;border-left:1px solid var(--border-subtle);margin-left:4px;width:100%;border-radius:0 var(--radius-sm) var(--radius-sm) 0;background:transparent;cursor:pointer;font-family:var(--font-mono);transition:background var(--transition-fast);border-top:none;border-right:none;border-bottom:none}.agents-panel__session:hover{background:var(--bg-hover)}.agents-panel__session--active{background:var(--bg-active);border-left-color:var(--accent-purple)}.agent-panel{display:flex;flex-direction:column;height:100%}.agent-panel__header{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:12px;padding-bottom:12px;border-bottom:1px solid var(--border-primary)}.agent-panel__header .panel-title{margin-bottom:0}.status-badge{display:inline-block;padding:2px 8px;border-radius:10px;font-size:11px;font-weight:600}.status-badge--active{background:#00ff8826;color:var(--accent-green)}.status-badge--idle{background:#ffd70026;color:var(--accent-yellow)}.status-badge--done{background:#00d4ff26;color:var(--accent-cyan)}.status-badge--unknown{background:#5555554d;color:var(--text-muted)}.agent-panel__tasks{padding:8px 12px;margin-bottom:12px;background:var(--bg-card);border-radius:var(--radius-md);border:1px solid var(--border-primary)}.agent-panel__task-item{display:flex;align-items:center;gap:8px;padding:4px 0;font-size:12px}.task-status-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.task-status-dot--pending{background:var(--text-muted)}.task-status-dot--in_progress{background:var(--accent-yellow)}.task-status-dot--completed{background:var(--accent-green)}.agent-panel__feed{flex:1;overflow-y:auto;padding:4px}.activity-entry{padding:8px 12px;margin-bottom:4px;border-radius:var(--radius-sm);font-size:12px}.activity-entry--user{border-left:3px solid var(--accent-green);background:#00ff880d}.activity-entry--assistant{color:var(--accent-cyan)}.activity-entry--tool-use{background:#ffd7000d}.activity-entry--tool-result{color:var(--text-muted)}.activity-entry__header{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}.activity-entry__role{color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em}.activity-entry__body{word-break:break-word}.activity-entry__code{background:var(--bg-secondary);padding:8px;border-radius:var(--radius-sm);overflow-x:auto;font-size:11px;white-space:pre-wrap;margin-top:4px}.activity-entry__tool-use{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.activity-entry__tool-badge{display:inline-block;padding:2px 6px;background:#ffd70026;color:var(--accent-yellow);border-radius:var(--radius-sm);font-size:11px;white-space:nowrap}.activity-entry__tool-input{font-size:11px;word-break:break-all}.activity-entry__tool-result{font-size:11px;line-height:1.4}
|
package/dist/index.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Agent Teams Dashboard</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-B8t0Tabx.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CsK61Xi-.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -13,6 +13,7 @@ const tasks = new Map();
|
|
|
13
13
|
const agentEntries = new Map();
|
|
14
14
|
const agentOffsets = new Map();
|
|
15
15
|
const teamFileMtimes = new Map(); // team name -> latest mtime (ms)
|
|
16
|
+
const knownProjectDirs = new Set(); // all project dir names under ~/.claude/projects/
|
|
16
17
|
export const onChange = new EventEmitter();
|
|
17
18
|
// --- Helpers ---
|
|
18
19
|
async function safeReaddir(dir) {
|
|
@@ -141,6 +142,10 @@ async function refreshAllTasks() {
|
|
|
141
142
|
// Scan both subagent JSONL (agent-*.jsonl) and team session JSONL (UUID.jsonl with teamName)
|
|
142
143
|
export async function scanAgentJsonl() {
|
|
143
144
|
const projectDirs = await safeReaddir(PROJECTS_DIR);
|
|
145
|
+
// Track all known project dirs for name resolution
|
|
146
|
+
for (const d of projectDirs) {
|
|
147
|
+
knownProjectDirs.add(d);
|
|
148
|
+
}
|
|
144
149
|
for (const projDir of projectDirs) {
|
|
145
150
|
const projPath = join(PROJECTS_DIR, projDir);
|
|
146
151
|
const entries = await safeReaddir(projPath);
|
|
@@ -148,7 +153,7 @@ export async function scanAgentJsonl() {
|
|
|
148
153
|
const entryPath = join(projPath, entry);
|
|
149
154
|
// Team session JSONL: UUID.jsonl files at project root level
|
|
150
155
|
if (entry.endsWith('.jsonl')) {
|
|
151
|
-
await readNewEntries(entryPath, true);
|
|
156
|
+
await readNewEntries(entryPath, true, projDir);
|
|
152
157
|
continue;
|
|
153
158
|
}
|
|
154
159
|
// Subagent JSONL: agent-*.jsonl under session/subagents/
|
|
@@ -157,12 +162,12 @@ export async function scanAgentJsonl() {
|
|
|
157
162
|
for (const file of files) {
|
|
158
163
|
if (!file.startsWith('agent-') || !file.endsWith('.jsonl'))
|
|
159
164
|
continue;
|
|
160
|
-
await readNewEntries(join(subagentsDir, file), false);
|
|
165
|
+
await readNewEntries(join(subagentsDir, file), false, projDir);
|
|
161
166
|
}
|
|
162
167
|
}
|
|
163
168
|
}
|
|
164
169
|
}
|
|
165
|
-
async function readNewEntries(filePath, isSessionFile) {
|
|
170
|
+
async function readNewEntries(filePath, isSessionFile, projectDir) {
|
|
166
171
|
const fileStat = await safeFileStat(filePath);
|
|
167
172
|
if (!fileStat)
|
|
168
173
|
return;
|
|
@@ -179,12 +184,12 @@ async function readNewEntries(filePath, isSessionFile) {
|
|
|
179
184
|
for (const line of lines) {
|
|
180
185
|
try {
|
|
181
186
|
const parsed = JSON.parse(line);
|
|
182
|
-
// For session files, only process entries that belong to a team
|
|
187
|
+
// For session files, only process entries that belong to a team
|
|
183
188
|
if (isSessionFile) {
|
|
184
189
|
const teamName = parsed.teamName;
|
|
185
|
-
|
|
186
|
-
if (!teamName || !agentName)
|
|
190
|
+
if (!teamName)
|
|
187
191
|
continue;
|
|
192
|
+
const agentName = parsed.agentName || 'team-lead';
|
|
188
193
|
// Use team agentId format: name@team
|
|
189
194
|
const fullAgentId = `${agentName}@${teamName}`;
|
|
190
195
|
const entry = {
|
|
@@ -202,6 +207,7 @@ async function readNewEntries(filePath, isSessionFile) {
|
|
|
202
207
|
model: parsed.message?.model,
|
|
203
208
|
},
|
|
204
209
|
timestamp: parsed.timestamp ?? '',
|
|
210
|
+
projectDir,
|
|
205
211
|
};
|
|
206
212
|
let arr = agentEntries.get(fullAgentId);
|
|
207
213
|
if (!arr) {
|
|
@@ -230,6 +236,7 @@ async function readNewEntries(filePath, isSessionFile) {
|
|
|
230
236
|
model: parsed.message?.model,
|
|
231
237
|
},
|
|
232
238
|
timestamp: parsed.timestamp ?? '',
|
|
239
|
+
projectDir,
|
|
233
240
|
};
|
|
234
241
|
if (!entry.agentId)
|
|
235
242
|
continue;
|
|
@@ -294,6 +301,119 @@ function buildTeamOverview(teamName) {
|
|
|
294
301
|
}
|
|
295
302
|
return { config, tasks: teamTasks, taskStats, agentSlugs, lastActivity };
|
|
296
303
|
}
|
|
304
|
+
/**
|
|
305
|
+
* Encode a filesystem path to the Claude project dir format.
|
|
306
|
+
* /Users/ping → -Users-ping
|
|
307
|
+
*/
|
|
308
|
+
function encodePathPrefix(fsPath) {
|
|
309
|
+
return '-' + fsPath.replace(/\//g, '-').replace(/^-/, '');
|
|
310
|
+
}
|
|
311
|
+
// The home directory prefix in encoded form, used to strip from project dir names.
|
|
312
|
+
// Uses HOST_HOME env var (set in Docker) or falls back to os.homedir().
|
|
313
|
+
const HOME_PREFIX = encodePathPrefix(process.env.HOST_HOME || homedir());
|
|
314
|
+
/**
|
|
315
|
+
* Use the set of all known project dirs to resolve ambiguous dashes.
|
|
316
|
+
* If "-Users-ping-projects" exists as a project dir, then in
|
|
317
|
+
* "-Users-ping-projects-agent-teams-dashboard", the "projects" portion
|
|
318
|
+
* is a directory (path separator), not part of a directory name.
|
|
319
|
+
*
|
|
320
|
+
* Returns the last path segment (the actual project directory name).
|
|
321
|
+
*/
|
|
322
|
+
function resolveProjectName(projectDir, allProjectDirs) {
|
|
323
|
+
if (projectDir === HOME_PREFIX)
|
|
324
|
+
return '~';
|
|
325
|
+
const prefixWithDash = HOME_PREFIX + '-';
|
|
326
|
+
if (!projectDir.startsWith(prefixWithDash))
|
|
327
|
+
return projectDir;
|
|
328
|
+
const remainder = projectDir.slice(prefixWithDash.length);
|
|
329
|
+
// Try to find the longest known parent directory prefix.
|
|
330
|
+
// A known dir is a valid parent only if:
|
|
331
|
+
// 1. It's a strict prefix of projectDir (not equal to it)
|
|
332
|
+
// 2. No OTHER known dir starts with it + the next dash-segment
|
|
333
|
+
// (which would mean the continuation is part of the dir name, not a child)
|
|
334
|
+
let bestSplit = 0;
|
|
335
|
+
const parts = remainder.split('-');
|
|
336
|
+
let accumulated = HOME_PREFIX;
|
|
337
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
338
|
+
accumulated += '-' + parts[i];
|
|
339
|
+
if (!allProjectDirs.has(accumulated) || accumulated === projectDir)
|
|
340
|
+
continue;
|
|
341
|
+
// Check: is there another known dir that starts with accumulated + '-' + nextPart?
|
|
342
|
+
// If so, accumulated might not be a true parent — the next segment could be part
|
|
343
|
+
// of a longer directory name at the same level.
|
|
344
|
+
const nextAccumulated = accumulated + '-' + parts[i + 1];
|
|
345
|
+
// When nextAccumulated === projectDir, accumulated could be a real parent
|
|
346
|
+
// (e.g. panamera-python3 → worktree3) or a false parent (e.g. erp-shipment → 2).
|
|
347
|
+
// Heuristic: accumulated is a real parent if other known dirs also have it as prefix.
|
|
348
|
+
if (nextAccumulated === projectDir) {
|
|
349
|
+
const accPrefix = accumulated + '-';
|
|
350
|
+
const hasOtherChildren = Array.from(allProjectDirs).some(d => d !== projectDir && d.startsWith(accPrefix));
|
|
351
|
+
if (hasOtherChildren) {
|
|
352
|
+
bestSplit = i + 1;
|
|
353
|
+
}
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
const isFalseParent = allProjectDirs.has(nextAccumulated) &&
|
|
357
|
+
projectDir.startsWith(nextAccumulated);
|
|
358
|
+
if (!isFalseParent) {
|
|
359
|
+
bestSplit = i + 1;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if (bestSplit > 0) {
|
|
363
|
+
return parts.slice(bestSplit).join('-');
|
|
364
|
+
}
|
|
365
|
+
return remainder;
|
|
366
|
+
}
|
|
367
|
+
function buildProjectOverviews() {
|
|
368
|
+
// Group all agent entries by projectDir
|
|
369
|
+
const projectMap = new Map();
|
|
370
|
+
for (const [agentId, entries] of agentEntries) {
|
|
371
|
+
for (const entry of entries) {
|
|
372
|
+
if (!entry.projectDir)
|
|
373
|
+
continue;
|
|
374
|
+
let agentMap = projectMap.get(entry.projectDir);
|
|
375
|
+
if (!agentMap) {
|
|
376
|
+
agentMap = new Map();
|
|
377
|
+
projectMap.set(entry.projectDir, agentMap);
|
|
378
|
+
}
|
|
379
|
+
let agentData = agentMap.get(agentId);
|
|
380
|
+
if (!agentData) {
|
|
381
|
+
agentData = { slug: entry.slug, entries: [] };
|
|
382
|
+
agentMap.set(agentId, agentData);
|
|
383
|
+
}
|
|
384
|
+
agentData.entries.push(entry);
|
|
385
|
+
if (entry.slug)
|
|
386
|
+
agentData.slug = entry.slug;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
const projects = [];
|
|
390
|
+
for (const [projectDir, agentMap] of projectMap) {
|
|
391
|
+
let lastActivity = '';
|
|
392
|
+
const agents = [];
|
|
393
|
+
for (const [agentId, data] of agentMap) {
|
|
394
|
+
const lastTs = data.entries.length > 0
|
|
395
|
+
? data.entries[data.entries.length - 1].timestamp
|
|
396
|
+
: '';
|
|
397
|
+
agents.push({
|
|
398
|
+
agentId,
|
|
399
|
+
slug: data.slug || agentId,
|
|
400
|
+
entryCount: data.entries.length,
|
|
401
|
+
lastTimestamp: lastTs,
|
|
402
|
+
});
|
|
403
|
+
if (lastTs > lastActivity)
|
|
404
|
+
lastActivity = lastTs;
|
|
405
|
+
}
|
|
406
|
+
agents.sort((a, b) => b.lastTimestamp.localeCompare(a.lastTimestamp));
|
|
407
|
+
projects.push({
|
|
408
|
+
projectDir,
|
|
409
|
+
projectName: resolveProjectName(projectDir, knownProjectDirs),
|
|
410
|
+
agents,
|
|
411
|
+
lastActivity,
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
projects.sort((a, b) => b.lastActivity.localeCompare(a.lastActivity));
|
|
415
|
+
return projects;
|
|
416
|
+
}
|
|
297
417
|
export function getSnapshot() {
|
|
298
418
|
const teamOverviews = [];
|
|
299
419
|
const matchedAgentIds = new Set();
|
|
@@ -326,7 +446,7 @@ export function getSnapshot() {
|
|
|
326
446
|
activity[agentId] = entries;
|
|
327
447
|
}
|
|
328
448
|
}
|
|
329
|
-
return { teams: teamOverviews, unmatchedAgents, agentActivity: activity };
|
|
449
|
+
return { teams: teamOverviews, unmatchedAgents, agentActivity: activity, projects: buildProjectOverviews() };
|
|
330
450
|
}
|
|
331
451
|
// --- Query ---
|
|
332
452
|
export function getAgentActivity(agentId) {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
:root{--bg-primary: #1a1a2e;--bg-secondary: #16213e;--bg-sidebar: #0f0f1a;--bg-sidebar-2: #111122;--bg-card: #16213e;--bg-hover: #1f2b47;--bg-active: #253350;--border-primary: #2a2a3e;--border-subtle: #222236;--text-primary: #e0e0e0;--text-secondary: #888;--text-muted: #555;--accent-blue: #58a6ff;--accent-green: #00ff88;--accent-yellow: #ffd700;--accent-red: #ff4444;--accent-purple: #bc8cff;--accent-cyan: #00d4ff;--font-mono: "JetBrains Mono", "Fira Code", Consolas, monospace;--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;--radius-sm: 4px;--radius-md: 6px;--radius-lg: 8px;--transition-fast: .15s ease}*,*:before,*:after{margin:0;padding:0;box-sizing:border-box}body{font-family:var(--font-mono);font-size:13px;line-height:1.5;color:var(--text-primary);background:var(--bg-primary);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.app-container{display:flex;height:100vh;overflow:hidden}.teams-panel{width:200px;min-width:200px;background:var(--bg-sidebar);border-right:1px solid var(--border-primary);display:flex;flex-direction:column;overflow:hidden}.teams-panel__header{padding:14px 12px;border-bottom:1px solid var(--border-primary)}.teams-panel__title{font-size:13px;font-weight:700;color:var(--text-primary);letter-spacing:.04em;text-transform:uppercase}.teams-panel__conn-dot{font-size:10px}.teams-panel__nav{flex:1;overflow-y:auto;padding:6px}.teams-panel__nav-item{display:flex;align-items:center;gap:8px;width:100%;padding:8px 10px;border:none;background:transparent;color:var(--text-secondary);font-family:var(--font-mono);font-size:12px;cursor:pointer;border-radius:var(--radius-sm);transition:all var(--transition-fast);text-align:left}.teams-panel__nav-item:hover{background:var(--bg-hover);color:var(--text-primary)}.teams-panel__nav-item--active{background:var(--bg-active);color:var(--accent-cyan)}.teams-panel__nav-icon{font-size:14px}.teams-panel__divider{height:1px;background:var(--border-subtle);margin:6px 4px}.teams-panel__team{display:flex;flex-direction:column;gap:4px;width:100%;padding:8px 10px;margin-bottom:2px;border:none;background:transparent;color:var(--text-primary);font-family:var(--font-mono);font-size:12px;cursor:pointer;border-radius:var(--radius-sm);border-left:3px solid transparent;transition:all var(--transition-fast);text-align:left}.teams-panel__team:hover{background:var(--bg-hover)}.teams-panel__team--active{background:var(--bg-active);border-left-color:var(--accent-cyan)}.teams-panel__team-row{display:flex;align-items:center;gap:6px}.teams-panel__team-dot{font-size:10px;flex-shrink:0;line-height:1}.teams-panel__team-name{flex:1;min-width:0}.teams-panel__team-progress{display:flex;align-items:center;gap:6px;padding-left:16px}.teams-panel__team-bar{flex:1;height:3px;background:var(--border-primary);border-radius:2px;overflow:hidden}.teams-panel__team-bar-fill{height:100%;background:var(--accent-green);border-radius:2px;transition:width .3s ease}.teams-panel__team-pct{flex-shrink:0;white-space:nowrap}.teams-panel__footer{padding:10px 12px;border-top:1px solid var(--border-primary)}.teams-panel__footer-stats{display:flex;gap:10px}.agents-panel{width:260px;min-width:260px;background:var(--bg-sidebar-2);border-right:1px solid var(--border-primary);display:flex;flex-direction:column;overflow:hidden}.agents-panel__header{padding:14px 12px;border-bottom:1px solid var(--border-primary);display:flex;align-items:center;justify-content:space-between;gap:8px}.agents-panel__title{font-size:13px;font-weight:700;color:var(--text-primary);min-width:0}.agents-panel__task-summary{flex-shrink:0;white-space:nowrap}.agents-panel__empty{flex:1;display:flex;align-items:center;justify-content:center}.agents-panel__actions{padding:8px;border-bottom:1px solid var(--border-subtle)}.agents-panel__tasks-btn{display:flex;align-items:center;gap:6px;width:100%;padding:6px 10px;border:1px solid var(--border-primary);background:transparent;color:var(--text-secondary);font-family:var(--font-mono);font-size:12px;cursor:pointer;border-radius:var(--radius-sm);transition:all var(--transition-fast)}.agents-panel__tasks-btn:hover{background:var(--bg-hover);color:var(--text-primary);border-color:var(--text-muted)}.agents-panel__tasks-btn--active{background:var(--bg-active);color:var(--accent-cyan);border-color:var(--accent-cyan)}.agents-panel__list{flex:1;overflow-y:auto;padding:6px}.agents-panel__agent{margin-bottom:2px}.agents-panel__agent-btn{display:flex;align-items:center;gap:6px;width:100%;padding:7px 10px;border:none;background:transparent;color:var(--text-primary);font-family:var(--font-mono);font-size:12px;cursor:pointer;border-radius:var(--radius-sm);transition:all var(--transition-fast);text-align:left;border-left:3px solid transparent}.agents-panel__agent-btn:hover{background:var(--bg-hover)}.agents-panel__agent-btn--active{background:var(--bg-active);border-left-color:var(--accent-cyan);color:var(--accent-cyan)}.agents-panel__agent-dot{font-size:10px;flex-shrink:0;line-height:1}.agents-panel__agent-name{flex:1;min-width:0}.agents-panel__agent-type{flex-shrink:0}.agents-panel__agent-meta{display:flex;align-items:center;gap:8px;padding:2px 10px 4px 26px}.agents-panel__session-toggle{border:none;background:transparent;color:var(--text-muted);font-family:var(--font-mono);font-size:11px;cursor:pointer;padding:0;transition:color var(--transition-fast)}.agents-panel__session-toggle:hover{color:var(--text-secondary)}.agents-panel__sessions{padding:2px 10px 6px 26px}.agents-panel__session-id{font-size:11px;color:var(--accent-purple);font-family:var(--font-mono)}.agents-panel__session-time{font-size:11px;color:var(--text-muted)}.agents-panel__session-count{font-size:10px;color:var(--text-muted);background:var(--bg-hover);padding:0 4px;border-radius:3px}.main-panel{flex:1;overflow:hidden;display:flex;flex-direction:column}.main-panel>.overview-grid,.main-panel>.task-board__columns,.main-panel--padded{padding:16px;overflow-y:auto}.placeholder{display:flex;align-items:center;justify-content:center;height:100%;color:var(--text-muted);font-size:14px}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border-primary);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--text-muted)}*{scrollbar-width:thin;scrollbar-color:var(--border-primary) transparent}.text-primary{color:var(--text-primary)}.text-secondary{color:var(--text-secondary)}.text-muted{color:var(--text-muted)}.text-blue{color:var(--accent-blue)}.text-green{color:var(--accent-green)}.text-yellow{color:var(--accent-yellow)}.text-red{color:var(--accent-red)}.text-purple{color:var(--accent-purple)}.text-cyan{color:var(--accent-cyan)}.bg-card{background:var(--bg-card)}.bg-hover{background:var(--bg-hover)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-md{border-radius:var(--radius-md)}.rounded-lg{border-radius:var(--radius-lg)}.flex{display:flex}.flex-col{flex-direction:column}.flex-1{flex:1}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-1{gap:4px}.gap-2{gap:8px}.gap-3{gap:12px}.gap-4{gap:16px}.p-1{padding:4px}.p-2{padding:8px}.p-3{padding:12px}.p-4{padding:16px}.px-2{padding-left:8px;padding-right:8px}.px-3{padding-left:12px;padding-right:12px}.py-1{padding-top:4px;padding-bottom:4px}.py-2{padding-top:8px;padding-bottom:8px}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.font-bold{font-weight:600}.text-sm{font-size:12px}.text-xs{font-size:11px}.border{border:1px solid var(--border-primary)}.border-b{border-bottom:1px solid var(--border-primary)}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;user-select:none}.transition{transition:all var(--transition-fast)}.panel-title{font-size:16px;font-weight:600;color:var(--text-primary);margin-bottom:16px}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;text-align:center}.empty-state__icon{font-size:48px}.empty-state__title{font-size:16px;font-weight:600;color:var(--text-secondary)}.empty-state__text{max-width:400px;line-height:1.6}.overview-panel{padding:16px;overflow-y:auto;height:100%}.overview-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:12px}.overview-card{background:var(--bg-card);border:1px solid var(--border-primary);border-left:3px solid var(--text-muted);border-radius:var(--radius-md);padding:16px;transition:all var(--transition-fast)}.overview-card:hover{border-color:var(--accent-cyan);border-left-color:inherit;background:var(--bg-hover)}.overview-card--active{border-left-color:var(--accent-green)}.overview-card--idle{border-left-color:var(--accent-yellow)}.overview-card--done{border-left-color:var(--accent-cyan)}.overview-card--inactive{border-left-color:var(--text-muted)}.overview-card__header{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}.overview-card__meta{margin-bottom:12px}.overview-card__progress{display:flex;align-items:center;gap:8px;margin-bottom:8px}.progress-bar{flex:1;height:4px;background:var(--border-primary);border-radius:2px;overflow:hidden}.progress-bar__fill{height:100%;background:var(--accent-green);border-radius:2px;transition:width .3s ease}.overview-card__footer{text-align:right}.pulse-dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--accent-green);animation:pulse 2s ease-in-out infinite;flex-shrink:0}@keyframes pulse{0%,to{opacity:1;box-shadow:0 0 #0f86}50%{opacity:.7;box-shadow:0 0 0 6px #0f80}}.task-board{padding:16px;overflow-y:auto;height:100%}.task-board__columns{display:flex;gap:12px}.task-board__column{flex:1;min-width:0}.task-board__column-header{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;margin-bottom:8px;border-bottom:2px solid var(--border-primary);font-weight:600;font-size:12px;color:var(--text-secondary)}.task-card{background:var(--bg-card);border:1px solid var(--border-primary);border-radius:var(--radius-md);padding:12px;margin-bottom:8px;border-left:3px solid var(--text-muted)}.task-card--in-progress{border-left-color:var(--accent-yellow)}.task-card--completed{border-left-color:var(--accent-green)}.task-card--pending{border-left-color:var(--text-muted)}.task-card__subject{font-size:12px;margin-bottom:4px;color:var(--text-primary)}.task-card__desc{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;margin-bottom:8px;line-height:1.4}.task-card__meta{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.task-card__owner{display:inline-block;padding:2px 6px;background:#00d4ff26;color:var(--accent-cyan);border-radius:var(--radius-sm);font-size:11px}.task-card__blocked{color:var(--accent-yellow)}.chat-panel{display:flex;flex-direction:column;height:100%;position:relative}.chat-panel__header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 16px;border-bottom:1px solid var(--border-primary);background:var(--bg-secondary);flex-shrink:0}.chat-panel__header-left{display:flex;align-items:center;gap:8px;min-width:0}.chat-panel__header-right{display:flex;align-items:center;gap:12px;flex-shrink:0}.chat-panel__agent-name{font-size:14px;font-weight:700;color:var(--accent-cyan);font-family:var(--font-mono)}.chat-panel__session-tag{font-size:11px;padding:2px 6px;background:#bc8cff26;color:var(--accent-purple);border-radius:var(--radius-sm);font-family:var(--font-mono)}.chat-panel__team{white-space:nowrap}.chat-panel__feed{flex:1;overflow-y:auto;padding:8px 0}.chat-panel__empty{display:flex;align-items:center;justify-content:center;height:100%}.chat-panel__scroll-btn{position:absolute;bottom:12px;right:16px;padding:6px 12px;background:var(--bg-active);border:1px solid var(--accent-cyan);color:var(--accent-cyan);font-family:var(--font-mono);font-size:11px;border-radius:var(--radius-sm);cursor:pointer;transition:all var(--transition-fast);z-index:10}.chat-panel__scroll-btn:hover{background:var(--bg-hover)}.chat-msg{padding:6px 16px;border-left:3px solid transparent;transition:background var(--transition-fast)}.chat-msg:hover{background:#ffffff05}.chat-msg--user{border-left-color:var(--accent-green);background:#00ff8808}.chat-msg--assistant{border-left-color:var(--accent-cyan)}.chat-msg--tool-use{border-left-color:var(--accent-yellow);background:#ffd70008}.chat-msg--tool-result{border-left-color:var(--text-muted)}.chat-msg__meta{display:flex;align-items:center;gap:8px;margin-bottom:4px}.chat-msg__role{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;font-family:var(--font-mono)}.chat-msg--user .chat-msg__role{color:var(--accent-green)}.chat-msg--assistant .chat-msg__role{color:var(--accent-cyan)}.chat-msg--tool-use .chat-msg__role{color:var(--accent-yellow)}.chat-msg--tool-result .chat-msg__role{color:var(--text-muted)}.chat-msg__time{font-size:10px;color:var(--text-muted);font-family:var(--font-mono)}.chat-msg__body{font-size:12px;line-height:1.6;word-break:break-word}.msg-prose{color:var(--text-primary);white-space:pre-wrap}.chat-msg--assistant .msg-prose{color:var(--text-primary)}.msg-code{background:var(--bg-secondary);border:1px solid var(--border-subtle);border-radius:var(--radius-sm);padding:8px 10px;font-size:11px;white-space:pre-wrap;overflow-x:auto;color:var(--text-primary);margin-top:2px}.msg-expand-btn{border:none;background:transparent;color:var(--text-muted);font-family:var(--font-mono);font-size:11px;cursor:pointer;padding:2px 0;margin-top:4px;transition:color var(--transition-fast)}.msg-expand-btn:hover{color:var(--text-secondary)}.msg-tool-use{margin-top:2px}.msg-tool-header{display:flex;align-items:center;gap:6px;border:none;background:transparent;cursor:pointer;padding:3px 0;font-family:var(--font-mono)}.msg-tool-name{display:inline-block;padding:2px 8px;background:#ffd7001f;border:1px solid rgba(255,215,0,.3);color:var(--accent-yellow);border-radius:var(--radius-sm);font-size:11px;font-weight:600;font-family:var(--font-mono)}.msg-tool-toggle{font-size:11px;color:var(--text-muted)}.msg-tool-body{background:var(--bg-secondary);border:1px solid rgba(255,215,0,.15);border-radius:var(--radius-sm);padding:8px 10px;font-size:11px;white-space:pre-wrap;overflow-x:auto;color:var(--text-secondary);margin-top:4px;max-height:300px;overflow-y:auto}.msg-tool-result{margin-top:2px}.msg-error-badge{display:inline-block;padding:1px 5px;background:#ff444426;color:var(--accent-red);border-radius:var(--radius-sm);font-size:10px;font-weight:700;margin-bottom:4px;font-family:var(--font-mono)}.msg-result-body{font-size:11px;white-space:pre-wrap;overflow-x:auto;color:var(--text-muted);line-height:1.5;max-height:200px;overflow-y:auto}.msg-tool-result--error .msg-result-body{color:#ff4444b3}.agents-panel__session{display:flex;align-items:center;gap:8px;padding:3px 8px;border-left:1px solid var(--border-subtle);margin-left:4px;width:100%;border-radius:0 var(--radius-sm) var(--radius-sm) 0;background:transparent;cursor:pointer;font-family:var(--font-mono);transition:background var(--transition-fast);border-top:none;border-right:none;border-bottom:none}.agents-panel__session:hover{background:var(--bg-hover)}.agents-panel__session--active{background:var(--bg-active);border-left-color:var(--accent-purple)}.agent-panel{display:flex;flex-direction:column;height:100%}.agent-panel__header{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:12px;padding-bottom:12px;border-bottom:1px solid var(--border-primary)}.agent-panel__header .panel-title{margin-bottom:0}.status-badge{display:inline-block;padding:2px 8px;border-radius:10px;font-size:11px;font-weight:600}.status-badge--active{background:#00ff8826;color:var(--accent-green)}.status-badge--idle{background:#ffd70026;color:var(--accent-yellow)}.status-badge--done{background:#00d4ff26;color:var(--accent-cyan)}.status-badge--unknown{background:#5555554d;color:var(--text-muted)}.agent-panel__tasks{padding:8px 12px;margin-bottom:12px;background:var(--bg-card);border-radius:var(--radius-md);border:1px solid var(--border-primary)}.agent-panel__task-item{display:flex;align-items:center;gap:8px;padding:4px 0;font-size:12px}.task-status-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.task-status-dot--pending{background:var(--text-muted)}.task-status-dot--in_progress{background:var(--accent-yellow)}.task-status-dot--completed{background:var(--accent-green)}.agent-panel__feed{flex:1;overflow-y:auto;padding:4px}.activity-entry{padding:8px 12px;margin-bottom:4px;border-radius:var(--radius-sm);font-size:12px}.activity-entry--user{border-left:3px solid var(--accent-green);background:#00ff880d}.activity-entry--assistant{color:var(--accent-cyan)}.activity-entry--tool-use{background:#ffd7000d}.activity-entry--tool-result{color:var(--text-muted)}.activity-entry__header{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}.activity-entry__role{color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em}.activity-entry__body{word-break:break-word}.activity-entry__code{background:var(--bg-secondary);padding:8px;border-radius:var(--radius-sm);overflow-x:auto;font-size:11px;white-space:pre-wrap;margin-top:4px}.activity-entry__tool-use{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.activity-entry__tool-badge{display:inline-block;padding:2px 6px;background:#ffd70026;color:var(--accent-yellow);border-radius:var(--radius-sm);font-size:11px;white-space:nowrap}.activity-entry__tool-input{font-size:11px;word-break:break-all}.activity-entry__tool-result{font-size:11px;line-height:1.4}
|