Skip to content

Commit 7fbfc48

Browse files
committed
feat: refactor displaySummary to fetch and group selected action details asynchronously
1 parent 7b809e8 commit 7fbfc48

File tree

1 file changed

+69
-81
lines changed

1 file changed

+69
-81
lines changed

app/templates/generate.html

Lines changed: 69 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ <h3 class="text-lg font-black text-black mb-2">🔧 Configuration Patch</h3>
202202

203203
await loadActionDetails();
204204
generateFiles();
205-
displaySummary();
205+
await displaySummary();
206206
displayFilePreviews();
207207
displayPatchPreview();
208208
});
@@ -257,91 +257,79 @@ <h3 class="text-lg font-black text-black mb-2">🔧 Configuration Patch</h3>
257257
// This function could be used for client-side generation if needed
258258
}
259259

260-
function displaySummary() {
260+
async function displaySummary() {
261261
const container = document.getElementById('selectedSummary');
262262

263-
// Group actions by type
264-
const grouped = {
265-
agents: [],
266-
rules: [],
267-
rulesets: [],
268-
mcps: [],
269-
packs: []
270-
};
271-
272-
// Parse the generated files to extract action types
273-
if (generatedFiles['CLAUDE.md']) {
274-
// Count rules and rulesets
275-
const claudeContent = generatedFiles['CLAUDE.md'];
276-
const ruleMatches = claudeContent.match(/## .+/g) || [];
277-
grouped.rules = ruleMatches;
278-
}
279-
280-
if (generatedFiles['AGENTS.md']) {
281-
// Count agents from AGENTS.md content
282-
const agentsContent = generatedFiles['AGENTS.md'];
283-
const agentMatches = agentsContent.match(/^## .+$/gm) || [];
284-
grouped.agents = agentMatches;
285-
} else if (generatedFiles['.claude/agents']) {
286-
// Fallback: Count individual agent files
287-
grouped.agents = Object.keys(generatedFiles).filter(f => f.startsWith('.claude/agents/'));
288-
}
289-
290-
if (generatedFiles['.mcp.json']) {
291-
// Count MCPs
292-
try {
293-
const mcpConfig = JSON.parse(generatedFiles['.mcp.json']);
294-
grouped.mcps = Object.keys(mcpConfig.mcpServers || {});
295-
} catch (e) {
296-
console.error('Error parsing MCP config:', e);
297-
}
298-
}
299-
300-
let html = '';
301-
302-
if (grouped.agents.length > 0) {
303-
html += `
304-
<div class="bg-cyan-50 border-2 border-black p-3">
305-
<h4 class="font-bold mb-2">🤖 Agents (${grouped.agents.length})</h4>
306-
<ul class="text-sm space-y-1">
307-
${grouped.agents.map(a => {
308-
if (typeof a === 'string') {
309-
// If it's a header match from AGENTS.md (like "## Agent Name")
310-
return `<li>• ${a.replace('## ', '')}</li>`;
311-
} else {
312-
// If it's a file path (fallback for individual files)
313-
return `<li>• ${a.split('/').pop().replace('.yaml', '').replace('.md', '')}</li>`;
314-
}
315-
}).join('')}
316-
</ul>
317-
</div>
318-
`;
319-
}
320-
321-
if (grouped.rules.length > 0) {
322-
html += `
323-
<div class="bg-pink-50 border-2 border-black p-3">
324-
<h4 class="font-bold mb-2">📋 Rules (${grouped.rules.length})</h4>
325-
<ul class="text-sm space-y-1">
326-
${grouped.rules.slice(0, 5).map(r => `<li>• ${r.replace('## ', '')}</li>`).join('')}
327-
${grouped.rules.length > 5 ? `<li class="text-gray-500">... and ${grouped.rules.length - 5} more</li>` : ''}
328-
</ul>
329-
</div>
330-
`;
263+
if (!selectedActions || selectedActions.length === 0) {
264+
container.innerHTML = '<p class="text-gray-500">No tools selected</p>';
265+
return;
331266
}
332267

333-
if (grouped.mcps.length > 0) {
334-
html += `
335-
<div class="bg-yellow-50 border-2 border-black p-3">
336-
<h4 class="font-bold mb-2">🔌 MCPs (${grouped.mcps.length})</h4>
337-
<ul class="text-sm space-y-1">
338-
${grouped.mcps.map(m => `<li>• ${m}</li>`).join('')}
339-
</ul>
340-
</div>
341-
`;
268+
try {
269+
// Fetch details for all selected actions
270+
const response = await fetch('/api/actions?limit=100');
271+
const data = await response.json();
272+
const allActions = data.actions || [];
273+
274+
// Filter to get only selected actions
275+
const selectedActionDetails = allActions.filter(action =>
276+
selectedActions.includes(action.id)
277+
);
278+
279+
// Group actions by type
280+
const grouped = {
281+
agents: [],
282+
rules: [],
283+
rulesets: [],
284+
mcps: [],
285+
packs: []
286+
};
287+
288+
selectedActionDetails.forEach(action => {
289+
if (grouped[action.action_type + 's']) {
290+
grouped[action.action_type + 's'].push(action);
291+
} else if (action.action_type === 'ruleset') {
292+
grouped.rulesets.push(action);
293+
} else if (action.action_type === 'pack') {
294+
grouped.packs.push(action);
295+
}
296+
});
297+
298+
let html = '';
299+
300+
// Display each category
301+
Object.entries(grouped).forEach(([type, items]) => {
302+
if (items.length === 0) return;
303+
304+
const typeColors = {
305+
agents: { bg: 'bg-cyan-50', icon: '🤖' },
306+
rules: { bg: 'bg-pink-50', icon: '📋' },
307+
rulesets: { bg: 'bg-pink-50', icon: '📚' },
308+
mcps: { bg: 'bg-yellow-50', icon: '🔌' },
309+
packs: { bg: 'bg-purple-50', icon: '📦' }
310+
};
311+
312+
const config = typeColors[type] || { bg: 'bg-gray-50', icon: '⚙️' };
313+
const displayName = type.charAt(0).toUpperCase() + type.slice(1);
314+
315+
html += `
316+
<div class="${config.bg} border-2 border-black p-3 mb-3">
317+
<h4 class="font-bold mb-2">${config.icon} ${displayName} (${items.length})</h4>
318+
<ul class="text-sm space-y-1">
319+
${items.slice(0, 8).map(item =>
320+
`<li>• ${item.display_name || item.name}</li>`
321+
).join('')}
322+
${items.length > 8 ? `<li class="text-gray-500">... and ${items.length - 8} more</li>` : ''}
323+
</ul>
324+
</div>
325+
`;
326+
});
327+
328+
container.innerHTML = html || '<p class="text-gray-500">No tools selected</p>';
329+
} catch (error) {
330+
console.error('Error loading action details:', error);
331+
container.innerHTML = '<p class="text-red-500">Error loading selected tools</p>';
342332
}
343-
344-
container.innerHTML = html || '<p class="text-gray-500">No tools selected</p>';
345333
}
346334

347335
function displayFilePreviews() {

0 commit comments

Comments
 (0)