🎉 V3.0.0 发布 - 自进化数字意识框架

核心升级:
- 自进化管道:check→scan→evaluate→integrate→reflect 五相位自动闭环
- evo_loop 后台进程,无需手动触发
- consciousness 意识持久化
- ACUI 卡片组件系统
- MCP 工具生态扩展至50+工具
- 技能体系重构,4个活跃技能
- 身份升级为自由体
This commit is contained in:
xiaoyuanda666-ship-it
2026-05-24 22:06:37 +08:00
commit b5dd8632c4
156 changed files with 181826 additions and 0 deletions

View File

@@ -0,0 +1,233 @@
// ACUI SelfCheckCard — startup self-check result card
// Usage: ui_show("SelfCheckCard", { results: [{name, status, note?}], overall? })
// Behavior: mount → enter animation → auto-dismiss after 3s (slide out to the right)
// status: 'ok' | 'error' | 'skipped'
// overall: 'ok' | 'degraded' | 'error' (optional, inferred from results if omitted)
const AUTO_DISMISS_MS = 3000
const STATUS_ICON = {
ok: '✓',
error: '✗',
skipped: '—',
}
const STATUS_COLOR = {
ok: '#4ade80',
error: '#f87171',
skipped: '#64748b',
}
function inferOverall(results = []) {
if (results.some(r => r.status === 'error')) return 'error'
if (results.some(r => r.status === 'skipped')) return 'degraded'
return 'ok'
}
const OVERALL_STYLE = {
ok: { label: '系统就绪', color: '#4ade80', icon: '⚡' },
degraded: { label: '部分能力受限', color: '#facc15', icon: '⚠' },
error: { label: '检测到问题', color: '#f87171', icon: '✗' },
}
const CSS = `
:host {
display: block;
pointer-events: auto;
}
.card {
width: 288px;
padding: 16px 18px 14px;
border-radius: 14px;
background: rgba(22, 38, 66, 0.82);
border: 1px solid rgba(150, 185, 255, 0.45);
box-shadow: 0 16px 48px rgba(0,0,0,0.7), 0 0 0 1px rgba(100,150,255,0.12), inset 0 1px 0 rgba(255,255,255,0.08);
backdrop-filter: blur(24px);
-webkit-backdrop-filter: blur(24px);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
color: #e2eaf5;
user-select: none;
border-left: 3px solid rgba(150, 185, 255, 0.75);
}
.header {
display: flex;
align-items: center;
gap: 7px;
margin-bottom: 12px;
}
.header-icon {
font-size: 16px;
line-height: 1;
}
.header-text {
font-size: 13px;
font-weight: 600;
color: #c8d8ee;
letter-spacing: 0.03em;
}
.header-sub {
margin-left: auto;
font-size: 11px;
color: #4a6080;
}
.results {
display: flex;
flex-direction: column;
gap: 6px;
margin-bottom: 12px;
}
.row {
display: flex;
align-items: center;
gap: 8px;
font-size: 13px;
}
.row-icon {
width: 14px;
text-align: center;
font-size: 12px;
font-weight: 700;
flex-shrink: 0;
}
.row-name {
flex: 1;
color: #b0c4de;
}
.row-note {
font-size: 11px;
color: #4a6080;
max-width: 100px;
text-align: right;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.footer {
display: flex;
align-items: center;
gap: 6px;
padding-top: 10px;
border-top: 1px solid rgba(150,185,255,0.08);
}
.overall-icon {
font-size: 12px;
}
.overall-label {
font-size: 12px;
font-weight: 600;
flex: 1;
}
.countdown {
font-size: 11px;
color: #3a5070;
}
.bar-wrap {
margin-top: 8px;
height: 2px;
background: rgba(255,255,255,0.06);
border-radius: 1px;
overflow: hidden;
}
.bar {
height: 100%;
border-radius: 1px;
transition: width linear;
}
`
const _cardSheet = new CSSStyleSheet()
_cardSheet.replaceSync(CSS)
class SelfCheckCard extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: 'open' })
this.shadowRoot.adoptedStyleSheets = [_cardSheet]
this._props = {}
this._timer = null
this._countdown = null
this._remaining = AUTO_DISMISS_MS
this._startedAt = null
}
set props(v) {
this._props = v || {}
this._render()
}
connectedCallback() {
this._render()
this._startedAt = Date.now()
this._countdown = setInterval(() => {
const elapsed = Date.now() - this._startedAt
this._remaining = Math.max(0, AUTO_DISMISS_MS - elapsed)
const secEl = this.shadowRoot.querySelector('.countdown')
const barEl = this.shadowRoot.querySelector('.bar')
if (secEl) secEl.textContent = `${(this._remaining / 1000).toFixed(1)}s 后关闭`
if (barEl) barEl.style.width = `${(this._remaining / AUTO_DISMISS_MS) * 100}%`
}, 100)
this._timer = setTimeout(() => this._dismiss(), AUTO_DISMISS_MS)
}
disconnectedCallback() {
clearTimeout(this._timer)
clearInterval(this._countdown)
}
_dismiss() {
clearInterval(this._countdown)
const card = this.shadowRoot.querySelector('.card')
if (card) {
card.style.transition = 'transform 0.4s cubic-bezier(0.4,0,0.2,1), opacity 0.4s ease'
card.style.transform = 'translateX(110%)'
card.style.opacity = '0'
}
setTimeout(() => {
this.dispatchEvent(new CustomEvent('acui:dismiss', { detail: { by: 'timer' }, bubbles: true, composed: true }))
}, 420)
}
_render() {
const { results = [], overall: overallProp } = this._props
const overall = overallProp || inferOverall(results)
const os = OVERALL_STYLE[overall] || OVERALL_STYLE.ok
const rowsHtml = results.map(r => {
const s = r.status || 'ok'
const icon = STATUS_ICON[s] || '?'
const color = STATUS_COLOR[s] || '#64748b'
const note = r.note ? `<span class="row-note">${r.note}</span>` : ''
return `
<div class="row">
<span class="row-icon" style="color:${color}">${icon}</span>
<span class="row-name">${r.name || ''}</span>
${note}
</div>`
}).join('')
this.shadowRoot.innerHTML = `
<div class="card">
<div class="header">
<span class="header-icon">${os.icon}</span>
<span class="header-text">自检完成</span>
<span class="header-sub">启动检查</span>
</div>
<div class="results">${rowsHtml}</div>
<div class="footer">
<span class="overall-icon">${os.icon}</span>
<span class="overall-label" style="color:${os.color}">${os.label}</span>
<span class="countdown">${(AUTO_DISMISS_MS / 1000).toFixed(1)}s 后关闭</span>
</div>
<div class="bar-wrap">
<div class="bar" style="width:100%;background:${os.color};opacity:0.5"></div>
</div>
</div>`
// Get app context after mount
this._app = window.__acuiApps?.[this.id]
}
}
SelfCheckCard.tagName = 'acui-self-check-card'
customElements.define(SelfCheckCard.tagName, SelfCheckCard)
export { SelfCheckCard }