<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AgentScript Report</title>
<script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
<style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; background: #0d1117; color: #c9d1d9; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; display: flex; min-height: 100vh; }
#sidebar { width: 240px; min-height: 100vh; background: #161b22; border-right: 1px solid #30363d; position: fixed; top: 0; left: 0; bottom: 0; overflow-y: auto; display: flex; flex-direction: column; }
.sidebar-header { padding: 20px 16px 16px; border-bottom: 1px solid #30363d; }
.sidebar-title { font-size: 0.75rem; font-weight: 600; color: #8b949e; text-transform: uppercase; letter-spacing: 0.05em; }
.sidebar-count { font-size: 0.7rem; color: #484f58; margin-top: 2px; }
.nav-item { padding: 8px 16px; cursor: pointer; color: #c9d1d9; font-size: 0.875rem; border-left: 3px solid transparent; display: flex; align-items: center; gap: 8px; transition: background 0.1s; }
.nav-item:hover { background: #21262d; }
.nav-item.active { color: #58a6ff; border-left-color: #58a6ff; background: rgba(88,166,255,0.05); }
.nav-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.badge { font-size: 0.65rem; color: #484f58; background: #21262d; border-radius: 10px; padding: 1px 6px; flex-shrink: 0; }
.nav-item.active .badge { background: rgba(88,166,255,0.15); color: #58a6ff; }
#main { margin-left: 240px; padding: 32px; flex: 1; min-width: 0; }
.agent-section { display: none; }
.agent-section.active { display: block; }
.agent-header { margin-bottom: 20px; }
.agent-name { font-size: 1.4rem; color: #58a6ff; margin: 0 0 2px 0; font-weight: 600; }
.agent-label { font-size: 0.85rem; color: #8b949e; margin-bottom: 2px; }
.agent-file { font-size: 0.75rem; color: #484f58; font-family: monospace; }
.graph-container { background: #161b22; border-radius: 8px; padding: 24px; border: 1px solid #30363d; overflow: auto; cursor: pointer; }
.stats-bar { margin-top: 10px; font-size: 0.8rem; color: #8b949e; background: #161b22; border-radius: 6px; padding: 9px 16px; border: 1px solid #30363d; display: flex; gap: 20px; flex-wrap: wrap; }
.stats-bar strong { color: #c9d1d9; }
.legend { margin-top: 8px; font-size: 0.72rem; color: #484f58; }
.mermaid svg { max-width: 100%; height: auto; }
/* Detail panel */
.detail-panel { margin-top: 24px; }
.detail-card { background: #161b22; border: 1px solid #30363d; border-radius: 8px; padding: 20px; }
.detail-card + .detail-card { margin-top: 16px; }
.detail-back { font-size: 0.78rem; color: #58a6ff; cursor: pointer; margin-bottom: 14px; display: inline-flex; align-items: center; gap: 4px; }
.detail-back:hover { text-decoration: underline; }
.detail-title { font-size: 1rem; font-weight: 600; color: #c9d1d9; margin: 0 0 4px 0; display: flex; align-items: center; gap: 8px; }
.detail-desc { font-size: 0.82rem; color: #8b949e; margin: 0 0 16px 0; }
.entry-badge { font-size: 0.65rem; background: rgba(88,166,255,0.15); color: #58a6ff; border: 1px solid rgba(88,166,255,0.3); border-radius: 10px; padding: 1px 7px; font-weight: 500; }
.detail-section { margin-bottom: 14px; }
.detail-section-title { font-size: 0.7rem; font-weight: 600; color: #8b949e; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 6px; }
.tag-list { display: flex; flex-wrap: wrap; gap: 6px; }
.tag { font-size: 0.78rem; padding: 2px 10px; border-radius: 12px; font-family: monospace; }
.tag-action { background: rgba(188,135,255,0.12); color: #c8a4ff; border: 1px solid rgba(188,135,255,0.25); }
.tag-topic { background: rgba(88,166,255,0.1); color: #79b8ff; border: 1px solid rgba(88,166,255,0.2); }
.tag-var-read { background: rgba(57,211,83,0.1); color: #7ee787; border: 1px solid rgba(57,211,83,0.2); }
.tag-var-write { background: rgba(255,166,77,0.1); color: #ffb347; border: 1px solid rgba(255,166,77,0.2); }
.tag-delegate { background: rgba(88,118,255,0.1); color: #7080ff; border: 1px solid rgba(88,118,255,0.2); }
.var-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
.var-table th { color: #8b949e; font-weight: 500; text-align: left; padding: 4px 8px 8px 0; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.04em; }
.var-table td { padding: 4px 8px 4px 0; color: #c9d1d9; border-top: 1px solid #21262d; font-family: monospace; }
.var-type { color: #7ee787; }
.var-mod { font-size: 0.7rem; color: #8b949e; }
.empty-msg { font-size: 0.8rem; color: #484f58; font-style: italic; }
.overview-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 700px) { .overview-grid { grid-template-columns: 1fr; } }
</style>
</head>
<body>
<nav id="sidebar">
<div class="sidebar-header">
<div class="sidebar-title">AgentScript</div>
<div class="sidebar-count">2 agents</div>
</div>
<div class="nav-item" id="nav-agent-a" data-id="agent-a" onclick="showAgent('agent-a')">
<span class="nav-name">AgentA</span>
<span class="badge">0T</span>
</div>
<div class="nav-item" id="nav-agent-b" data-id="agent-b" onclick="showAgent('agent-b')">
<span class="nav-name">AgentB</span>
<span class="badge">0T</span>
</div>
</nav>
<main id="main">
<div class="agent-section" id="section-agent-a">
<div class="agent-header">
<h1 class="agent-name">AgentA</h1>
<div class="agent-label">Agent A</div>
<div class="agent-file">test/commands/agency/fixtures/agents-dir/agent-a.agent</div>
</div>
<div class="graph-container">
<div class="mermaid">flowchart LR
start_agent([start_agent])
click start_agent onNodeClick</div>
</div>
<div class="stats-bar">
<span><strong>0</strong> topics</span>
<span><strong>1</strong> variables</span>
<span><strong>0</strong> action defs</span>
<span><strong>0</strong> reasoning steps</span>
</div>
<div class="legend">→ transition | ⇒ delegate | ([name]) = entry point | <em>click a node for details</em></div>
<div class="detail-panel" id="detail-agent-a"></div>
</div>
<div class="agent-section" id="section-agent-b">
<div class="agent-header">
<h1 class="agent-name">AgentB</h1>
<div class="agent-label">Agent B</div>
<div class="agent-file">test/commands/agency/fixtures/agents-dir/agent-b.agent</div>
</div>
<div class="graph-container">
<div class="mermaid">flowchart LR
start_agent([start_agent])
click start_agent onNodeClick</div>
</div>
<div class="stats-bar">
<span><strong>0</strong> topics</span>
<span><strong>0</strong> variables</span>
<span><strong>0</strong> action defs</span>
<span><strong>0</strong> reasoning steps</span>
</div>
<div class="legend">→ transition | ⇒ delegate | ([name]) = entry point | <em>click a node for details</em></div>
<div class="detail-panel" id="detail-agent-b"></div>
</div>
</main>
<script>
const allData = {"agent-a":{"agentName":"AgentA","agentLabel":"Agent A","agentDescription":"First test agent for multi-file tests","variables":[{"name":"node","type":"unknown","mutable":false,"linked":false},{"name":"span","type":"unknown","mutable":false,"linked":false}],"topics":[{"safeId":"start_agent","name":"start_agent","description":null,"is_entry":true,"actions":[],"transitions_to":[],"delegates_to":[],"var_reads":[],"var_writes":[]}]},"agent-b":{"agentName":"AgentB","agentLabel":"Agent B","agentDescription":"Second test agent for multi-file tests","variables":[],"topics":[{"safeId":"start_agent","name":"start_agent","description":null,"is_entry":true,"actions":[],"transitions_to":[],"delegates_to":[],"var_reads":[],"var_writes":[]}]}};
mermaid.initialize({ startOnLoad: false, theme: 'dark' });
const rendered = new Set();
let currentAgentId = null;
function showAgent(id) {
document.querySelectorAll('.agent-section').forEach(el => el.classList.remove('active'));
document.querySelectorAll('.nav-item').forEach(el => el.classList.remove('active'));
const section = document.getElementById('section-' + id);
const nav = document.getElementById('nav-' + id);
if (!section) return;
section.classList.add('active');
if (nav) nav.classList.add('active');
currentAgentId = id;
if (!rendered.has(id)) {
rendered.add(id);
mermaid.run({ nodes: section.querySelectorAll('.mermaid') });
}
history.replaceState(null, '', '#' + id);
showOverview(id);
}
function showOverview(agentId) {
const data = allData[agentId];
const panel = document.getElementById('detail-' + agentId);
if (!panel || !data) return;
const descHtml = data.agentDescription
? '<p class="detail-desc">' + esc(data.agentDescription) + '</p>' : '';
const varRows = data.variables.length
? data.variables.map(v => {
const mods = [v.mutable ? 'mutable' : '', v.linked ? 'linked' : ''].filter(Boolean).join(' ');
return '<tr><td>' + esc(v.name) + '</td><td class="var-type">' + esc(v.type) + '</td><td class="var-mod">' + esc(mods) + '</td></tr>';
}).join('')
: '<tr><td colspan="3" class="empty-msg">No variables defined</td></tr>';
panel.innerHTML = '<div class="detail-card">' +
'<div class="detail-title">Agent Overview</div>' +
descHtml +
'<div class="overview-grid">' +
'<div class="detail-section"><div class="detail-section-title">Variables (' + data.variables.length + ')</div>' +
'<table class="var-table"><thead><tr><th>Name</th><th>Type</th><th>Modifiers</th></tr></thead><tbody>' + varRows + '</tbody></table></div>' +
'<div class="detail-section"><div class="detail-section-title">Topics (' + data.topics.length + ')</div>' +
'<div class="tag-list">' + data.topics.map(t =>
'<span class="tag tag-topic">' + esc(t.name) + (t.is_entry ? ' ★' : '') + '</span>'
).join('') + '</div></div>' +
'</div></div>';
}
function onNodeClick(nodeId) {
if (!currentAgentId) return;
const data = allData[currentAgentId];
if (!data) return;
const topic = data.topics.find(t => t.safeId === nodeId);
if (!topic) return;
const panel = document.getElementById('detail-' + currentAgentId);
if (!panel) return;
const descHtml = topic.description
? '<p class="detail-desc">' + esc(topic.description) + '</p>' : '';
const actionsHtml = topic.actions.length
? '<div class="tag-list">' + topic.actions.map(a => '<span class="tag tag-action">' + esc(a) + '</span>').join('') + '</div>'
: '<span class="empty-msg">None</span>';
const transHtml = topic.transitions_to.length
? '<div class="tag-list">' + topic.transitions_to.map(t => '<span class="tag tag-topic">' + esc(t) + '</span>').join('') + '</div>'
: '<span class="empty-msg">None (terminal topic)</span>';
const delegHtml = topic.delegates_to.length
? '<div class="tag-list">' + topic.delegates_to.map(t => '<span class="tag tag-delegate">' + esc(t) + '</span>').join('') + '</div>'
: '';
const readsHtml = topic.var_reads.length
? '<div class="tag-list">' + topic.var_reads.map(v => '<span class="tag tag-var-read">' + esc(v) + '</span>').join('') + '</div>'
: '<span class="empty-msg">None</span>';
const writesHtml = topic.var_writes.length
? '<div class="tag-list">' + topic.var_writes.map(v => '<span class="tag tag-var-write">' + esc(v) + '</span>').join('') + '</div>'
: '<span class="empty-msg">None</span>';
panel.innerHTML =
'<div class="detail-back" onclick="showOverview('' + currentAgentId + '')">← back to overview</div>' +
'<div class="detail-card">' +
'<div class="detail-title">' + esc(topic.name) + (topic.is_entry ? ' <span class="entry-badge">entry</span>' : '') + '</div>' +
descHtml +
(topic.actions.length ? '<div class="detail-section"><div class="detail-section-title">Actions (' + topic.actions.length + ')</div>' + actionsHtml + '</div>' : '') +
'<div class="detail-section"><div class="detail-section-title">Transitions to</div>' + transHtml + '</div>' +
(topic.delegates_to.length ? '<div class="detail-section"><div class="detail-section-title">Delegates to</div>' + delegHtml + '</div>' : '') +
'<div class="detail-section"><div class="detail-section-title">Variables read</div>' + readsHtml + '</div>' +
'<div class="detail-section"><div class="detail-section-title">Variables written</div>' + writesHtml + '</div>' +
'</div>';
}
function esc(str) {
if (!str) return '';
return String(str).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
}
const hash = location.hash.slice(1);
const firstId = 'agent-a';
showAgent(hash && document.getElementById('section-' + hash) ? hash : firstId);
</script>
</body>
</html>