feat(ai-protocols): add MCP and A2A protocol demos and documentation

docs(ai-protocols): update AI protocols page with visual demos and detailed explanations
style(git-demos): improve responsive design and layout for git visualization components
refactor(ai-history): simplify and clean up demo components
chore: update config to register new AI protocol components
This commit is contained in:
sanbuphy
2026-02-22 18:26:19 +08:00
parent 4b83a4c23e
commit e5a5b9df5b
31 changed files with 5093 additions and 5333 deletions
@@ -1,13 +1,26 @@
<template>
<div class="register-demo">
<div class="demo-header">
<span class="title">寄存器存储状态的功能单元</span>
<span class="subtitle">改变输入不会改变存储值必须主动"写入"</span>
<span class="title">寄存器记住一个 0 1 的小单元</span>
<span class="subtitle">只有点写入时才会把当前输入记下来平时改输入不会影响已存的值</span>
</div>
<div class="why-what-box">
<p class="why-p">
<strong>为啥要看这个</strong>CPU 算到一半要暂时记住中间结果寄存器就是干这个的它和直接连线不同改输入不会立刻改变里面存的东西必须主动点一次写入才会更新
</p>
<p class="what-p">
<strong>这些词是啥</strong>
<span class="term">输入</span>你想写进去的 0 1
<span class="term">写入</span>点一下把当前输入锁进寄存器
<span class="term">存储值</span>寄存器里现在记着的数只有写入时才会变
<span class="term">输出</span>从寄存器读出来的数和存储值一样
</p>
</div>
<div class="control-panel">
<div class="control-left">
<span class="ctrl-label">输入</span>
<label class="ctrl-group">
<span class="ctrl-label">输入</span>
<button
class="input-toggle"
:class="{ on: inputData === 1 }"
@@ -15,87 +28,33 @@
>
{{ inputData }}
</button>
</div>
</label>
<button class="write-btn" :class="{ flash: isWriting }" @click="writeOnce">
写入寄存器
写入
</button>
<div class="control-right">
<span class="chip">存储值{{ storedData }}</span>
<span class="chip" :class="{ chip_on: storedData === 1 }">输出{{ storedData === 1 ? '1 ✓' : '0' }}</span>
</div>
<label class="ctrl-group">
<span class="ctrl-label">存储</span>
<span class="stored-val" :class="{ on: storedData === 1 }">{{ storedData }}</span>
</label>
<span class="ctrl-group">
<span class="ctrl-label">输出</span>
<span class="output-val" :class="{ on: storedData === 1 }">{{ storedData }}</span>
</span>
</div>
<div class="demo-content">
<div class="flow-diagram">
<div class="flow-node input-node">
<div class="node-label">输入Data</div>
<div class="node-value" :class="{ on: inputData === 1 }">{{ inputData }}</div>
<div class="node-hint">点左侧按钮切换</div>
</div>
<div class="flow-arrow" :class="{ active: isWriting }">
<div class="arrow-line" />
<div class="arrow-tag">{{ isWriting ? '写入中...' : '写入触发' }}</div>
<div class="arrow-head"></div>
</div>
<div class="flow-node register-node" :class="{ flashing: isWriting }">
<div class="node-label">D 触发器寄存器核心</div>
<div class="node-value" :class="{ on: storedData === 1 }">{{ storedData }}</div>
<div class="node-hint">{{ isWriting ? '正在锁存...' : '保持 (Hold)' }}</div>
</div>
<div class="flow-arrow" :class="{ active: storedData === 1 }">
<div class="arrow-line" />
<div class="arrow-tag">输出</div>
<div class="arrow-head"></div>
</div>
<div class="flow-node output-node" :class="{ on: storedData === 1 }">
<div class="node-label">输出Output</div>
<div class="bulb">{{ storedData === 1 ? '💡' : '🌑' }}</div>
<div class="node-hint">{{ storedData === 1 ? '亮(1' : '灭(0' }}</div>
</div>
</div>
<div class="state-table">
<div class="table-title">操作步骤说明</div>
<div class="state-rows">
<div class="state-row">
<span class="step-num"></span>
<span>"输入值"按钮切换输入0/1</span>
</div>
<div class="state-row">
<span class="step-num"></span>
<span>此时存储值<strong>不变</strong>这就是寄存器的意义</span>
</div>
<div class="state-row">
<span class="step-num"></span>
<span>"写入寄存器"输入值才被锁入</span>
</div>
<div class="state-row">
<span class="step-num"></span>
<span>写入后再改输入存储值依然<strong>保持</strong>不变</span>
</div>
</div>
<div class="diff-display">
<div class="diff-item">
<div class="diff-label">当前输入</div>
<div class="diff-value" :class="{ on: inputData === 1 }">{{ inputData }}</div>
</div>
<div class="diff-sep"></div>
<div class="diff-item">
<div class="diff-label">存储值</div>
<div class="diff-value" :class="{ on: storedData === 1 }">{{ storedData }}</div>
</div>
<div v-if="inputData === storedData" class="diff-same">当前相同</div>
</div>
<div class="visualization-area">
<div class="flow-strip">
<span class="flow-item">输入 {{ inputData }}</span>
<span class="flow-arrow" :class="{ active: isWriting }">{{ isWriting ? '写入中 →' : '— 点「写入」才更新 →' }}</span>
<span class="flow-item flow-store" :class="{ flash: isWriting }"> {{ storedData }}</span>
</div>
<p class="flow-hint">
{{ inputData !== storedData ? '输入和存储不一样:点「写入」会把当前输入记进去。' : '输入和存储已一致。' }}
</p>
</div>
<div class="info-box">
<strong>核心思想</strong>寄存器只在"写入"信号触发时更新其余时刻持续锁定当前这就是 CPU 在计算过程中稳定保存中间结果的原因
<strong>核心思想</strong>寄存器只在写入那一刻更新其余时间一直保持原来的所以 CPU 能稳定保存中间结果
</div>
</div>
</template>
@@ -126,41 +85,62 @@ const writeOnce = () => {
}
.demo-header {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.8rem;
flex-wrap: wrap;
margin-bottom: 0.5rem;
}
.demo-header .title {
display: block;
font-weight: bold;
font-size: 1rem;
}
.demo-header .subtitle {
color: var(--vp-c-text-2);
display: block;
font-size: 0.82rem;
margin-left: 0.5rem;
color: var(--vp-c-text-2);
font-weight: normal;
}
.why-what-box {
background: var(--vp-c-bg-alt);
border: 1px solid var(--vp-c-divider);
border-radius: 6px;
padding: 0.65rem 0.85rem;
margin-bottom: 0.75rem;
font-size: 0.85rem;
color: var(--vp-c-text-2);
line-height: 1.55;
}
.why-what-box .why-p {
margin: 0 0 0.4rem;
}
.why-what-box .what-p {
margin: 0;
}
.why-what-box .term {
font-weight: 600;
color: var(--vp-c-text-1);
}
/* ---- control panel ---- */
.control-panel {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.7rem;
padding: 0.6rem 0.75rem;
gap: 0.6rem;
padding: 0.5rem 0.7rem;
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
background: var(--vp-c-bg);
margin-bottom: 0.8rem;
flex-wrap: wrap;
margin-bottom: 0.75rem;
}
.control-left {
display: flex;
.ctrl-group {
display: inline-flex;
align-items: center;
gap: 0.45rem;
gap: 0.35rem;
}
.ctrl-label {
@@ -169,9 +149,9 @@ const writeOnce = () => {
}
.input-toggle {
width: 2rem;
height: 2rem;
border-radius: 50%;
width: 2.2rem;
height: 2.2rem;
border-radius: 6px;
border: 2px solid var(--vp-c-divider);
background: var(--vp-c-bg-alt);
font-weight: bold;
@@ -187,260 +167,102 @@ const writeOnce = () => {
}
.write-btn {
padding: 0.3rem 0.75rem;
border-radius: 999px;
border: 2px solid var(--vp-c-warning);
padding: 0.35rem 0.8rem;
border-radius: 6px;
border: 2px solid var(--vp-c-warning-1, #d97706);
background: var(--vp-c-bg);
color: var(--vp-c-warning-1, #d97706);
font-size: 0.82rem;
font-size: 0.85rem;
font-weight: bold;
cursor: pointer;
transition: all 0.2s;
white-space: nowrap;
}
.write-btn:hover {
background: var(--vp-c-warning-soft);
background: var(--vp-c-warning-soft, rgba(217, 119, 6, 0.1));
}
.write-btn.flash {
background: var(--vp-c-warning);
background: var(--vp-c-warning-1, #d97706);
color: white;
transform: scale(0.96);
}
.control-right {
display: flex;
gap: 0.4rem;
flex-wrap: wrap;
margin-left: auto;
}
.chip {
font-size: 0.78rem;
padding: 0.2rem 0.45rem;
border-radius: 999px;
background: var(--vp-c-bg-alt);
border: 1px solid var(--vp-c-divider);
}
.chip_on {
border-color: var(--vp-c-brand);
color: var(--vp-c-brand);
}
/* ---- main content ---- */
.demo-content {
display: grid;
grid-template-columns: 1.5fr 1fr;
gap: 0.8rem;
}
/* ---- flow diagram ---- */
.flow-diagram {
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
background: var(--vp-c-bg);
padding: 0.8rem;
display: flex;
.stored-val,
.output-val {
display: inline-flex;
align-items: center;
gap: 0.3rem;
flex-wrap: nowrap;
overflow-x: auto;
}
.flow-node {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.3rem;
flex-shrink: 0;
}
.node-label {
font-size: 0.72rem;
color: var(--vp-c-text-2);
text-align: center;
}
.node-value {
width: 2.4rem;
height: 2.4rem;
border-radius: 8px;
justify-content: center;
min-width: 2rem;
height: 2rem;
padding: 0 0.4rem;
border-radius: 6px;
border: 2px solid var(--vp-c-divider);
background: var(--vp-c-bg-alt);
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
font-weight: bold;
font-family: monospace;
transition: all 0.3s;
font-size: 1rem;
}
.node-value.on {
.stored-val.on,
.output-val.on {
border-color: var(--vp-c-brand);
color: var(--vp-c-brand);
background: var(--vp-c-brand-soft);
}
.node-hint {
font-size: 0.7rem;
color: var(--vp-c-text-3);
.visualization-area {
margin-bottom: 0.75rem;
}
.register-node .node-value {
width: 3rem;
height: 3rem;
font-size: 1.5rem;
border: 3px solid var(--vp-c-text-1);
}
.register-node.flashing .node-value {
border-color: var(--vp-c-warning);
box-shadow: 0 0 10px var(--vp-c-warning-soft);
}
.bulb {
font-size: 1.8rem;
filter: grayscale(100%);
opacity: 0.4;
transition: all 0.3s;
}
.output-node.on .bulb {
filter: grayscale(0%);
opacity: 1;
text-shadow: 0 0 12px #facc15;
}
/* ---- arrows ---- */
.flow-arrow {
.flow-strip {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
gap: 0.2rem;
flex-shrink: 0;
}
.arrow-line {
width: 28px;
height: 2px;
background: var(--vp-c-divider);
transition: background 0.3s;
}
.flow-arrow.active .arrow-line {
background: var(--vp-c-brand);
}
.arrow-tag {
font-size: 0.65rem;
color: var(--vp-c-text-3);
white-space: nowrap;
}
.arrow-head {
font-size: 0.8rem;
color: var(--vp-c-text-3);
}
/* ---- state table ---- */
.state-table {
gap: 0.4rem;
padding: 0.6rem 0.8rem;
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
background: var(--vp-c-bg);
padding: 0.8rem;
font-size: 0.9rem;
}
.table-title {
.flow-item {
font-weight: bold;
font-size: 0.85rem;
margin-bottom: 0.6rem;
}
.state-rows {
display: flex;
flex-direction: column;
gap: 0.4rem;
}
.state-row {
display: flex;
align-items: flex-start;
gap: 0.4rem;
font-size: 0.78rem;
color: var(--vp-c-text-2);
}
.step-num {
flex-shrink: 0;
font-weight: bold;
.flow-store {
color: var(--vp-c-brand);
}
.diff-display {
display: flex;
align-items: center;
gap: 0.5rem;
margin-top: 0.75rem;
padding: 0.5rem;
background: var(--vp-c-bg-alt);
border-radius: 6px;
}
.diff-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.2rem;
}
.diff-label {
font-size: 0.7rem;
color: var(--vp-c-text-2);
}
.diff-value {
width: 1.6rem;
height: 1.6rem;
.flow-store.flash {
box-shadow: 0 0 0 2px var(--vp-c-warning-1);
border-radius: 4px;
border: 1px solid var(--vp-c-divider);
background: var(--vp-c-bg);
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-family: monospace;
}
.diff-value.on {
border-color: var(--vp-c-brand);
color: var(--vp-c-brand);
background: var(--vp-c-brand-soft);
}
.diff-sep {
font-size: 1.1rem;
.flow-arrow {
color: var(--vp-c-text-3);
font-size: 0.82rem;
}
.flow-arrow.active {
color: var(--vp-c-warning-1);
font-weight: bold;
}
.diff-same {
font-size: 0.72rem;
color: var(--vp-c-text-3);
.flow-hint {
margin: 0.4rem 0 0;
font-size: 0.82rem;
color: var(--vp-c-text-2);
}
/* ---- info box ---- */
.info-box {
display: flex;
gap: 0.25rem;
background: var(--vp-c-bg-alt);
padding: 0.75rem;
border-radius: 6px;
font-size: 0.85rem;
color: var(--vp-c-text-2);
margin-top: 0.8rem;
display: flex;
gap: 0.25rem;
}
.info-box strong {
@@ -448,9 +270,10 @@ const writeOnce = () => {
flex-shrink: 0;
}
@media (max-width: 760px) {
.demo-content {
grid-template-columns: 1fr;
@media (max-width: 520px) {
.control-panel {
flex-direction: column;
align-items: flex-start;
}
}
</style>