gitlink-cli/gitlink-web/templates/skill.html

169 lines
7.7 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block content %}
<div class="max-w-4xl mx-auto">
<a href="/skills/" class="text-blue-600 hover:underline text-sm mb-4 inline-block">&larr; 返回首页</a>
<h1 class="text-3xl font-bold text-gray-800 mb-2">{{ info.title }}</h1>
{% if skill_name.startswith("lab-") and info.intro %}
<div class="bg-green-50 border border-green-200 rounded-xl p-4 mb-6 text-sm text-green-800">
{{ info.intro }}
</div>
{% endif %}
<!-- 功能介绍 + 预期输出 -->
<div class="space-y-2 mb-6">
<details class="bg-white border border-gray-200 rounded-xl overflow-hidden">
<summary class="px-4 py-3 cursor-pointer font-medium text-gray-700 hover:bg-gray-50 transition flex items-center gap-2">
<span class="text-blue-500">📖</span> 功能介绍
</summary>
<div class="px-4 py-3 text-sm text-gray-600 border-t border-gray-100">
{% if info.intro %}{{ info.intro }}{% endif %}
</div>
</details>
<details class="bg-white border border-gray-200 rounded-xl overflow-hidden">
<summary class="px-4 py-3 cursor-pointer font-medium text-gray-700 hover:bg-gray-50 transition flex items-center gap-2">
<span class="text-blue-500">📋</span> 预期输出格式与内容
</summary>
<div class="px-4 py-3 text-sm text-gray-600 border-t border-gray-100">
{% if info.output_desc %}{{ info.output_desc|replace('\n', '<br>')|safe }}{% else %}
<p>生成中文分析报告,包含:总览、详细分析、排行榜、建议等。</p>
{% endif %}
</div>
</details>
</div>
<!-- 输入表单 -->
<div class="bg-white rounded-xl shadow-sm p-6 mb-8">
<label class="block font-medium text-gray-700 mb-2">{{ info.prompt_label }}</label>
<input id="user-input" type="text"
class="w-full border rounded-lg px-4 py-3 text-gray-700 focus:ring-2 focus:ring-blue-300 focus:border-blue-400 outline-none"
placeholder="{{ info.prompt_placeholder }}">
<p id="hint-text" class="text-sm text-gray-400 mt-2"></p>
<button onclick="runSkill()" id="run-btn"
class="mt-4 bg-blue-600 hover:bg-blue-700 text-white font-medium px-6 py-3 rounded-lg transition disabled:opacity-50">
🚀 开始分析
</button>
</div>
<!-- 进度 -->
<div id="progress" class="hidden mb-6">
<div class="bg-white rounded-xl shadow-sm p-6">
<div class="flex items-center gap-3 mb-4">
<div class="animate-spin w-5 h-5 border-2 border-blue-600 border-t-transparent rounded-full"></div>
<span class="text-gray-600 font-medium">AI 正在分析中...</span>
</div>
<div id="log" class="text-sm text-gray-500 space-y-1 font-mono max-h-48 overflow-y-auto"></div>
</div>
</div>
<!-- 报告输出 -->
<div id="report" class="hidden">
<div class="bg-white rounded-xl shadow-sm p-6 overflow-auto">
<div id="report-content" class="markdown-body"></div>
</div>
<div class="mt-4 flex gap-3">
<button onclick="downloadTxt()" class="text-sm bg-gray-100 hover:bg-gray-200 text-gray-700 px-4 py-2 rounded-lg transition font-medium">
📥 下载 TXT
</button>
</div>
</div>
<!-- 错误 -->
<div id="error" class="hidden bg-red-50 border border-red-200 rounded-xl p-6 text-red-700"></div>
</div>
<script>
const skillName = "{{ skill_name }}";
const hints = {
"research-tracker": "例如微服务框架、AI Agent、DevOps 流水线、大模型、数据可视化",
"contributor-insight": "例如ci4s/ci4sManagement-cloud, jiangtx/gitlink-cli",
"issue-triage": "例如Gitlink/gitlink-cli, ci4s/ci4sManagement-cloud",
"ci-health": "例如jiangtx/gitlink-cli, Gitlink/gitlink-cli",
"lab-hotspot": "例如大模型、AI Agent、微服务、DevOps、数据可视化",
"lab-insight": "例如ci4s/ci4sManagement-cloud, Gitlink/gitlink-cli",
"lab-compliance": "例如ci4s/ci4sManagement-cloud, Gitlink/gitlink-cli",
"lab-match": "例如ci4s/ci4sManagement-cloud, Gitlink/gitlink-cli",
"lab-track": "例如ci4s/ci4sManagement-cloud, Gitlink/gitlink-cli",
};
document.getElementById('hint-text').textContent = '💡 ' + (hints[skillName] || '');
function runSkill() {
const input = document.getElementById('user-input').value.trim();
if (!input) { alert('请输入参数'); return; }
document.getElementById('progress').classList.remove('hidden');
document.getElementById('report').classList.add('hidden');
document.getElementById('error').classList.add('hidden');
document.getElementById('run-btn').disabled = true;
document.getElementById('log').innerHTML = '<div>⏳ 提交中...</div>';
fetch('/api/run', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: `skill=${encodeURIComponent(skillName)}&input=${encodeURIComponent(input)}`
})
.then(r => r.json())
.then(data => {
if (data.error) {
document.getElementById('error').classList.remove('hidden');
document.getElementById('error').textContent = '❌ ' + data.error;
return;
}
document.getElementById('log').innerHTML = '<div class="text-green-600">✅ 分析完成</div>';
// Render Markdown
const reportDiv = document.getElementById('report-content');
reportDiv.innerHTML = marked.parse(data.report || '');
document.getElementById('report').classList.remove('hidden');
// Render Mermaid diagrams (find code.language-mermaid)
document.querySelectorAll('code.language-mermaid').forEach((code) => {
const pre = code.parentElement;
const div = document.createElement('div');
div.className = 'mermaid';
div.textContent = code.textContent;
pre.parentElement.replaceChild(div, pre);
});
if (typeof mermaid !== 'undefined') {
mermaid.run({ nodes: document.querySelectorAll('.mermaid') });
}
})
.catch(err => {
document.getElementById('error').classList.remove('hidden');
document.getElementById('error').textContent = '❌ 请求失败: ' + err.message;
})
.finally(() => {
document.getElementById('progress').classList.add('hidden');
document.getElementById('run-btn').disabled = false;
});
}
function downloadTxt() {
const text = document.getElementById('report-content').textContent;
const blob = new Blob([text], { type: 'text/plain;charset=utf-8' });
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = 'report-' + new Date().toISOString().slice(0,10) + '.txt';
a.click();
URL.revokeObjectURL(a.href);
}
</script>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>mermaid.initialize({ startOnLoad: false, theme: 'default' });</script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.5.1/github-markdown.min.css">
<style>
#report-content.markdown-body { padding: 0; }
#report-content.markdown-body table { display: table; width: 100%; }
#report-content.markdown-body pre { background: #f6f8fa; border-radius: 6px; position: relative; }
#report-content.markdown-body code { font-size: 13px; }
#report-content.markdown-body img { max-width: 100%; }
/* Mermaid SVG should be visible */
#report-content.markdown-body .mermaid svg { max-width: 100%; height: auto; }
</style>
{% endblock %}