speccore 8.3.148 → 8.3.150

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "speccore",
3
- "version": "8.3.148",
3
+ "version": "8.3.150",
4
4
  "description": "SpecCore - Code by Spec, Not by Vibe.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -7,4 +7,4 @@
7
7
  .match-result{padding:10px 0}.match-summary{font-weight:600;font-size:14px;margin-bottom:12px}.match-detail{color:var(--muted);font-size:12px;line-height:1.6}
8
8
  /* Pipeline */
9
9
  .pipeline-title{font-weight:600;margin-bottom:16px}.pipeline-steps{display:flex;flex-direction:column;gap:10px}.pipe-step{display:flex;gap:14px;padding:12px 14px;background:rgba(99,102,241,.04);border-left:2px solid var(--purple);border-radius:0 8px 8px 0}.pipe-step .pipe-num{font-family:Orbitron;font-size:20px;font-weight:900;color:var(--purple);min-width:36px}.pipe-step .pipe-cmd{font-weight:600;color:var(--green)}.pipe-step .pipe-args{color:var(--muted);font-size:11px}.pipe-step .pipe-desc{color:var(--muted);font-size:10px;margin-top:4px}.pipe-step .pipe-dep{font-size:9px;color:var(--orange);margin-top:4px}.confirm-bar{text-align:center;padding:14px;margin-top:16px;background:rgba(99,102,241,.08);border:1px dashed rgba(99,102,241,.2);border-radius:8px;color:var(--purple);font-size:12px}
10
- .footer{text-align:center;color:var(--muted);font-size:10px;margin-top:24px;padding-top:16px;border-top:1px solid rgba(255,255,255,.04)}h1{text-shadow:0 0 20px rgba(14,165,233,.35),0 0 60px rgba(14,165,233,.12)!important}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 25% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}h1,h2{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}</style></head><body><div class="scanlines"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><h1>SPECCORE ASK</h1><div class="query">"我想做一个登录功能"</div><div class="badge">🗺️ 任务指引</div><div class="guide-title">已为你规划「新功能开发全流程」(8 步)</div><div class="guide-steps"><div class="guide-step"><div class="step-num">1</div><div class="step-body"><div class="step-cmd">speccore init</div><div class="step-desc">初始化项目(如果还没有)</div></div></div><div class="guide-step"><div class="step-num">2</div><div class="step-body"><div class="step-cmd">speccore doc2spec -f PRD.docx --iter {iteration}</div><div class="step-desc">导入 PRD 文档,AI 分析生成需求规格</div></div></div><div class="guide-step"><div class="step-num">3</div><div class="step-body"><div class="step-cmd">speccore analyze --iteration {iteration} --audit</div><div class="step-desc">AI 分析需求,生成审计报告</div></div></div><div class="guide-step"><div class="step-num">4</div><div class="step-body"><div class="step-cmd">speccore split -f REQUIREMENT.md</div><div class="step-desc">将需求拆分为独立开发任务</div></div></div><div class="guide-step"><div class="step-num">5</div><div class="step-body"><div class="step-cmd">speccore plan --all</div><div class="step-desc">生成任务执行计划,确定优先级和依赖</div></div></div><div class="guide-step"><div class="step-num">6</div><div class="step-body"><div class="step-cmd">speccore execute --auto</div><div class="step-desc">按计划依次执行开发任务</div></div></div><div class="guide-step"><div class="step-num">7</div><div class="step-body"><div class="step-cmd">speccore pr --auto</div><div class="step-desc">代码提交后创建 Pull Request</div></div></div><div class="guide-step"><div class="step-num">8</div><div class="step-body"><div class="step-cmd">speccore done --all</div><div class="step-desc">全部完成后归档收尾</div></div></div></div><div style="text-align:center;margin-top:16px"><a href="speccore-welcome.html" style="color:var(--cyan);font-size:11px;text-decoration:none">← 返回 ask 引导页</a></div><div class="footer">由 SpecCore 驱动 · v8.3.148 · 2026-08-31</div></div></body></html>
10
+ .footer{text-align:center;color:var(--muted);font-size:10px;margin-top:24px;padding-top:16px;border-top:1px solid rgba(255,255,255,.04)}h1{text-shadow:0 0 20px rgba(14,165,233,.35),0 0 60px rgba(14,165,233,.12)!important}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 25% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}h1,h2{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}</style></head><body><div class="scanlines"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><h1>SPECCORE ASK</h1><div class="query">"我想做一个登录功能"</div><div class="badge">🗺️ 任务指引</div><div class="guide-title">已为你规划「新功能开发全流程」(8 步)</div><div class="guide-steps"><div class="guide-step"><div class="step-num">1</div><div class="step-body"><div class="step-cmd">speccore init</div><div class="step-desc">初始化项目(如果还没有)</div></div></div><div class="guide-step"><div class="step-num">2</div><div class="step-body"><div class="step-cmd">speccore doc2spec -f PRD.docx --iter {iteration}</div><div class="step-desc">导入 PRD 文档,AI 分析生成需求规格</div></div></div><div class="guide-step"><div class="step-num">3</div><div class="step-body"><div class="step-cmd">speccore analyze --iteration {iteration} --audit</div><div class="step-desc">AI 分析需求,生成审计报告</div></div></div><div class="guide-step"><div class="step-num">4</div><div class="step-body"><div class="step-cmd">speccore split -f REQUIREMENT.md</div><div class="step-desc">将需求拆分为独立开发任务</div></div></div><div class="guide-step"><div class="step-num">5</div><div class="step-body"><div class="step-cmd">speccore plan --all</div><div class="step-desc">生成任务执行计划,确定优先级和依赖</div></div></div><div class="guide-step"><div class="step-num">6</div><div class="step-body"><div class="step-cmd">speccore execute --auto</div><div class="step-desc">按计划依次执行开发任务</div></div></div><div class="guide-step"><div class="step-num">7</div><div class="step-body"><div class="step-cmd">speccore pr --auto</div><div class="step-desc">代码提交后创建 Pull Request</div></div></div><div class="guide-step"><div class="step-num">8</div><div class="step-body"><div class="step-cmd">speccore done --all</div><div class="step-desc">全部完成后归档收尾</div></div></div></div><div style="text-align:center;margin-top:16px"><a href="speccore-welcome.html" style="color:var(--cyan);font-size:11px;text-decoration:none">← 返回 ask 引导页</a></div><div class="footer">由 SpecCore 驱动 · v8.3.150 · 2026-08-31</div></div></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html lang="zh-CN" data-theme="ocean"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>SpecCore · ask --pipeline</title><style>@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700;900&family=JetBrains+Mono:wght@400;600;700&display=swap');[data-theme="ocean"]{--cyan:#0ea5e9;--bg:#0b1929;--card:rgba(13,31,56,.95);--border:rgba(14,165,233,.15);--text:#bae6fd;--muted:#5b7fa5;--green:#14b8a6;--orange:#f97316;--purple:#6366f1}*{margin:0;padding:0;box-sizing:border-box}body{font-family:'JetBrains Mono',monospace;background:var(--bg);color:var(--text);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}.scanlines{position:fixed;inset:0;pointer-events:none;z-index:99;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,240,255,.01) 2px,rgba(0,240,255,.01) 4px)}.card{max-width:900px;width:100%;margin:0 auto;background:var(--card);border:1px solid var(--border);border-radius:16px;padding:32px;position:relative;overflow:hidden;z-index:1}.card::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX 3s linear infinite}.card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX-rev 3s linear infinite}@keyframes scanX{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}@keyframes scanX-rev{0%{transform:translateX(100%)}100%{transform:translateX(-100%)}}@keyframes scanY{0%{transform:translateY(-100%)}100%{transform:translateY(100%)}}@keyframes scanY-rev{0%{transform:translateY(100%)}100%{transform:translateY(-100%)}}.vline{position:absolute;top:0;width:1px;bottom:0;pointer-events:none}.vline.l{left:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY-rev 3s linear infinite}.vline.r{right:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY 3s linear infinite}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 25% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.page-title{font-family:'Orbitron',sans-serif;font-size:22px;font-weight:700;text-align:center;color:var(--cyan);margin-bottom:32px;letter-spacing:1px;text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}.page-title span{color:var(--text);font-weight:500}.flow-chart{display:flex;align-items:stretch;gap:0;margin-bottom:28px}.flow-node{flex:1;background:rgba(13,31,56,.7);border:1px solid;border-radius:10px;padding:14px 8px;text-align:center;position:relative}.flow-node .icon{font-size:18px;margin-bottom:6px}.flow-node .name{font-size:12px;font-weight:600;margin-bottom:4px}.flow-node .desc{font-size:10px;color:var(--muted)}.flow-node.n1{border-color:rgba(14,165,233,.4);color:var(--cyan)}.flow-node.n2{border-color:rgba(99,102,241,.4);color:var(--purple)}.flow-node.n3{border-color:rgba(14,165,233,.4);color:var(--cyan)}.flow-node.n4{border-color:rgba(20,184,166,.4);color:var(--green)}.flow-connector{width:24px;display:flex;align-items:center;justify-content:center}.flow-connector::after{content:'';width:100%;height:1px;background:linear-gradient(90deg,var(--border),var(--cyan),var(--border))}.example-box{border:1px dashed rgba(14,165,233,.3);border-radius:12px;padding:16px 20px;margin-bottom:24px;background:rgba(14,165,233,.03)}.example-label{font-size:13px;font-weight:600;color:var(--cyan);margin-bottom:8px}.example-query{font-family:'JetBrains Mono',monospace;font-size:14px;color:var(--text)}.example-query code{color:var(--green);font-weight:600}.steps{display:flex;flex-direction:column;gap:12px;margin-bottom:24px}.step{background:rgba(13,31,56,.8);border:1px solid rgba(14,165,233,.12);border-radius:10px;padding:14px 18px}.step-num{font-family:'Orbitron',sans-serif;font-size:14px;font-weight:700;color:var(--green);margin-bottom:6px}.step-cmd{font-family:'JetBrains Mono',monospace;font-size:14px;color:var(--text);margin-bottom:6px}.step-cmd .cmd-name{color:var(--green)}.step-cmd .cmd-args{color:var(--muted)}.step-parse{font-size:12px;color:var(--muted);line-height:1.5}.step-parse::before{content:'→ 解析:';color:var(--cyan)}.confirm-btn{display:block;width:100%;max-width:420px;margin:0 auto 16px;text-align:center;padding:16px;background:linear-gradient(135deg,var(--cyan),#0284c7);border:none;border-radius:40px;color:#fff;font-size:15px;font-weight:600;cursor:pointer;box-shadow:0 0 30px rgba(14,165,233,.3)}.legend{display:flex;justify-content:center;gap:20px;font-size:11px;color:var(--muted);margin-bottom:16px;flex-wrap:wrap}.legend-item{display:flex;align-items:center;gap:4px}.legend-dot{width:8px;height:8px;border-radius:50%;display:inline-block}.legend-dot.required{background:var(--cyan)}.legend-dot.generated{background:var(--green)}.legend-dot.pending{background:rgba(255,255,255,.3)}.back-link{text-align:center;margin-top:12px}.back-link a{color:var(--cyan);font-size:11px;text-decoration:none}.footer{text-align:center;color:var(--muted);font-size:10px;margin-top:20px}</style></head><body><div class="scanlines"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><div class="page-title">ask --pipeline <span>多步骤编排引擎</span></div><div class="flow-chart"><div class="flow-node n1"><div class="icon">🧠</div><div class="name">AI 意图分解</div><div class="desc">LLM 分解多步骤</div></div><div class="flow-connector"></div><div class="flow-node n2"><div class="icon">📐</div><div class="name">命令匹配</div><div class="desc">意图→命令图</div></div><div class="flow-connector"></div><div class="flow-node n3"><div class="icon">🔗</div><div class="name">依赖解析</div><div class="desc">顺序/并行/参数</div></div><div class="flow-connector"></div><div class="flow-node n4"><div class="icon">✅</div><div class="name">预览</div><div class="desc">展示给用户</div></div></div><div class="example-box"><div class="example-label">📋 示例:<span class="example-query"><code>/spec-ask "本期迭代:从 PRD 导入到代码提交,跑完整开发流程"</code></span></div></div><div class="steps"><div class="step"><div class="step-num">1.</div><div class="step-cmd"><span class="cmd-name">speccore doc2spec</span> <span class="cmd-args">-f PRD.docx --iter {iteration}</span></div><div class="step-parse">导入 PRD 文档,AI 分析生成需求规格说明书</div></div><div class="step"><div class="step-num">2.</div><div class="step-cmd"><span class="cmd-name">speccore analyze</span> <span class="cmd-args">--iteration {iteration} --audit</span></div><div class="step-parse">AI 深度分析需求,生成审计报告和可行性评估</div></div><div class="step"><div class="step-num">3.</div><div class="step-cmd"><span class="cmd-name">speccore split</span> <span class="cmd-args">-f REQUIREMENT.md</span></div><div class="step-parse">将需求拆分为独立开发任务,确定优先级和依赖关系</div></div><div class="step"><div class="step-num">4.</div><div class="step-cmd"><span class="cmd-name">speccore execute</span> <span class="cmd-args">--auto</span></div><div class="step-parse">按任务计划依次自动执行开发、测试和代码生成</div></div><div class="step"><div class="step-num">5.</div><div class="step-cmd"><span class="cmd-name">speccore pr</span> <span class="cmd-args">--auto</span></div><div class="step-parse">代码提交后自动创建 Pull Request,完成交付</div></div></div><div class="confirm-btn">确认执行? (y/N) 或修改参数</div><div class="legend"><div class="legend-item"><span class="legend-dot required"></span> = 必选步骤</div><div class="legend-item"><span class="legend-dot generated"></span> = 已生成</div><div class="legend-item"><span class="legend-dot pending"></span> = 待执行</div><div class="legend-item">→ = 依赖传递</div></div><div class="back-link"><a href="speccore-welcome.html">← 返回 ask 引导页</a></div><div class="footer">由 SpecCore 驱动 · v8.3.148 · 2026-08-31</div></div></body></html>
1
+ <!DOCTYPE html><html lang="zh-CN" data-theme="ocean"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>SpecCore · ask --pipeline</title><style>@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700;900&family=JetBrains+Mono:wght@400;600;700&display=swap');[data-theme="ocean"]{--cyan:#0ea5e9;--bg:#0b1929;--card:rgba(13,31,56,.95);--border:rgba(14,165,233,.15);--text:#bae6fd;--muted:#5b7fa5;--green:#14b8a6;--orange:#f97316;--purple:#6366f1}*{margin:0;padding:0;box-sizing:border-box}body{font-family:'JetBrains Mono',monospace;background:var(--bg);color:var(--text);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}.scanlines{position:fixed;inset:0;pointer-events:none;z-index:99;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,240,255,.01) 2px,rgba(0,240,255,.01) 4px)}.card{max-width:900px;width:100%;margin:0 auto;background:var(--card);border:1px solid var(--border);border-radius:16px;padding:32px;position:relative;overflow:hidden;z-index:1}.card::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX 3s linear infinite}.card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX-rev 3s linear infinite}@keyframes scanX{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}@keyframes scanX-rev{0%{transform:translateX(100%)}100%{transform:translateX(-100%)}}@keyframes scanY{0%{transform:translateY(-100%)}100%{transform:translateY(100%)}}@keyframes scanY-rev{0%{transform:translateY(100%)}100%{transform:translateY(-100%)}}.vline{position:absolute;top:0;width:1px;bottom:0;pointer-events:none}.vline.l{left:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY-rev 3s linear infinite}.vline.r{right:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY 3s linear infinite}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 25% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.page-title{font-family:'Orbitron',sans-serif;font-size:22px;font-weight:700;text-align:center;color:var(--cyan);margin-bottom:32px;letter-spacing:1px;text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}.page-title span{color:var(--text);font-weight:500}.flow-chart{display:flex;align-items:stretch;gap:0;margin-bottom:28px}.flow-node{flex:1;background:rgba(13,31,56,.7);border:1px solid;border-radius:10px;padding:14px 8px;text-align:center;position:relative}.flow-node .icon{font-size:18px;margin-bottom:6px}.flow-node .name{font-size:12px;font-weight:600;margin-bottom:4px}.flow-node .desc{font-size:10px;color:var(--muted)}.flow-node.n1{border-color:rgba(14,165,233,.4);color:var(--cyan)}.flow-node.n2{border-color:rgba(99,102,241,.4);color:var(--purple)}.flow-node.n3{border-color:rgba(14,165,233,.4);color:var(--cyan)}.flow-node.n4{border-color:rgba(20,184,166,.4);color:var(--green)}.flow-connector{width:24px;display:flex;align-items:center;justify-content:center}.flow-connector::after{content:'';width:100%;height:1px;background:linear-gradient(90deg,var(--border),var(--cyan),var(--border))}.example-box{border:1px dashed rgba(14,165,233,.3);border-radius:12px;padding:16px 20px;margin-bottom:24px;background:rgba(14,165,233,.03)}.example-label{font-size:13px;font-weight:600;color:var(--cyan);margin-bottom:8px}.example-query{font-family:'JetBrains Mono',monospace;font-size:14px;color:var(--text)}.example-query code{color:var(--green);font-weight:600}.steps{display:flex;flex-direction:column;gap:12px;margin-bottom:24px}.step{background:rgba(13,31,56,.8);border:1px solid rgba(14,165,233,.12);border-radius:10px;padding:14px 18px}.step-num{font-family:'Orbitron',sans-serif;font-size:14px;font-weight:700;color:var(--green);margin-bottom:6px}.step-cmd{font-family:'JetBrains Mono',monospace;font-size:14px;color:var(--text);margin-bottom:6px}.step-cmd .cmd-name{color:var(--green)}.step-cmd .cmd-args{color:var(--muted)}.step-parse{font-size:12px;color:var(--muted);line-height:1.5}.step-parse::before{content:'→ 解析:';color:var(--cyan)}.confirm-btn{display:block;width:100%;max-width:420px;margin:0 auto 16px;text-align:center;padding:16px;background:linear-gradient(135deg,var(--cyan),#0284c7);border:none;border-radius:40px;color:#fff;font-size:15px;font-weight:600;cursor:pointer;box-shadow:0 0 30px rgba(14,165,233,.3)}.legend{display:flex;justify-content:center;gap:20px;font-size:11px;color:var(--muted);margin-bottom:16px;flex-wrap:wrap}.legend-item{display:flex;align-items:center;gap:4px}.legend-dot{width:8px;height:8px;border-radius:50%;display:inline-block}.legend-dot.required{background:var(--cyan)}.legend-dot.generated{background:var(--green)}.legend-dot.pending{background:rgba(255,255,255,.3)}.back-link{text-align:center;margin-top:12px}.back-link a{color:var(--cyan);font-size:11px;text-decoration:none}.footer{text-align:center;color:var(--muted);font-size:10px;margin-top:20px}</style></head><body><div class="scanlines"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><div class="page-title">ask --pipeline <span>多步骤编排引擎</span></div><div class="flow-chart"><div class="flow-node n1"><div class="icon">🧠</div><div class="name">AI 意图分解</div><div class="desc">LLM 分解多步骤</div></div><div class="flow-connector"></div><div class="flow-node n2"><div class="icon">📐</div><div class="name">命令匹配</div><div class="desc">意图→命令图</div></div><div class="flow-connector"></div><div class="flow-node n3"><div class="icon">🔗</div><div class="name">依赖解析</div><div class="desc">顺序/并行/参数</div></div><div class="flow-connector"></div><div class="flow-node n4"><div class="icon">✅</div><div class="name">预览</div><div class="desc">展示给用户</div></div></div><div class="example-box"><div class="example-label">📋 示例:<span class="example-query"><code>/spec-ask "本期迭代:从 PRD 导入到代码提交,跑完整开发流程"</code></span></div></div><div class="steps"><div class="step"><div class="step-num">1.</div><div class="step-cmd"><span class="cmd-name">speccore doc2spec</span> <span class="cmd-args">-f PRD.docx --iter {iteration}</span></div><div class="step-parse">导入 PRD 文档,AI 分析生成需求规格说明书</div></div><div class="step"><div class="step-num">2.</div><div class="step-cmd"><span class="cmd-name">speccore analyze</span> <span class="cmd-args">--iteration {iteration} --audit</span></div><div class="step-parse">AI 深度分析需求,生成审计报告和可行性评估</div></div><div class="step"><div class="step-num">3.</div><div class="step-cmd"><span class="cmd-name">speccore split</span> <span class="cmd-args">-f REQUIREMENT.md</span></div><div class="step-parse">将需求拆分为独立开发任务,确定优先级和依赖关系</div></div><div class="step"><div class="step-num">4.</div><div class="step-cmd"><span class="cmd-name">speccore execute</span> <span class="cmd-args">--auto</span></div><div class="step-parse">按任务计划依次自动执行开发、测试和代码生成</div></div><div class="step"><div class="step-num">5.</div><div class="step-cmd"><span class="cmd-name">speccore pr</span> <span class="cmd-args">--auto</span></div><div class="step-parse">代码提交后自动创建 Pull Request,完成交付</div></div></div><div class="confirm-btn">确认执行? (y/N) 或修改参数</div><div class="legend"><div class="legend-item"><span class="legend-dot required"></span> = 必选步骤</div><div class="legend-item"><span class="legend-dot generated"></span> = 已生成</div><div class="legend-item"><span class="legend-dot pending"></span> = 待执行</div><div class="legend-item">→ = 依赖传递</div></div><div class="back-link"><a href="speccore-welcome.html">← 返回 ask 引导页</a></div><div class="footer">由 SpecCore 驱动 · v8.3.150 · 2026-08-31</div></div></body></html>
@@ -7,4 +7,4 @@
7
7
  .match-result{padding:10px 0}.match-summary{font-weight:600;font-size:14px;margin-bottom:12px}.match-detail{color:var(--muted);font-size:12px;line-height:1.6}
8
8
  /* Pipeline */
9
9
  .pipeline-title{font-weight:600;margin-bottom:16px}.pipeline-steps{display:flex;flex-direction:column;gap:10px}.pipe-step{display:flex;gap:14px;padding:12px 14px;background:rgba(99,102,241,.04);border-left:2px solid var(--purple);border-radius:0 8px 8px 0}.pipe-step .pipe-num{font-family:Orbitron;font-size:20px;font-weight:900;color:var(--purple);min-width:36px}.pipe-step .pipe-cmd{font-weight:600;color:var(--green)}.pipe-step .pipe-args{color:var(--muted);font-size:11px}.pipe-step .pipe-desc{color:var(--muted);font-size:10px;margin-top:4px}.pipe-step .pipe-dep{font-size:9px;color:var(--orange);margin-top:4px}.confirm-bar{text-align:center;padding:14px;margin-top:16px;background:rgba(99,102,241,.08);border:1px dashed rgba(99,102,241,.2);border-radius:8px;color:var(--purple);font-size:12px}
10
- .footer{text-align:center;color:var(--muted);font-size:10px;margin-top:24px;padding-top:16px;border-top:1px solid rgba(255,255,255,.04)}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 25% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}h1,h2{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}</style></head><body><div class="scanlines"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><h1>SPECCORE ASK</h1><div class="query">"dashboard"</div><div class="badge">🎯 意图匹配</div><div class="match-result"><div class="match-summary">✅ 推荐: dashboard</div><div class="match-detail">🎯 推荐命令: <code>speccore dashboard<br>项目仪表盘:期次状态/进度/健康度,--scope</code> global 全量视图<br><br>用法: <code>speccore dashboard</code> [--scope global|iteration] [--export html] [--health] [--lifecycle]<br><br>示例:<br> $ <code>speccore dashboard<br></code> $ <code>speccore dashboard</code> --scope global --export html</div></div><div class="footer">由 SpecCore 驱动 v8.3.148 · 2026-08-31</div></div></body></html>
10
+ .footer{text-align:center;color:var(--muted);font-size:10px;margin-top:24px;padding-top:16px;border-top:1px solid rgba(255,255,255,.04)}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 25% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}h1,h2{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}</style></head><body><div class="scanlines"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><h1>SPECCORE ASK</h1><div class="query">"dashboard"</div><div class="badge">🎯 意图匹配</div><div class="match-result"><div class="match-summary">✅ 推荐: dashboard</div><div class="match-detail">🎯 推荐命令: <code>speccore dashboard<br>项目仪表盘:期次状态/进度/健康度,--scope</code> global 全量视图<br><br>用法: <code>speccore dashboard</code> [--scope global|iteration] [--export html] [--health] [--lifecycle]<br><br>示例:<br> $ <code>speccore dashboard<br></code> $ <code>speccore dashboard</code> --scope global --export html</div></div><div class="footer">由 SpecCore 驱动 v8.3.150 · 2026-08-31</div></div></body></html>
@@ -40,7 +40,7 @@
40
40
  </div>
41
41
  </div>
42
42
 
43
- <div class="footer">由 SpecCore 驱动 v8.3.148 | 2026-08-31</div>
43
+ <div class="footer">由 SpecCore 驱动 v8.3.150 | 2026-08-31</div>
44
44
 
45
45
  <script>
46
46
  const STATE = {&quot;iteration&quot;:&quot;期次-Q2&quot;,&quot;phases&quot;:[{&quot;name&quot;:&quot;初始化&quot;,&quot;key&quot;:&quot;init&quot;,&quot;done&quot;:true,&quot;icon&quot;:&quot;🏗️&quot;,&quot;cmd&quot;:&quot;init&quot;,&quot;description&quot;:&quot;初始化 SpecCore 项目结构&quot;,&quot;args&quot;:&quot;&quot;},{&quot;name&quot;:&quot;导入需求&quot;,&quot;key&quot;:&quot;doc&quot;,&quot;done&quot;:false,&quot;icon&quot;:&quot;📝&quot;,&quot;cmd&quot;:&quot;doc2spec&quot;,&quot;description&quot;:&quot;导入 PRD 文档,AI 转换需求规格&quot;,&quot;args&quot;:&quot;-f PRD.docx --iteration 期次-Q2&quot;},{&quot;name&quot;:&quot;分析需求&quot;,&quot;key&quot;:&quot;analyze&quot;,&quot;done&quot;:false,&quot;icon&quot;:&quot;🧠&quot;,&quot;cmd&quot;:&quot;analyze&quot;,&quot;description&quot;:&quot;AI 分析需求文档,生成审计报告&quot;,&quot;args&quot;:&quot;--iteration=期次-Q2&quot;},{&quot;name&quot;:&quot;拆分任务&quot;,&quot;key&quot;:&quot;split&quot;,&quot;done&quot;:false,&quot;icon&quot;:&quot;📦&quot;,&quot;cmd&quot;:&quot;split&quot;,&quot;description&quot;:&quot;将需求拆分为独立开发任务&quot;,&quot;args&quot;:&quot;-f REQUIREMENT.md&quot;},{&quot;name&quot;:&quot;执行开发&quot;,&quot;key&quot;:&quot;execute&quot;,&quot;done&quot;:false,&quot;icon&quot;:&quot;⚡&quot;,&quot;cmd&quot;:&quot;execute&quot;,&quot;description&quot;:&quot;按计划分批执行开发任务&quot;,&quot;args&quot;:&quot;--auto&quot;},{&quot;name&quot;:&quot;提交 PR&quot;,&quot;key&quot;:&quot;pr&quot;,&quot;done&quot;:false,&quot;icon&quot;:&quot;🔀&quot;,&quot;cmd&quot;:&quot;pr&quot;,&quot;description&quot;:&quot;代码提交后创建 Pull Request&quot;,&quot;args&quot;:&quot;--auto&quot;},{&quot;name&quot;:&quot;归档收尾&quot;,&quot;key&quot;:&quot;done&quot;,&quot;done&quot;:false,&quot;icon&quot;:&quot;✅&quot;,&quot;cmd&quot;:&quot;done&quot;,&quot;description&quot;:&quot;校验、同步、审计,归档记录&quot;,&quot;args&quot;:&quot;--all&quot;}],&quot;currentIdx&quot;:1,&quot;currentPhase&quot;:{&quot;name&quot;:&quot;导入需求&quot;,&quot;key&quot;:&quot;doc&quot;,&quot;done&quot;:false,&quot;icon&quot;:&quot;📝&quot;,&quot;cmd&quot;:&quot;doc2spec&quot;,&quot;description&quot;:&quot;导入 PRD 文档,AI 转换需求规格&quot;,&quot;args&quot;:&quot;-f PRD.docx --iteration 期次-Q2&quot;}};
@@ -1 +1 @@
1
- <!DOCTYPE html><html lang="zh-CN" data-theme="ocean"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>SpecCore Help</title><style>@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700;900&family=JetBrains+Mono:wght@400;600;700&display=swap');[data-theme="ocean"]{--cyan:#0ea5e9;--bg:#0b1929;--card:rgba(13,31,56,.95);--border:rgba(14,165,233,.15);--text:#bae6fd;--muted:#5b7fa5;--green:#14b8a6;--orange:#f97316;--purple:#6366f1}*{margin:0;padding:0;box-sizing:border-box}body{font-family:'JetBrains Mono',monospace;background:var(--bg);color:var(--text);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}.scanlines{position:fixed;inset:0;pointer-events:none;z-index:99;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,240,255,.01) 2px,rgba(0,240,255,.01) 4px)}.card{max-width:800px;width:100%;margin:0 auto;background:var(--card);border:1px solid var(--border);border-radius:16px;padding:24px;position:relative;overflow:hidden}.card::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX 3s linear infinite}.card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX-rev 3s linear infinite}@keyframes scanX{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}@keyframes scanX-rev{0%{transform:translateX(100%)}100%{transform:translateX(-100%)}}@keyframes scanY{0%{transform:translateY(-100%)}100%{transform:translateY(100%)}}@keyframes scanY-rev{0%{transform:translateY(100%)}100%{transform:translateY(-100%)}}.vline{position:absolute;top:0;width:1px;bottom:0;pointer-events:none}.vline.l{left:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY-rev 3s linear infinite}.vline.r{right:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY 3s linear infinite}h1{font-family:'Orbitron',sans-serif;font-size:24px;font-weight:900;background:linear-gradient(135deg,var(--cyan),var(--purple));-webkit-background-clip:text;-webkit-text-fill-color:transparent;letter-spacing:2px;margin-bottom:4px}.sub{color:var(--muted);font-size:11px;margin-bottom:20px}.cat{margin:12px 0;padding:12px;background:rgba(255,255,255,.02);border:1px solid rgba(255,255,255,.04);border-radius:10px}.cat-title{font-size:10px;font-weight:700;color:var(--cyan);text-transform:uppercase;letter-spacing:1px;margin-bottom:8px}.cat-cmds{display:flex;flex-wrap:wrap;gap:6px}.cmd-pill{padding:3px 10px;border-radius:4px;font-size:10px;background:rgba(14,165,233,.1);color:var(--cyan);border:1px solid rgba(14,165,233,.15)}.cmd-detail{padding:8px 0}.cmd-desc{font-size:13px;margin-bottom:16px}.param-list{margin:12px 0}.param{display:flex;gap:12px;padding:6px 0;border-bottom:1px solid rgba(255,255,255,.03)}.param-flag{color:var(--green);font-size:11px;min-width:160px}.param-meaning{color:var(--muted);font-size:11px}.example-list{margin:12px 0}.section-label{font-size:9px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;margin-bottom:6px}code{display:block;background:rgba(14,165,233,.1);padding:4px 10px;border-radius:4px;color:var(--cyan);font-size:11px;margin:4px 0}.footer{text-align:center;color:var(--muted);font-size:10px;margin-top:24px;padding-top:16px;border-top:1px solid rgba(255,255,255,.04)}.grid-pattern{position:fixed;inset:0;pointer-events:none;z-index:0;background-image:linear-gradient(rgba(14,165,233,.03) 1px,transparent 1px),linear-gradient(90deg,rgba(14,165,233,.03) 1px,transparent 1px);background-size:60px 60px}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 25% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}h1,h2{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}</style></head><body><div class="scanlines"></div><div class="grid-pattern"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><h1>SPECCORE HELP</h1><div class="sub">SpecCore 命令参考 · v8.3.148</div><div class="cat"><div class="cat-title">🧠 AI 入口</div><div class="cat-cmds"><span class="cmd-pill">speccore ask</span><span class="cmd-pill">speccore welcome</span></div></div><div class="cat"><div class="cat-title">🏗️ 初始化</div><div class="cat-cmds"><span class="cmd-pill">speccore init</span></div></div><div class="cat"><div class="cat-title">📋 期次与任务</div><div class="cat-cmds"><span class="cmd-pill">speccore iteration</span><span class="cmd-pill">speccore task</span><span class="cmd-pill">speccore rename</span></div></div><div class="cat"><div class="cat-title">📝 文档转换</div><div class="cat-cmds"><span class="cmd-pill">speccore doc2spec</span><span class="cmd-pill">speccore spec2doc</span></div></div><div class="cat"><div class="cat-title">🔍 分析与计划</div><div class="cat-cmds"><span class="cmd-pill">speccore analyze</span><span class="cmd-pill">speccore plan</span><span class="cmd-pill">speccore split</span></div></div><div class="cat"><div class="cat-title">⚡ 执行与交付</div><div class="cat-cmds"><span class="cmd-pill">speccore execute</span><span class="cmd-pill">speccore pr</span><span class="cmd-pill">speccore done</span></div></div><div class="cat"><div class="cat-title">🔄 同步与变更</div><div class="cat-cmds"><span class="cmd-pill">speccore change</span><span class="cmd-pill">speccore sync</span><span class="cmd-pill">speccore retro</span><span class="cmd-pill">speccore ops</span></div></div><div class="cat"><div class="cat-title">📊 查看与验证</div><div class="cat-cmds"><span class="cmd-pill">speccore dashboard</span><span class="cmd-pill">speccore validate</span><span class="cmd-pill">speccore track</span><span class="cmd-pill">speccore search</span><span class="cmd-pill">speccore graph</span><span class="cmd-pill">speccore knowledge</span></div></div><div class="cat"><div class="cat-title">🤖 智能操作</div><div class="cat-cmds"><span class="cmd-pill">speccore dev</span></div></div><div class="cat"><div class="cat-title">🔧 维护与升级</div><div class="cat-cmds"><span class="cmd-pill">speccore update</span><span class="cmd-pill">speccore doctor</span><span class="cmd-pill">speccore config</span></div></div><div class="cat" onclick="window.location.href='speccore-prompts.html'" style="cursor:pointer"><div class="cat-title">📋 提示词库</div><div class="cat-cmds"><span class="cmd-pill">speccore prompts</span><span class="cmd-pill">查看全部 31 个提示词</span></div></div><div class="footer">由 SpecCore 驱动 v8.3.148 · 2026-08-31</div></div></body></html>
1
+ <!DOCTYPE html><html lang="zh-CN" data-theme="ocean"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>SpecCore Help</title><style>@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700;900&family=JetBrains+Mono:wght@400;600;700&display=swap');[data-theme="ocean"]{--cyan:#0ea5e9;--bg:#0b1929;--card:rgba(13,31,56,.95);--border:rgba(14,165,233,.15);--text:#bae6fd;--muted:#5b7fa5;--green:#14b8a6;--orange:#f97316;--purple:#6366f1}*{margin:0;padding:0;box-sizing:border-box}body{font-family:'JetBrains Mono',monospace;background:var(--bg);color:var(--text);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}.scanlines{position:fixed;inset:0;pointer-events:none;z-index:99;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,240,255,.01) 2px,rgba(0,240,255,.01) 4px)}.card{max-width:800px;width:100%;margin:0 auto;background:var(--card);border:1px solid var(--border);border-radius:16px;padding:24px;position:relative;overflow:hidden}.card::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX 3s linear infinite}.card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX-rev 3s linear infinite}@keyframes scanX{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}@keyframes scanX-rev{0%{transform:translateX(100%)}100%{transform:translateX(-100%)}}@keyframes scanY{0%{transform:translateY(-100%)}100%{transform:translateY(100%)}}@keyframes scanY-rev{0%{transform:translateY(100%)}100%{transform:translateY(-100%)}}.vline{position:absolute;top:0;width:1px;bottom:0;pointer-events:none}.vline.l{left:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY-rev 3s linear infinite}.vline.r{right:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY 3s linear infinite}h1{font-family:'Orbitron',sans-serif;font-size:24px;font-weight:900;background:linear-gradient(135deg,var(--cyan),var(--purple));-webkit-background-clip:text;-webkit-text-fill-color:transparent;letter-spacing:2px;margin-bottom:4px}.sub{color:var(--muted);font-size:11px;margin-bottom:20px}.cat{margin:12px 0;padding:12px;background:rgba(255,255,255,.02);border:1px solid rgba(255,255,255,.04);border-radius:10px}.cat-title{font-size:10px;font-weight:700;color:var(--cyan);text-transform:uppercase;letter-spacing:1px;margin-bottom:8px}.cat-cmds{display:flex;flex-wrap:wrap;gap:6px}.cmd-pill{padding:3px 10px;border-radius:4px;font-size:10px;background:rgba(14,165,233,.1);color:var(--cyan);border:1px solid rgba(14,165,233,.15)}.cmd-detail{padding:8px 0}.cmd-desc{font-size:13px;margin-bottom:16px}.param-list{margin:12px 0}.param{display:flex;gap:12px;padding:6px 0;border-bottom:1px solid rgba(255,255,255,.03)}.param-flag{color:var(--green);font-size:11px;min-width:160px}.param-meaning{color:var(--muted);font-size:11px}.example-list{margin:12px 0}.section-label{font-size:9px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;margin-bottom:6px}code{display:block;background:rgba(14,165,233,.1);padding:4px 10px;border-radius:4px;color:var(--cyan);font-size:11px;margin:4px 0}.footer{text-align:center;color:var(--muted);font-size:10px;margin-top:24px;padding-top:16px;border-top:1px solid rgba(255,255,255,.04)}.grid-pattern{position:fixed;inset:0;pointer-events:none;z-index:0;background-image:linear-gradient(rgba(14,165,233,.03) 1px,transparent 1px),linear-gradient(90deg,rgba(14,165,233,.03) 1px,transparent 1px);background-size:60px 60px}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 25% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}h1,h2{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}</style></head><body><div class="scanlines"></div><div class="grid-pattern"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><h1>SPECCORE HELP</h1><div class="sub">SpecCore 命令参考 · v8.3.150</div><div class="cat"><div class="cat-title">🧠 AI 入口</div><div class="cat-cmds"><span class="cmd-pill">speccore ask</span><span class="cmd-pill">speccore welcome</span></div></div><div class="cat"><div class="cat-title">🏗️ 初始化</div><div class="cat-cmds"><span class="cmd-pill">speccore init</span></div></div><div class="cat"><div class="cat-title">📋 期次与任务</div><div class="cat-cmds"><span class="cmd-pill">speccore iteration</span><span class="cmd-pill">speccore task</span><span class="cmd-pill">speccore rename</span></div></div><div class="cat"><div class="cat-title">📝 文档转换</div><div class="cat-cmds"><span class="cmd-pill">speccore doc2spec</span><span class="cmd-pill">speccore spec2doc</span></div></div><div class="cat"><div class="cat-title">🔍 分析与计划</div><div class="cat-cmds"><span class="cmd-pill">speccore analyze</span><span class="cmd-pill">speccore plan</span><span class="cmd-pill">speccore split</span></div></div><div class="cat"><div class="cat-title">⚡ 执行与交付</div><div class="cat-cmds"><span class="cmd-pill">speccore execute</span><span class="cmd-pill">speccore pr</span><span class="cmd-pill">speccore done</span></div></div><div class="cat"><div class="cat-title">🔄 同步与变更</div><div class="cat-cmds"><span class="cmd-pill">speccore change</span><span class="cmd-pill">speccore sync</span><span class="cmd-pill">speccore retro</span><span class="cmd-pill">speccore ops</span></div></div><div class="cat"><div class="cat-title">📊 查看与验证</div><div class="cat-cmds"><span class="cmd-pill">speccore dashboard</span><span class="cmd-pill">speccore validate</span><span class="cmd-pill">speccore track</span><span class="cmd-pill">speccore search</span><span class="cmd-pill">speccore graph</span><span class="cmd-pill">speccore knowledge</span></div></div><div class="cat"><div class="cat-title">🤖 智能操作</div><div class="cat-cmds"><span class="cmd-pill">speccore dev</span></div></div><div class="cat"><div class="cat-title">🔧 维护与升级</div><div class="cat-cmds"><span class="cmd-pill">speccore update</span><span class="cmd-pill">speccore doctor</span><span class="cmd-pill">speccore config</span></div></div><div class="cat" onclick="window.location.href='speccore-prompts.html'" style="cursor:pointer"><div class="cat-title">📋 提示词库</div><div class="cat-cmds"><span class="cmd-pill">speccore prompts</span><span class="cmd-pill">查看全部 31 个提示词</span></div></div><div class="footer">由 SpecCore 驱动 v8.3.150 · 2026-08-31</div></div></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>SpecCore Retro · T-001</title><style>@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700;900&family=JetBrains+Mono:wght@400;600;700');body{margin:0;padding:20px;background:#0b1929;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;font-family:'JetBrains Mono',monospace;box-sizing:border-box}.scanlines{position:fixed;inset:0;pointer-events:none;z-index:0;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,240,255,.015) 2px,rgba(0,240,255,.015) 4px)}.grid-pattern{position:fixed;inset:0;pointer-events:none;z-index:0;background-image:linear-gradient(rgba(14,165,233,.03) 1px,transparent 1px),linear-gradient(90deg,rgba(14,165,233,.03) 1px,transparent 1px);background-size:60px 60px}.card{max-width:800px;width:100%;background:rgba(13,31,56,.95);border:1px solid rgba(14,165,233,.15);border-radius:16px;padding:24px;position:relative;overflow:hidden;z-index:1}.card::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,#0ea5e9,transparent);animation:scanX 3s linear infinite}.card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,#0ea5e9,transparent);animation:scanX-rev 3s linear infinite}.vline{position:absolute;top:0;width:1px;bottom:0;pointer-events:none}.vline.l{left:0;background:linear-gradient(0deg,transparent,#0ea5e9,transparent);animation:scanY-rev 3s linear infinite}.vline.r{right:0;background:linear-gradient(0deg,transparent,#0ea5e9,transparent);animation:scanY 3s linear infinite}@keyframes scanX{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}@keyframes scanX-rev{0%{transform:translateX(100%)}100%{transform:translateX(-100%)}}@keyframes scanY{0%{transform:translateY(-100%)}100%{transform:translateY(100%)}}@keyframes scanY-rev{0%{transform:translateY(100%)}100%{transform:translateY(-100%)}}h1{font-family:'Orbitron',sans-serif;font-size:22px;font-weight:900;background:linear-gradient(135deg,#0ea5e9,#6366f1);-webkit-background-clip:text;-webkit-text-fill-color:transparent;letter-spacing:2px}.meta{color:#5b7fa5;font-size:11px;margin:8px 0 20px}.grid2{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:16px 0}.stat{background:rgba(14,165,233,.06);border:1px solid rgba(14,165,233,.1);border-radius:8px;padding:12px;text-align:center}.stat .val{font-family:'Orbitron',sans-serif;font-size:20px;font-weight:900;color:#0ea5e9}.stat .lbl{font-size:10px;color:#5b7fa5;margin-top:4px}.score{text-align:center;margin:12px 0;display:flex;justify-content:center;gap:14px}.star-filled,.star-empty{display:inline-flex;width:42px;height:42px;align-items:center;justify-content:center}.summary{padding:12px;background:rgba(20,184,166,.06);border:1px solid rgba(20,184,166,.15);border-radius:8px;color:#bae6fd;font-size:12px;line-height:1.6;margin:12px 0}.improve{padding:12px;background:rgba(249,115,22,.06);border:1px solid rgba(249,115,22,.15);border-radius:8px;color:#f97316;font-size:11px}.pass{color:#14b8a6}.fail{color:#f97316}.ft{text-align:center;color:#5b7fa5;font-size:10px;margin-top:24px}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 25% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}h1,h2{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}</style></head><body><div class="scanlines"></div><div class="grid-pattern"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><h1>RETRO · T-001</h1><div class="meta">期次: :--- · 2026-08-31</div><div class="score"><i class="star-filled"><svg width="42" height="42" viewBox="0 0 24 24" style="filter:drop-shadow(0 0 8px rgba(251,191,36,.7)) drop-shadow(0 0 16px rgba(251,191,36,.4))"><defs><linearGradient id="sg" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#fcd34d"/><stop offset="1" stop-color="#f59e0b"/></linearGradient></defs><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" fill="url(#sg)" stroke="#fbbf24" stroke-width="0.5" stroke-linejoin="round"/></svg></i><i class="star-filled"><svg width="42" height="42" viewBox="0 0 24 24" style="filter:drop-shadow(0 0 8px rgba(251,191,36,.7)) drop-shadow(0 0 16px rgba(251,191,36,.4))"><defs><linearGradient id="sg" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#fcd34d"/><stop offset="1" stop-color="#f59e0b"/></linearGradient></defs><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" fill="url(#sg)" stroke="#fbbf24" stroke-width="0.5" stroke-linejoin="round"/></svg></i><i class="star-filled"><svg width="42" height="42" viewBox="0 0 24 24" style="filter:drop-shadow(0 0 8px rgba(251,191,36,.7)) drop-shadow(0 0 16px rgba(251,191,36,.4))"><defs><linearGradient id="sg" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#fcd34d"/><stop offset="1" stop-color="#f59e0b"/></linearGradient></defs><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" fill="url(#sg)" stroke="#fbbf24" stroke-width="0.5" stroke-linejoin="round"/></svg></i><i class="star-filled"><svg width="42" height="42" viewBox="0 0 24 24" style="filter:drop-shadow(0 0 8px rgba(251,191,36,.7)) drop-shadow(0 0 16px rgba(251,191,36,.4))"><defs><linearGradient id="sg" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#fcd34d"/><stop offset="1" stop-color="#f59e0b"/></linearGradient></defs><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" fill="url(#sg)" stroke="#fbbf24" stroke-width="0.5" stroke-linejoin="round"/></svg></i><i class="star-empty"><svg width="42" height="42" viewBox="0 0 24 24" style="filter:drop-shadow(0 0 4px rgba(51,65,85,.3))"><defs><linearGradient id="sg2" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#475569"/><stop offset="1" stop-color="#0f172a"/></linearGradient></defs><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" fill="url(#sg2)" stroke="#334155" stroke-width="0.5" stroke-linejoin="round"/></svg></i></div><div class="grid2"><div class="stat"><div class="val">0</div><div class="lbl">文件变更</div></div><div class="stat"><div class="val fail">❌</div><div class="lbl">验证</div></div></div><div class="summary">任务 T-001 已完成,共涉及 0 个文件变更</div><div class="improve">💡 任务粒度合适</div><div class="ft">SpecCore Retro v8.3.148 · 2026-08-31</div></div></body></html>
1
+ <!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>SpecCore Retro · T-001</title><style>@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700;900&family=JetBrains+Mono:wght@400;600;700');body{margin:0;padding:20px;background:#0b1929;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;font-family:'JetBrains Mono',monospace;box-sizing:border-box}.scanlines{position:fixed;inset:0;pointer-events:none;z-index:0;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,240,255,.015) 2px,rgba(0,240,255,.015) 4px)}.grid-pattern{position:fixed;inset:0;pointer-events:none;z-index:0;background-image:linear-gradient(rgba(14,165,233,.03) 1px,transparent 1px),linear-gradient(90deg,rgba(14,165,233,.03) 1px,transparent 1px);background-size:60px 60px}.card{max-width:800px;width:100%;background:rgba(13,31,56,.95);border:1px solid rgba(14,165,233,.15);border-radius:16px;padding:24px;position:relative;overflow:hidden;z-index:1}.card::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,#0ea5e9,transparent);animation:scanX 3s linear infinite}.card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,#0ea5e9,transparent);animation:scanX-rev 3s linear infinite}.vline{position:absolute;top:0;width:1px;bottom:0;pointer-events:none}.vline.l{left:0;background:linear-gradient(0deg,transparent,#0ea5e9,transparent);animation:scanY-rev 3s linear infinite}.vline.r{right:0;background:linear-gradient(0deg,transparent,#0ea5e9,transparent);animation:scanY 3s linear infinite}@keyframes scanX{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}@keyframes scanX-rev{0%{transform:translateX(100%)}100%{transform:translateX(-100%)}}@keyframes scanY{0%{transform:translateY(-100%)}100%{transform:translateY(100%)}}@keyframes scanY-rev{0%{transform:translateY(100%)}100%{transform:translateY(-100%)}}h1{font-family:'Orbitron',sans-serif;font-size:22px;font-weight:900;background:linear-gradient(135deg,#0ea5e9,#6366f1);-webkit-background-clip:text;-webkit-text-fill-color:transparent;letter-spacing:2px}.meta{color:#5b7fa5;font-size:11px;margin:8px 0 20px}.grid2{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:16px 0}.stat{background:rgba(14,165,233,.06);border:1px solid rgba(14,165,233,.1);border-radius:8px;padding:12px;text-align:center}.stat .val{font-family:'Orbitron',sans-serif;font-size:20px;font-weight:900;color:#0ea5e9}.stat .lbl{font-size:10px;color:#5b7fa5;margin-top:4px}.score{text-align:center;margin:12px 0;display:flex;justify-content:center;gap:14px}.star-filled,.star-empty{display:inline-flex;width:42px;height:42px;align-items:center;justify-content:center}.summary{padding:12px;background:rgba(20,184,166,.06);border:1px solid rgba(20,184,166,.15);border-radius:8px;color:#bae6fd;font-size:12px;line-height:1.6;margin:12px 0}.improve{padding:12px;background:rgba(249,115,22,.06);border:1px solid rgba(249,115,22,.15);border-radius:8px;color:#f97316;font-size:11px}.pass{color:#14b8a6}.fail{color:#f97316}.ft{text-align:center;color:#5b7fa5;font-size:10px;margin-top:24px}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 25% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}h1,h2{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}</style></head><body><div class="scanlines"></div><div class="grid-pattern"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><h1>RETRO · T-001</h1><div class="meta">期次: :--- · 2026-08-31</div><div class="score"><i class="star-filled"><svg width="42" height="42" viewBox="0 0 24 24" style="filter:drop-shadow(0 0 8px rgba(251,191,36,.7)) drop-shadow(0 0 16px rgba(251,191,36,.4))"><defs><linearGradient id="sg" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#fcd34d"/><stop offset="1" stop-color="#f59e0b"/></linearGradient></defs><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" fill="url(#sg)" stroke="#fbbf24" stroke-width="0.5" stroke-linejoin="round"/></svg></i><i class="star-filled"><svg width="42" height="42" viewBox="0 0 24 24" style="filter:drop-shadow(0 0 8px rgba(251,191,36,.7)) drop-shadow(0 0 16px rgba(251,191,36,.4))"><defs><linearGradient id="sg" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#fcd34d"/><stop offset="1" stop-color="#f59e0b"/></linearGradient></defs><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" fill="url(#sg)" stroke="#fbbf24" stroke-width="0.5" stroke-linejoin="round"/></svg></i><i class="star-filled"><svg width="42" height="42" viewBox="0 0 24 24" style="filter:drop-shadow(0 0 8px rgba(251,191,36,.7)) drop-shadow(0 0 16px rgba(251,191,36,.4))"><defs><linearGradient id="sg" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#fcd34d"/><stop offset="1" stop-color="#f59e0b"/></linearGradient></defs><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" fill="url(#sg)" stroke="#fbbf24" stroke-width="0.5" stroke-linejoin="round"/></svg></i><i class="star-filled"><svg width="42" height="42" viewBox="0 0 24 24" style="filter:drop-shadow(0 0 8px rgba(251,191,36,.7)) drop-shadow(0 0 16px rgba(251,191,36,.4))"><defs><linearGradient id="sg" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#fcd34d"/><stop offset="1" stop-color="#f59e0b"/></linearGradient></defs><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" fill="url(#sg)" stroke="#fbbf24" stroke-width="0.5" stroke-linejoin="round"/></svg></i><i class="star-empty"><svg width="42" height="42" viewBox="0 0 24 24" style="filter:drop-shadow(0 0 4px rgba(51,65,85,.3))"><defs><linearGradient id="sg2" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#475569"/><stop offset="1" stop-color="#0f172a"/></linearGradient></defs><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" fill="url(#sg2)" stroke="#334155" stroke-width="0.5" stroke-linejoin="round"/></svg></i></div><div class="grid2"><div class="stat"><div class="val">0</div><div class="lbl">文件变更</div></div><div class="stat"><div class="val fail">❌</div><div class="lbl">验证</div></div></div><div class="summary">任务 T-001 已完成,共涉及 0 个文件变更</div><div class="improve">💡 任务粒度合适</div><div class="ft">SpecCore Retro v8.3.150 · 2026-08-31</div></div></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html lang="zh-CN" data-theme="ocean"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>SpecCore — 项目名片</title><style>@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700;900&family=JetBrains+Mono:wght@400;600;700&display=swap');[data-theme="ocean"]{--cyan:#0ea5e9;--bg:#0b1929;--card:rgba(13,31,56,.95);--border:rgba(14,165,233,.15);--text:#bae6fd;--muted:#5b7fa5;--green:#14b8a6;--orange:#f97316;--purple:#6366f1}*{margin:0;padding:0;box-sizing:border-box}body{font-family:'JetBrains Mono',monospace;background:var(--bg);color:var(--text);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:24px 20px}.scanlines{position:fixed;inset:0;pointer-events:none;z-index:99;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,240,255,.015) 2px,rgba(0,240,255,.015) 4px)}.stars{position:fixed;inset:0;pointer-events:none;background:radial-gradient(1px 1px at 20% 30%,rgba(255,255,255,.3),transparent),radial-gradient(1.5px 1.5px at 60% 70%,rgba(14,165,233,.4),transparent)}.card{max-width:800px;width:100%;margin:0 auto;background:var(--card);border:1px solid var(--border);border-radius:16px;padding:24px;position:relative;overflow:hidden;z-index:1}.card::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX 3s linear infinite}.card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX-rev 3s linear infinite}@keyframes scanX{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}@keyframes scanX-rev{0%{transform:translateX(100%)}100%{transform:translateX(-100%)}}@keyframes scanY{0%{transform:translateY(-100%)}100%{transform:translateY(100%)}}@keyframes scanY-rev{0%{transform:translateY(100%)}100%{transform:translateY(-100%)}}.vline{position:absolute;top:0;width:1px;bottom:0;pointer-events:none}.vline.l{left:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY-rev 3s linear infinite}.vline.r{right:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY 3s linear infinite}.center-node{width:90px;height:90px;border-radius:50%;border:2px solid var(--cyan);display:flex;align-items:center;justify-content:center;background:rgba(14,165,233,.08);margin:24px auto;font-family:Orbitron,sans-serif;font-size:20px;font-weight:900;background:linear-gradient(135deg,var(--cyan),var(--purple));-webkit-background-clip:text;-webkit-text-fill-color:transparent;position:relative;z-index:2}.modes-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:20px 0}.mode-card{border-radius:10px;padding:14px;position:relative;overflow:hidden;background:rgba(255,255,255,.02)}.mode-card.m1{border:1.5px solid var(--green)}.mode-card.m2{border:1.5px solid var(--orange)}.mode-card.m3{border:1.5px solid var(--cyan)}.mode-card.m4{border:1.5px solid var(--purple)}.mode-card .mode-title{font-weight:600;margin:6px 0;font-size:13px}.mode-card.m1 .mode-title{color:var(--green)}.mode-card.m2 .mode-title{color:var(--orange)}.mode-card.m3 .mode-title{color:var(--cyan)}.mode-card.m4 .mode-title{color:var(--purple)}.mode-card .mode-icon{font-size:18px;margin-right:4px}.mode-card .mode-desc{font-size:10px;color:var(--muted);margin:4px 0}.mode-card .mode-tag{display:inline-block;padding:2px 8px;font-size:9px;border-radius:4px;background:rgba(20,184,166,.1);color:var(--green);margin-top:6px}.mode-card.m1 .mode-tag{background:rgba(20,184,166,.08);color:var(--green)}.mode-card.m2 .mode-tag{background:rgba(249,115,22,.08);color:var(--orange)}.mode-card.m3 .mode-tag{background:rgba(14,165,233,.08);color:var(--cyan)}.mode-card.m4 .mode-tag{background:rgba(99,102,241,.08);color:var(--purple)}.status-row{display:flex;align-items:center;gap:8px;margin:8px 0;padding:10px 14px;background:rgba(14,165,233,.04);border:1px solid rgba(14,165,233,.1);border-radius:8px}.flow{display:flex;gap:8px;align-items:center;flex-wrap:wrap;justify-content:flex-start}.flow-step{display:flex;flex-direction:row;align-items:center;gap:6px;padding:10px 8px;border-radius:10px;border:none}.flow-step.done{background:rgba(20,184,166,.1)}.flow-step.pending{background:rgba(255,255,255,.04)}.flow-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0;border:none}.flow-dot.done{background:var(--green);box-shadow:0 0 8px var(--green)}.flow-dot.pending{background:rgba(255,255,255,.15)}.flow-label{font-size:11px;color:var(--muted);white-space:nowrap}.flow-label.done{color:var(--green)}.flow-arrow{color:var(--muted);font-size:12px;text-align:center;line-height:1}.cmd-row{display:flex;gap:6px;flex-wrap:wrap;margin-top:10px}.cmd-pill{padding:3px 10px;border-radius:4px;font-size:10px;background:rgba(14,165,233,.1);color:var(--cyan);border:1px solid rgba(14,165,233,.15)}.footer{text-align:center;color:var(--muted);font-size:10px;margin-top:24px;padding-top:16px;border-top:1px solid rgba(255,255,255,.04)}h1{font-family:'Orbitron',sans-serif;font-size:32px;font-weight:900;background:linear-gradient(135deg,var(--cyan),var(--purple));-webkit-background-clip:text;-webkit-text-fill-color:transparent;letter-spacing:2px;text-align:center}.sub{color:var(--muted);font-size:11px;letter-spacing:1px;text-align:center;margin-top:4px}.section-title{font-size:10px;font-weight:700;color:var(--cyan);text-transform:uppercase;letter-spacing:2px;margin:20px 0 10px}.confirm-bar{text-align:center;padding:18px;margin:24px 0 8px;background:linear-gradient(135deg,var(--cyan) 0%,#0284c7 100%);border-radius:40px;color:#fff;font-weight:600;font-size:14px;box-shadow:0 0 30px rgba(14,165,233,.3);cursor:pointer;letter-spacing:1px}.section{margin:14px 0;padding:14px;background:rgba(255,255,255,.02);border:1px solid rgba(255,255,255,.04);border-radius:10px}.grid-pattern{position:fixed;inset:0;pointer-events:none;z-index:0;background-image:linear-gradient(rgba(14,165,233,.03) 1px,transparent 1px),linear-gradient(90deg,rgba(14,165,233,.03) 1px,transparent 1px);background-size:60px 60px}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 50% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}h1,h2{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}</style></head><body><div class="scanlines"></div><div class="grid-pattern"></div><div class="stars"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><h1>SPECCORE</h1><div class="sub">Code by Spec, Not by Vibe · v8.3.148 · Q2</div><div class="status-row"><span>📍</span><div><div style="font-size:11px;font-weight:600">⚡ 执行中 (6 任务)</div><div style="font-size:9px;color:var(--muted)">当前迭代: Q2 · 6 任务</div></div></div><div class="section-title">🔄 核心流水线</div><div class="section"><div class="flow"><div class="flow-step done"><span class="flow-dot done"></span><span class="flow-label done">导入</span></div><div class="flow-arrow">→</div><div class="flow-step done"><span class="flow-dot done"></span><span class="flow-label done">分析</span></div><div class="flow-arrow">→</div><div class="flow-step done"><span class="flow-dot done"></span><span class="flow-label done">拆分</span></div><div class="flow-arrow">→</div><div class="flow-step done"><span class="flow-dot done"></span><span class="flow-label done">计划</span></div><div class="flow-arrow">→</div><div class="flow-step pending"><span class="flow-dot pending"></span><span class="flow-label ">执行</span></div><div class="flow-arrow">→</div><div class="flow-step pending"><span class="flow-dot pending"></span><span class="flow-label ">交付</span></div></div></div><div class="section-title">🧠 ask — SpecCore 万能 AI 入口</div><div class="modes-grid"><div class="mode-card m1" onclick="window.location.href='speccore-ask-explain.html'" style="cursor:pointer"><div class="mode-title"><span class="mode-icon">📖</span>命令解释</div><div class="mode-desc">"dashboard 怎么用"<br>"init 有哪些参数"</div><div class="mode-tag">知识库匹配 →</div></div><div class="mode-card m2" onclick="window.location.href='speccore-ask-guide.html'" style="cursor:pointer"><div class="mode-title"><span class="mode-icon">🗺️</span>任务指引</div><div class="mode-desc">"我想做一个登录功能"<br>"怎么开始新项目"</div><div class="mode-tag">工作流生成 →</div></div><div class="mode-card m3" onclick="window.location.href='speccore-ask-match.html'" style="cursor:pointer"><div class="mode-title"><span class="mode-icon">🎯</span>意图匹配</div><div class="mode-desc">"查看进度" → dashboard<br>"审查代码" → validate</div><div class="mode-tag">38意图 + AI →</div></div><div class="mode-card m4" onclick="window.location.href='speccore-ask-pipeline.html'" style="cursor:pointer"><div class="mode-title"><span class="mode-icon">⚡</span>复杂编排</div><div class="mode-desc">"计划所有任务晚8点分批"<br>"做完分析→拆分→PR"</div><div class="mode-tag">Pipeline 引擎 →</div></div></div><div class="confirm-bar" onclick="window.location.href='speccore-ask-onboarding.html'">确认进入 · 输入 <code style="background:rgba(255,255,255,.2);padding:2px 8px;border-radius:4px">speccore ask "你的需求"</code> 开始</div><div class="section-title">📋 提示词库</div><div class="section" onclick="window.location.href='speccore-prompts.html'" style="cursor:pointer"><div style="display:flex;align-items:center;gap:10px"><span style="font-size:24px">🎯</span><div><div style="font-size:13px;font-weight:600;color:var(--cyan)">SpecCore 提示词库</div><div style="font-size:11px;color:var(--muted);margin-top:2px">31 个预置提示词,按场景分类,一键复制 AI 说法 / 触发命令</div></div><span style="margin-left:auto;color:var(--cyan);font-size:12px">→</span></div></div><div class="section-title">━━ 常用命令 ━━</div><div class="cmd-row"><span class="cmd-pill">speccore dashboard</span><span class="cmd-pill">speccore dev --auto</span><span class="cmd-pill">speccore ask "描述"</span><span class="cmd-pill">speccore graph query "订单"</span><span class="cmd-pill">speccore help</span></div><div class="footer">由 SpecCore 驱动 v8.3.148 · 2026-08-31</div></div></body></html>
1
+ <!DOCTYPE html><html lang="zh-CN" data-theme="ocean"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>SpecCore — 项目名片</title><style>@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700;900&family=JetBrains+Mono:wght@400;600;700&display=swap');[data-theme="ocean"]{--cyan:#0ea5e9;--bg:#0b1929;--card:rgba(13,31,56,.95);--border:rgba(14,165,233,.15);--text:#bae6fd;--muted:#5b7fa5;--green:#14b8a6;--orange:#f97316;--purple:#6366f1}*{margin:0;padding:0;box-sizing:border-box}body{font-family:'JetBrains Mono',monospace;background:var(--bg);color:var(--text);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:24px 20px}.scanlines{position:fixed;inset:0;pointer-events:none;z-index:99;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,240,255,.015) 2px,rgba(0,240,255,.015) 4px)}.stars{position:fixed;inset:0;pointer-events:none;background:radial-gradient(1px 1px at 20% 30%,rgba(255,255,255,.3),transparent),radial-gradient(1.5px 1.5px at 60% 70%,rgba(14,165,233,.4),transparent)}.card{max-width:800px;width:100%;margin:0 auto;background:var(--card);border:1px solid var(--border);border-radius:16px;padding:24px;position:relative;overflow:hidden;z-index:1}.card::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX 3s linear infinite}.card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX-rev 3s linear infinite}@keyframes scanX{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}@keyframes scanX-rev{0%{transform:translateX(100%)}100%{transform:translateX(-100%)}}@keyframes scanY{0%{transform:translateY(-100%)}100%{transform:translateY(100%)}}@keyframes scanY-rev{0%{transform:translateY(100%)}100%{transform:translateY(-100%)}}.vline{position:absolute;top:0;width:1px;bottom:0;pointer-events:none}.vline.l{left:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY-rev 3s linear infinite}.vline.r{right:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY 3s linear infinite}.center-node{width:90px;height:90px;border-radius:50%;border:2px solid var(--cyan);display:flex;align-items:center;justify-content:center;background:rgba(14,165,233,.08);margin:24px auto;font-family:Orbitron,sans-serif;font-size:20px;font-weight:900;background:linear-gradient(135deg,var(--cyan),var(--purple));-webkit-background-clip:text;-webkit-text-fill-color:transparent;position:relative;z-index:2}.modes-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:20px 0}.mode-card{border-radius:10px;padding:14px;position:relative;overflow:hidden;background:rgba(255,255,255,.02)}.mode-card.m1{border:1.5px solid var(--green)}.mode-card.m2{border:1.5px solid var(--orange)}.mode-card.m3{border:1.5px solid var(--cyan)}.mode-card.m4{border:1.5px solid var(--purple)}.mode-card .mode-title{font-weight:600;margin:6px 0;font-size:13px}.mode-card.m1 .mode-title{color:var(--green)}.mode-card.m2 .mode-title{color:var(--orange)}.mode-card.m3 .mode-title{color:var(--cyan)}.mode-card.m4 .mode-title{color:var(--purple)}.mode-card .mode-icon{font-size:18px;margin-right:4px}.mode-card .mode-desc{font-size:10px;color:var(--muted);margin:4px 0}.mode-card .mode-tag{display:inline-block;padding:2px 8px;font-size:9px;border-radius:4px;background:rgba(20,184,166,.1);color:var(--green);margin-top:6px}.mode-card.m1 .mode-tag{background:rgba(20,184,166,.08);color:var(--green)}.mode-card.m2 .mode-tag{background:rgba(249,115,22,.08);color:var(--orange)}.mode-card.m3 .mode-tag{background:rgba(14,165,233,.08);color:var(--cyan)}.mode-card.m4 .mode-tag{background:rgba(99,102,241,.08);color:var(--purple)}.status-row{display:flex;align-items:center;gap:8px;margin:8px 0;padding:10px 14px;background:rgba(14,165,233,.04);border:1px solid rgba(14,165,233,.1);border-radius:8px}.flow{display:flex;gap:8px;align-items:center;flex-wrap:wrap;justify-content:flex-start}.flow-step{display:flex;flex-direction:row;align-items:center;gap:6px;padding:10px 8px;border-radius:10px;border:none}.flow-step.done{background:rgba(20,184,166,.1)}.flow-step.pending{background:rgba(255,255,255,.04)}.flow-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0;border:none}.flow-dot.done{background:var(--green);box-shadow:0 0 8px var(--green)}.flow-dot.pending{background:rgba(255,255,255,.15)}.flow-label{font-size:11px;color:var(--muted);white-space:nowrap}.flow-label.done{color:var(--green)}.flow-arrow{color:var(--muted);font-size:12px;text-align:center;line-height:1}.cmd-row{display:flex;gap:6px;flex-wrap:wrap;margin-top:10px}.cmd-pill{padding:3px 10px;border-radius:4px;font-size:10px;background:rgba(14,165,233,.1);color:var(--cyan);border:1px solid rgba(14,165,233,.15)}.footer{text-align:center;color:var(--muted);font-size:10px;margin-top:24px;padding-top:16px;border-top:1px solid rgba(255,255,255,.04)}h1{font-family:'Orbitron',sans-serif;font-size:32px;font-weight:900;background:linear-gradient(135deg,var(--cyan),var(--purple));-webkit-background-clip:text;-webkit-text-fill-color:transparent;letter-spacing:2px;text-align:center}.sub{color:var(--muted);font-size:11px;letter-spacing:1px;text-align:center;margin-top:4px}.section-title{font-size:10px;font-weight:700;color:var(--cyan);text-transform:uppercase;letter-spacing:2px;margin:20px 0 10px}.confirm-bar{text-align:center;padding:18px;margin:24px 0 8px;background:linear-gradient(135deg,var(--cyan) 0%,#0284c7 100%);border-radius:40px;color:#fff;font-weight:600;font-size:14px;box-shadow:0 0 30px rgba(14,165,233,.3);cursor:pointer;letter-spacing:1px}.section{margin:14px 0;padding:14px;background:rgba(255,255,255,.02);border:1px solid rgba(255,255,255,.04);border-radius:10px}.grid-pattern{position:fixed;inset:0;pointer-events:none;z-index:0;background-image:linear-gradient(rgba(14,165,233,.03) 1px,transparent 1px),linear-gradient(90deg,rgba(14,165,233,.03) 1px,transparent 1px);background-size:60px 60px}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 50% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}h1,h2{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}</style></head><body><div class="scanlines"></div><div class="grid-pattern"></div><div class="stars"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><h1>SPECCORE</h1><div class="sub">Code by Spec, Not by Vibe · v8.3.150 · Q2</div><div class="status-row"><span>📍</span><div><div style="font-size:11px;font-weight:600">⚡ 执行中 (6 任务)</div><div style="font-size:9px;color:var(--muted)">当前迭代: Q2 · 6 任务</div></div></div><div class="section-title">🔄 核心流水线</div><div class="section"><div class="flow"><div class="flow-step done"><span class="flow-dot done"></span><span class="flow-label done">导入</span></div><div class="flow-arrow">→</div><div class="flow-step done"><span class="flow-dot done"></span><span class="flow-label done">分析</span></div><div class="flow-arrow">→</div><div class="flow-step done"><span class="flow-dot done"></span><span class="flow-label done">拆分</span></div><div class="flow-arrow">→</div><div class="flow-step done"><span class="flow-dot done"></span><span class="flow-label done">计划</span></div><div class="flow-arrow">→</div><div class="flow-step pending"><span class="flow-dot pending"></span><span class="flow-label ">执行</span></div><div class="flow-arrow">→</div><div class="flow-step pending"><span class="flow-dot pending"></span><span class="flow-label ">交付</span></div></div></div><div class="section-title">🧠 ask — SpecCore 万能 AI 入口</div><div class="modes-grid"><div class="mode-card m1" onclick="window.location.href='speccore-ask-explain.html'" style="cursor:pointer"><div class="mode-title"><span class="mode-icon">📖</span>命令解释</div><div class="mode-desc">"dashboard 怎么用"<br>"init 有哪些参数"</div><div class="mode-tag">知识库匹配 →</div></div><div class="mode-card m2" onclick="window.location.href='speccore-ask-guide.html'" style="cursor:pointer"><div class="mode-title"><span class="mode-icon">🗺️</span>任务指引</div><div class="mode-desc">"我想做一个登录功能"<br>"怎么开始新项目"</div><div class="mode-tag">工作流生成 →</div></div><div class="mode-card m3" onclick="window.location.href='speccore-ask-match.html'" style="cursor:pointer"><div class="mode-title"><span class="mode-icon">🎯</span>意图匹配</div><div class="mode-desc">"查看进度" → dashboard<br>"审查代码" → validate</div><div class="mode-tag">38意图 + AI →</div></div><div class="mode-card m4" onclick="window.location.href='speccore-ask-pipeline.html'" style="cursor:pointer"><div class="mode-title"><span class="mode-icon">⚡</span>复杂编排</div><div class="mode-desc">"计划所有任务晚8点分批"<br>"做完分析→拆分→PR"</div><div class="mode-tag">Pipeline 引擎 →</div></div></div><div class="confirm-bar" onclick="window.location.href='speccore-ask-onboarding.html'">确认进入 · 输入 <code style="background:rgba(255,255,255,.2);padding:2px 8px;border-radius:4px">speccore ask "你的需求"</code> 开始</div><div class="section-title">📋 提示词库</div><div class="section" onclick="window.location.href='speccore-prompts.html'" style="cursor:pointer"><div style="display:flex;align-items:center;gap:10px"><span style="font-size:24px">🎯</span><div><div style="font-size:13px;font-weight:600;color:var(--cyan)">SpecCore 提示词库</div><div style="font-size:11px;color:var(--muted);margin-top:2px">31 个预置提示词,按场景分类,一键复制 AI 说法 / 触发命令</div></div><span style="margin-left:auto;color:var(--cyan);font-size:12px">→</span></div></div><div class="section-title">━━ 常用命令 ━━</div><div class="cmd-row"><span class="cmd-pill">speccore dashboard</span><span class="cmd-pill">speccore dev --auto</span><span class="cmd-pill">speccore ask "描述"</span><span class="cmd-pill">speccore graph query "订单"</span><span class="cmd-pill">speccore help</span></div><div class="footer">由 SpecCore 驱动 v8.3.150 · 2026-08-31</div></div></body></html>
@@ -1,138 +1,891 @@
1
- # VERIFY_SPEC.yaml — UI 冒烟测试规格
1
+ # VERIFY_SPEC.yaml — UI 冒烟测试规格(真实值示例版)
2
2
  # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3
3
  # 格式类型: VERIFY_SPEC 格式(scenarios + actions + assertions 结构)
4
- # 适用场景: 精细 UI 交互测试(填写表单、点击按钮、断言元素状态)
5
4
  # 对应命令:
6
- # • speccore verify --ui --spec ./tests/smoke.yaml ← 推荐,原生支持完整交互逻辑
7
- # • speccore verify --ui --config ./tests/smoke.yaml ← 兼容,自动转换为批量页面测试
5
+ # • speccore verify --ui --spec ./tests/smoke.yaml ← 推荐
6
+ # • speccore verify --ui --config ./tests/smoke.yaml ← 兼容
8
7
  # 按模块过滤: speccore verify --ui --spec ./tests/smoke.yaml --module=login
9
8
  #
10
- # ⚠️ 格式说明:
11
- # VERIFY_SPEC 格式 = scenarios + actions + assertions(本文件,支持完整交互)
12
- # TestConfig 格式 = tests + routes + type(用于批量页面/API测试,见 pr.yaml/release.yaml)
13
- # 两种格式 speccore verify --config 均可自动识别。
14
- #
15
- # v8.3.95+ 支持: cookie / localStorage / script / scroll / upload / iframe / waitForRequest / waitForResponse
9
+ # 本文件所有 value / selector 均为真实示例值,使用时替换为你的实际值即可。
10
+ # 选择器建议优先使用 data-testid(最稳定),其次 name / id,避免随机 class。
16
11
 
17
12
  name: 示例项目冒烟测试
18
13
  platform: h5-mobile
19
14
  url: /
20
15
 
21
16
  scenarios:
22
- # ── 场景1: 登录流程 ──
17
+
18
+ # ═══════════════════════════════════════════════════════════════════════════
19
+ # 一、登录认证 (auth)
20
+ # ═══════════════════════════════════════════════════════════════════════════
21
+
22
+ # ── 场景1: 账号密码登录 ──
23
+ # 说明: 最基础的登录方式,填写用户名密码后点击登录
24
+ # 如何替换: 把 selector 换成你页面上的真实选择器,value 换成你的测试账号
23
25
  - name: 登录-账号密码登录
24
26
  description: 模块:auth 页面:/login
27
+ actions:
28
+ - type: navigate
29
+ value: /login # 登录页路由
30
+ - type: fill
31
+ selector: 'input[name="username"]' # 用户名输入框(换成你实际的,如 '#username' / '[data-testid="user-input"]')
32
+ value: test_user # 测试账号用户名
33
+ - type: fill
34
+ selector: 'input[name="password"]' # 密码输入框
35
+ value: Test@123456 # 测试账号密码
36
+ - type: click
37
+ selector: 'button[type="submit"]' # 登录按钮
38
+ waitFor: '.dashboard-container' # 登录成功后出现的元素(用于等待跳转完成)
39
+ assertions:
40
+ - type: url
41
+ contains: /dashboard # 断言 URL 跳转到控制台
42
+ - type: visible
43
+ selector: '.dashboard-container' # 断言控制台容器可见
44
+ - type: text
45
+ selector: '.user-name' # 断言页面显示用户名
46
+ contains: test_user # 预期显示的用户名
47
+
48
+ # ── 场景2: 手机号+验证码登录 ──
49
+ # 说明: 输入手机号 → 点击获取验证码 → 输入验证码 → 登录
50
+ # 如何替换: 测试环境通常有固定验证码(如123456),或需要 mock 验证码接口
51
+ - name: 登录-手机号验证码
52
+ description: 模块:auth 页面:/login/phone
53
+ actions:
54
+ - type: navigate
55
+ value: /login/phone # 手机号登录页路由
56
+ - type: fill
57
+ selector: 'input[name="phone"]' # 手机号输入框
58
+ value: '13800138000' # 测试手机号
59
+ - type: click
60
+ selector: '.send-code-btn' # 获取验证码按钮
61
+ - type: wait
62
+ delay: 2000 # 等待短信发送(测试环境可缩短)
63
+ - type: fill
64
+ selector: 'input[name="verifyCode"]' # 验证码输入框
65
+ value: '123456' # 测试环境固定验证码
66
+ - type: click
67
+ selector: 'button[type="submit"]' # 登录按钮
68
+ waitFor: '.dashboard-container'
69
+ assertions:
70
+ - type: url
71
+ contains: /dashboard
72
+ - type: visible
73
+ selector: '.dashboard-container'
74
+
75
+ # ── 场景3: 微信 OAuth 登录 ──
76
+ # 说明: 点击微信登录按钮 → 跳转微信授权页 → 授权后回调
77
+ # 如何替换: 需配置微信开放平台测试账号,回调域名需与测试环境一致
78
+ - name: 登录-微信OAuth
79
+ description: 模块:auth 页面:/login 第三方登录
80
+ actions:
81
+ - type: navigate
82
+ value: /login # 登录页
83
+ - type: click
84
+ selector: '.wechat-login-btn' # 微信登录按钮(如 [data-testid="wechat-login"])
85
+ - type: waitForRequest
86
+ selector: 'https://open.weixin.qq.com/connect/oauth2/authorize' # 等待跳转微信授权页
87
+ timeout: 5000
88
+ - type: wait
89
+ delay: 3000 # 等待授权回调
90
+ assertions:
91
+ - type: url
92
+ contains: wechat # 断言 URL 包含微信域名
93
+
94
+ # ── 场景4: 企业微信 SSO 登录 ──
95
+ # 说明: 页面内嵌 iframe 展示企业微信登录 → 填写企业 ID → 授权
96
+ # 如何替换: 企业 ID 从企业微信管理后台获取(格式: wwxxxxxxxxxxxxxxxx)
97
+ - name: 登录-企业微信SSO
98
+ description: 模块:auth 页面:/login/sso
99
+ actions:
100
+ - type: navigate
101
+ value: /login/sso # SSO 登录页
102
+ - type: iframe
103
+ selector: '#sso-frame' # iframe 选择器(切换上下文到 iframe 内部)
104
+ - type: fill
105
+ selector: 'input[name="corpId"]' # 企业 ID 输入框(在 iframe 内)
106
+ value: 'ww1234567890abcdef' # 企业微信企业 ID
107
+ - type: click
108
+ selector: '.sso-submit-btn' # 确认按钮(在 iframe 内)
109
+ waitFor: '.dashboard-container'
110
+ assertions:
111
+ - type: url
112
+ contains: /dashboard
113
+ - type: visible
114
+ selector: '.dashboard-container'
115
+
116
+ # ── 场景5: 扫码登录 ──
117
+ # 说明: 进入扫码页 → 二维码渲染 → 等待扫码 → 登录成功
118
+ # 如何替换: 测试环境可用 mock 接口模拟扫码成功,避免人工操作
119
+ - name: 登录-扫码登录
120
+ description: 模块:auth 页面:/login/qrcode
121
+ actions:
122
+ - type: navigate
123
+ value: /login/qrcode # 扫码登录页
124
+ - type: visible
125
+ selector: '.qrcode-img' # 断言二维码图片已渲染
126
+ - type: wait
127
+ delay: 5000 # 等待扫码(测试环境可 mock 缩短)
128
+ assertions:
129
+ - type: visible
130
+ selector: '.qrcode-img'
131
+ - type: attribute
132
+ selector: '.qrcode-img' # 断言二维码图片
133
+ attribute: src # 检查 src 属性
134
+ contains: data:image # 包含 base64 图片数据
135
+
136
+ # ── 场景6: 登录失败-密码错误 ──
137
+ # 说明: 故意输错密码,验证错误提示是否正确
138
+ # 如何替换: value 填存在的账号 + 错误的密码
139
+ - name: 登录-密码错误提示
140
+ description: 模块:auth 页面:/login 异常场景
25
141
  actions:
26
142
  - type: navigate
27
143
  value: /login
144
+ - type: fill
145
+ selector: 'input[name="username"]'
146
+ value: test_user # 存在的用户名
147
+ - type: fill
148
+ selector: 'input[name="password"]'
149
+ value: wrong_password # 故意填错密码
150
+ - type: click
151
+ selector: 'button[type="submit"]'
152
+ - type: wait
153
+ delay: 1000 # 等待错误提示出现
154
+ assertions:
155
+ - type: visible
156
+ selector: '.error-message' # 错误提示元素
157
+ - type: text
158
+ selector: '.error-message'
159
+ contains: 密码错误 # 根据实际文案调整(如"用户名或密码错误")
160
+
161
+ # ── 场景7: 登录失败-账号锁定 ──
162
+ # 说明: 使用被锁定的账号登录,验证锁定提示
163
+ - name: 登录-账号锁定提示
164
+ description: 模块:auth 页面:/login 异常场景
165
+ actions:
166
+ - type: navigate
167
+ value: /login
168
+ - type: fill
169
+ selector: 'input[name="username"]'
170
+ value: locked_user # 被锁定的测试账号
171
+ - type: fill
172
+ selector: 'input[name="password"]'
173
+ value: any_password # 任意密码
174
+ - type: click
175
+ selector: 'button[type="submit"]'
176
+ - type: wait
177
+ delay: 1000
178
+ assertions:
179
+ - type: visible
180
+ selector: '.error-message'
181
+ - type: text
182
+ selector: '.error-message'
183
+ contains: 账号已被锁定 # 根据实际文案调整
184
+
185
+ # ── 场景8: 记住密码 ──
186
+ # 说明: 勾选记住密码 → 登录 → 验证 Cookie 中写入记住密码标记
187
+ - name: 登录-记住密码
188
+ description: 模块:auth 页面:/login 记住密码勾选
189
+ actions:
190
+ - type: navigate
191
+ value: /login
192
+ - type: check
193
+ selector: 'input[name="rememberMe"]' # 记住密码复选框
28
194
  - type: fill
29
195
  selector: 'input[name="username"]'
30
196
  value: test_user
31
197
  - type: fill
32
198
  selector: 'input[name="password"]'
33
- value: test_password
199
+ value: Test@123456
34
200
  - type: click
35
201
  selector: 'button[type="submit"]'
36
202
  waitFor: '.dashboard-container'
203
+ assertions:
204
+ - type: cookie
205
+ selector: remember_me # Cookie 名称
206
+ contains: 'true' # Cookie 值包含 true
207
+
208
+ # ── 场景9: 退出登录 ──
209
+ # 说明: 点击用户头像展开菜单 → 点击退出 → 验证跳回登录页
210
+ - name: 登录-退出登录
211
+ description: 模块:auth 页面:/dashboard
212
+ actions:
213
+ - type: navigate
214
+ value: /dashboard # 已登录后的首页
215
+ - type: click
216
+ selector: '.user-avatar' # 用户头像/菜单触发器
217
+ - type: click
218
+ selector: '.logout-btn' # 退出按钮
219
+ - type: wait
220
+ delay: 1000 # 等待跳转
37
221
  assertions:
38
222
  - type: url
39
- contains: /dashboard
223
+ contains: /login # 断言回到登录页
40
224
  - type: visible
41
- selector: '.dashboard-container'
225
+ selector: '.login-form' # 断言登录表单可见
226
+
227
+ # ═══════════════════════════════════════════════════════════════════════════
228
+ # 二、用户中心 (user)
229
+ # ═══════════════════════════════════════════════════════════════════════════
42
230
 
43
- # ── 场景2: Cookie 注入免登录 ──
44
- # 适用于: 已有登录态 Cookie,跳过登录页直接测试业务模块
45
- - name: 预订列表-免登录(cookie注入)
46
- description: 模块:booking 页面:/booking/list
231
+ # ── 场景10: 修改个人资料 ──
232
+ # 说明: 修改昵称、性别、邮箱,点击保存
233
+ # select 说明: value 填 option 的 value 属性(不是显示文本)
234
+ - name: 用户-修改个人资料
235
+ description: 模块:user 页面:/profile/edit
47
236
  actions:
48
- # 注入登录 Cookie(跳过登录页)
49
- - type: cookie
50
- selector: session_token
51
- value: eyJhbGciOiJIUzI1NiIs...
52
- domain: example.com
53
- path: /
54
- secure: true
55
- httpOnly: true
56
237
  - type: navigate
57
- value: /booking/list
238
+ value: /profile/edit # 个人资料编辑页
239
+ - type: fill
240
+ selector: 'input[name="nickname"]' # 昵称输入框
241
+ value: 新昵称测试 # 新昵称
242
+ - type: select
243
+ selector: 'select[name="gender"]' # 性别下拉框
244
+ value: female # option 的 value 值(如 female/male/unknown)
245
+ - type: fill
246
+ selector: 'input[name="email"]' # 邮箱输入框
247
+ value: 'newemail@example.com' # 新邮箱
248
+ - type: click
249
+ selector: '.save-profile-btn' # 保存按钮
250
+ - type: wait
251
+ delay: 1500 # 等待保存接口返回
252
+ assertions:
253
+ - type: visible
254
+ selector: '.toast-success' # 成功提示元素
255
+ - type: text
256
+ selector: '.toast-success'
257
+ contains: 保存成功 # 预期提示文案
258
+
259
+ # ── 场景11: 上传头像 ──
260
+ # 说明: 选择本地图片文件上传,验证预览图更新
261
+ # upload 说明: value 为本地文件路径(相对项目根目录或绝对路径)
262
+ - name: 用户-上传头像
263
+ description: 模块:user 页面:/profile/edit 头像上传
264
+ actions:
265
+ - type: navigate
266
+ value: /profile/edit
267
+ - type: upload
268
+ selector: 'input[type="file"].avatar-upload' # 文件输入框
269
+ value: ./fixtures/test-avatar.png # 本地图片路径(确保文件存在)
270
+ - type: wait
271
+ delay: 2000 # 等待上传完成
272
+ assertions:
273
+ - type: visible
274
+ selector: '.avatar-preview img' # 头像预览图
275
+ - type: attribute
276
+ selector: '.avatar-preview img'
277
+ attribute: src # 断言 src 属性已更新
278
+ contains: avatar # 包含 avatar 路径
279
+
280
+ # ── 场景12: 修改密码 ──
281
+ # 说明: 填写旧密码 + 新密码 + 确认密码,点击修改
282
+ - name: 用户-修改密码
283
+ description: 模块:user 页面:/profile/security
284
+ actions:
285
+ - type: navigate
286
+ value: /profile/security # 安全设置页
287
+ - type: fill
288
+ selector: 'input[name="oldPassword"]' # 旧密码
289
+ value: OldPass123 # 当前密码
290
+ - type: fill
291
+ selector: 'input[name="newPassword"]' # 新密码
292
+ value: NewPass456 # 新密码
293
+ - type: fill
294
+ selector: 'input[name="confirmPassword"]' # 确认密码
295
+ value: NewPass456 # 与新密码保持一致
296
+ - type: click
297
+ selector: '.change-password-btn' # 确认修改按钮
298
+ - type: wait
299
+ delay: 1500
300
+ assertions:
301
+ - type: visible
302
+ selector: '.toast-success'
303
+ - type: text
304
+ selector: '.toast-success'
305
+ contains: 密码修改成功
306
+
307
+ # ── 场景13: Token 注入免登录 ──
308
+ # 说明: 直接通过 localStorage 注入 JWT,跳过登录流程
309
+ # 适用场景: 测试环境已有固定账号,不需重复测试登录
310
+ - name: 用户-Token注入免登录
311
+ description: 模块:user 页面:/profile Token注入方式
312
+ actions:
313
+ - type: localStorage
314
+ selector: accessToken # localStorage key 名
315
+ value: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEwMDg2fQ.test' # JWT Token
316
+ - type: localStorage
317
+ selector: refreshToken # 同时注入 refreshToken
318
+ value: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoicmVmcmVzaCJ9.test'
319
+ - type: navigate
320
+ value: /profile # 直接访问需要登录的页面
321
+ - type: wait
322
+ delay: 800
323
+ assertions:
324
+ - type: visible
325
+ selector: '.profile-header' # 断言个人中心头部可见
326
+ - type: text
327
+ selector: '.username' # 断言显示用户名
328
+ contains: test_user
329
+
330
+ # ═══════════════════════════════════════════════════════════════════════════
331
+ # 三、商品模块 (product)
332
+ # ═══════════════════════════════════════════════════════════════════════════
333
+
334
+ # ── 场景14: 商品列表浏览 ──
335
+ # 说明: 进入商品列表 → 滚动到底部 → 验证商品数量
336
+ - name: 商品-列表浏览
337
+ description: 模块:product 页面:/products
338
+ actions:
339
+ - type: navigate
340
+ value: /products # 商品列表页
341
+ - type: scroll
342
+ selector: bottom # 滚动到页面底部(触发懒加载)
58
343
  - type: wait
59
344
  delay: 1000
60
345
  assertions:
61
346
  - type: visible
62
- selector: '.booking-list'
347
+ selector: '.product-list' # 商品列表容器
63
348
  - type: count
64
- selector: '.booking-item'
65
- count: 5
349
+ selector: '.product-item' # 商品卡片
350
+ count: 10 # 预期至少 10 个商品
66
351
 
67
- # ── 场景3: localStorage 注入 Token ──
68
- # 适用于: JWT Token 存储在 localStorage 的前端项目
69
- - name: 个人中心-Token注入
70
- description: 模块:user 页面:/profile
352
+ # ── 场景15: 商品搜索 ──
353
+ # 说明: 输入关键词 → 按回车 → 验证搜索结果
354
+ - name: 商品-搜索
355
+ description: 模块:product 页面:/products 搜索功能
71
356
  actions:
72
- - type: localStorage
73
- selector: accessToken
74
- value: Bearer eyJhbGciOiJIUzI1NiIs...
75
357
  - type: navigate
76
- value: /profile
358
+ value: /products
359
+ - type: fill
360
+ selector: 'input[name="keyword"]' # 搜索框
361
+ value: iPhone # 搜索关键词
362
+ - type: press
363
+ key: Enter # 按回车触发搜索
364
+ - type: wait
365
+ delay: 1500 # 等待搜索结果返回
366
+ assertions:
367
+ - type: visible
368
+ selector: '.search-result-list' # 搜索结果列表
369
+ - type: count
370
+ selector: '.product-item'
371
+ count: 3 # 预期至少 3 个结果
372
+
373
+ # ── 场景16: 商品详情 ──
374
+ # 说明: 点击商品标题进入详情页,验证详情信息展示
375
+ - name: 商品-详情页
376
+ description: 模块:product 页面:/products/:id
377
+ actions:
378
+ - type: navigate
379
+ value: /products
380
+ - type: click
381
+ selector: '.product-item:first-child .product-title' # 点击第一个商品的标题
382
+ - type: wait
383
+ delay: 1000
384
+ assertions:
385
+ - type: visible
386
+ selector: '.product-detail' # 详情页容器
387
+ - type: text
388
+ selector: '.product-name' # 商品名称
389
+ contains: iPhone # 包含搜索关键词
390
+ - type: visible
391
+ selector: '.product-price' # 价格元素
392
+
393
+ # ── 场景17: 商品多条件筛选 ──
394
+ # 说明: 同时选择分类 + 库存状态,验证筛选结果
395
+ - name: 商品-多条件筛选
396
+ description: 模块:product 页面:/products 筛选功能
397
+ actions:
398
+ - type: navigate
399
+ value: /products
400
+ - type: select
401
+ selector: 'select[name="category"]' # 分类下拉框
402
+ value: electronics # option value(如 electronics/clothing/food)
403
+ - type: check
404
+ selector: 'input[value="inStock"]' # 仅看有库存(复选框)
405
+ - type: click
406
+ selector: '.filter-submit-btn' # 确认筛选按钮
407
+ - type: wait
408
+ delay: 1200
409
+ assertions:
410
+ - type: visible
411
+ selector: '.product-list'
412
+ - type: count
413
+ selector: '.product-item'
414
+ count: 5 # 筛选后预期 5 个商品
415
+
416
+ # ── 场景18: 商品收藏 ──
417
+ # 说明: 点击收藏按钮,验证按钮颜色变为红色(已收藏状态)
418
+ - name: 商品-收藏/取消收藏
419
+ description: 模块:product 页面:/products/:id 收藏功能
420
+ actions:
421
+ - type: navigate
422
+ value: /products/123 # 某个商品详情页(123 为商品 ID)
423
+ - type: click
424
+ selector: '.favorite-btn' # 收藏按钮(空心)
77
425
  - type: wait
78
426
  delay: 500
427
+ assertions:
428
+ - type: style
429
+ selector: '.favorite-btn' # 断言按钮样式变化
430
+ style: color # CSS 属性: 颜色
431
+ value: rgb(255, 77, 79) # 预期变为红色(根据实际样式调整)
432
+
433
+ # ═══════════════════════════════════════════════════════════════════════════
434
+ # 四、购物车 (cart)
435
+ # ═══════════════════════════════════════════════════════════════════════════
436
+
437
+ # ── 场景19: 添加商品到购物车 ──
438
+ # 说明: 商品详情页点击加购,验证购物车角标数字更新
439
+ - name: 购物车-添加商品
440
+ description: 模块:cart 页面:/products/:id
441
+ actions:
442
+ - type: navigate
443
+ value: /products/123 # 商品详情页
444
+ - type: click
445
+ selector: '.add-to-cart-btn' # 加入购物车按钮
446
+ - type: wait
447
+ delay: 800 # 等待加购动画/接口
79
448
  assertions:
80
449
  - type: visible
81
- selector: '.profile-header'
450
+ selector: '.cart-badge' # 购物车角标
82
451
  - type: text
83
- selector: '.username'
84
- contains: test_user
452
+ selector: '.cart-badge'
453
+ contains: '1' # 角标显示 1
85
454
 
86
- # ── 场景4: 按模块测试示例 (booking 模块) ──
87
- # 运行: speccore verify --ui --config ./tests/smoke.yaml --module=booking
88
- - name: 预订表单-提交预订
89
- description: 模块:booking 页面:/booking/create
455
+ # ── 场景20: 修改购物车商品数量 ──
456
+ # 说明: 修改数量输入框 → 失去焦点触发计算 → 验证小计金额更新
457
+ - name: 购物车-修改数量
458
+ description: 模块:cart 页面:/cart
90
459
  actions:
91
460
  - type: navigate
92
- value: /booking/create
461
+ value: /cart # 购物车页面
93
462
  - type: fill
94
- selector: 'input[name="checkIn"]'
95
- value: '2026-10-01'
463
+ selector: '.cart-item:first-child .quantity-input' # 第一个商品的数量输入框
464
+ value: '3' # 修改为 3 件
465
+ - type: blur
466
+ selector: '.cart-item:first-child .quantity-input' # 触发 blur 事件(触发价格重算)
467
+ - type: wait
468
+ delay: 800
469
+ assertions:
470
+ - type: text
471
+ selector: '.cart-item:first-child .subtotal' # 小计金额
472
+ contains: '¥' # 包含人民币符号(断言金额已更新)
473
+
474
+ # ── 场景21: 购物车去结算 ──
475
+ # 说明: 勾选商品 → 点击结算 → 验证跳转到结算页
476
+ - name: 购物车-去结算
477
+ description: 模块:cart 页面:/cart
478
+ actions:
479
+ - type: navigate
480
+ value: /cart
481
+ - type: check
482
+ selector: '.cart-item:first-child .item-checkbox' # 勾选第一个商品
483
+ - type: click
484
+ selector: '.checkout-btn' # 去结算按钮
485
+ - type: wait
486
+ delay: 1500
487
+ assertions:
488
+ - type: url
489
+ contains: /checkout # 断言跳转到结算页
490
+ - type: visible
491
+ selector: '.checkout-form' # 结算表单
492
+
493
+ # ── 场景22: 删除购物车商品 ──
494
+ # 说明: 点击删除按钮,验证商品被移除
495
+ - name: 购物车-删除商品
496
+ description: 模块:cart 页面:/cart
497
+ actions:
498
+ - type: navigate
499
+ value: /cart
500
+ - type: click
501
+ selector: '.cart-item:first-child .delete-btn' # 删除按钮
502
+ - type: wait
503
+ delay: 800
504
+ assertions:
505
+ - type: count
506
+ selector: '.cart-item' # 断言购物车商品数量
507
+ count: 0 # 预期为 0(空购物车)
508
+
509
+ # ═══════════════════════════════════════════════════════════════════════════
510
+ # 五、订单模块 (order)
511
+ # ═══════════════════════════════════════════════════════════════════════════
512
+
513
+ # ── 场景23: 创建订单 ──
514
+ # 说明: 填写收货信息 → 提交订单 → 验证订单创建成功
515
+ - name: 订单-创建订单
516
+ description: 模块:order 页面:/checkout
517
+ actions:
518
+ - type: navigate
519
+ value: /checkout # 结算页
520
+ - type: fill
521
+ selector: 'input[name="receiverName"]' # 收货人姓名
522
+ value: 张三 # 真实姓名或测试姓名
96
523
  - type: fill
97
- selector: 'input[name="checkOut"]'
98
- value: '2026-10-05'
524
+ selector: 'input[name="phone"]' # 手机号
525
+ value: '13800138000'
526
+ - type: fill
527
+ selector: 'input[name="address"]' # 详细地址
528
+ value: 北京市朝阳区测试街道123号 # 测试地址
529
+ - type: click
530
+ selector: '.submit-order-btn' # 提交订单按钮
531
+ - type: wait
532
+ delay: 2000 # 等待订单创建接口
533
+ assertions:
534
+ - type: url
535
+ contains: /order/success # 断言跳转到成功页
536
+ - type: visible
537
+ selector: '.order-success' # 成功提示
538
+ - type: text
539
+ selector: '.order-success'
540
+ contains: 订单提交成功
541
+
542
+ # ── 场景24: 订单支付 ──
543
+ # 说明: 选择支付方式 → 确认支付 → 等待支付接口返回 → 验证成功
544
+ - name: 订单-支付订单
545
+ description: 模块:order 页面:/pay/:orderId
546
+ actions:
547
+ - type: navigate
548
+ value: /pay/ORD202409110001 # 支付页(ORD202409110001 为订单号)
549
+ - type: click
550
+ selector: '.pay-method-wechat' # 选择微信支付
551
+ - type: click
552
+ selector: '.confirm-pay-btn' # 确认支付按钮
553
+ - type: waitForResponse
554
+ selector: '/api/pay/create' # 等待支付创建接口返回
555
+ timeout: 10000 # 支付接口较慢,超时设 10 秒
556
+ - type: wait
557
+ delay: 2000
558
+ assertions:
559
+ - type: url
560
+ contains: /pay/success # 断言跳转到支付成功页
561
+ - type: visible
562
+ selector: '.pay-success'
563
+
564
+ # ── 场景25: 订单列表查询 ──
565
+ - name: 订单-列表查询
566
+ description: 模块:order 页面:/orders
567
+ actions:
568
+ - type: navigate
569
+ value: /orders # 订单列表页
570
+ - type: wait
571
+ delay: 1000
572
+ assertions:
573
+ - type: visible
574
+ selector: '.order-list'
575
+ - type: count
576
+ selector: '.order-item'
577
+ count: 5 # 预期至少 5 个订单
578
+
579
+ # ── 场景26: 订单详情查看 ──
580
+ - name: 订单-详情查看
581
+ description: 模块:order 页面:/orders/:id
582
+ actions:
583
+ - type: navigate
584
+ value: /orders
99
585
  - type: click
100
- selector: '.search-btn'
101
- waitFor: '.room-list'
586
+ selector: '.order-item:first-child .view-detail-btn' # 查看第一个订单详情
587
+ - type: wait
588
+ delay: 800
589
+ assertions:
590
+ - type: visible
591
+ selector: '.order-detail'
592
+ - type: text
593
+ selector: '.order-status' # 订单状态
594
+ contains: 待付款 # 预期状态文案
595
+
596
+ # ── 场景27: 取消订单 ──
597
+ # 说明: 点击取消 → 确认取消 → 验证状态变为已取消
598
+ - name: 订单-取消订单
599
+ description: 模块:order 页面:/orders/:id
600
+ actions:
601
+ - type: navigate
602
+ value: /orders/ORD202409110001 # 某个待付款订单
603
+ - type: click
604
+ selector: '.cancel-order-btn' # 取消订单按钮
605
+ - type: wait
606
+ delay: 500 # 等待确认弹窗
102
607
  - type: click
103
- selector: '.room-item:first-child .select-btn'
608
+ selector: '.confirm-cancel-btn' # 确认取消按钮
609
+ - type: wait
610
+ delay: 1500 # 等待取消接口返回
611
+ assertions:
612
+ - type: text
613
+ selector: '.order-status'
614
+ contains: 已取消 # 状态变为已取消
615
+
616
+ # ═══════════════════════════════════════════════════════════════════════════
617
+ # 六、消息通知 (notification)
618
+ # ═══════════════════════════════════════════════════════════════════════════
619
+
620
+ # ── 场景28: 消息列表查看 ──
621
+ - name: 消息-列表查看
622
+ description: 模块:notification 页面:/notifications
623
+ actions:
624
+ - type: navigate
625
+ value: /notifications # 消息中心
626
+ - type: wait
627
+ delay: 1000
628
+ assertions:
629
+ - type: visible
630
+ selector: '.notification-list'
631
+ - type: count
632
+ selector: '.notification-item'
633
+ count: 3 # 预期 3 条未读消息
634
+
635
+ # ── 场景29: 消息标记已读 ──
636
+ # 说明: 点击消息 → 验证字体从粗体变为正常(已读状态)
637
+ - name: 消息-标记已读
638
+ description: 模块:notification 页面:/notifications
639
+ actions:
640
+ - type: navigate
641
+ value: /notifications
104
642
  - type: click
105
- selector: '.submit-booking-btn'
106
- waitFor: '.booking-success'
643
+ selector: '.notification-item:first-child' # 点击第一条消息
644
+ - type: wait
645
+ delay: 500
646
+ assertions:
647
+ - type: style
648
+ selector: '.notification-item:first-child'
649
+ style: font-weight # CSS 属性: 字重
650
+ value: '400' # 400 = normal(已读),700 = bold(未读)
651
+
652
+ # ═══════════════════════════════════════════════════════════════════════════
653
+ # 七、后台管理 (admin)
654
+ # ═══════════════════════════════════════════════════════════════════════════
655
+
656
+ # ── 场景30: 用户管理列表 ──
657
+ - name: 后台-用户管理
658
+ description: 模块:admin 页面:/admin/users
659
+ actions:
660
+ - type: navigate
661
+ value: /admin/users # 后台用户管理页
662
+ - type: wait
663
+ delay: 1500 # 等待表格数据加载
107
664
  assertions:
108
665
  - type: visible
109
- selector: '.booking-success'
666
+ selector: '.user-table' # 用户表格
667
+ - type: count
668
+ selector: '.user-table tbody tr' # 表格行数
669
+ count: 10 # 预期 10 条用户数据
670
+
671
+ # ── 场景31: 数据报表(iframe 嵌入) ──
672
+ # 说明: 后台报表通常用 iframe 嵌入第三方 BI 工具(如帆软、Tableau)
673
+ - name: 后台-数据报表iframe
674
+ description: 模块:admin 页面:/admin/reports iframe嵌入
675
+ actions:
676
+ - type: navigate
677
+ value: /admin/reports # 报表页面
678
+ - type: iframe
679
+ selector: '#report-frame' # 报表 iframe
680
+ - type: wait
681
+ delay: 2000 # 等待 iframe 内报表加载
682
+ assertions:
683
+ - type: visible
684
+ selector: '.chart-container' # 图表容器(在 iframe 内)
685
+ - type: count
686
+ selector: '.chart-item' # 图表数量
687
+ count: 4 # 预期 4 个图表
688
+
689
+ # ── 场景32: 拖拽排序 ──
690
+ # 说明: 拖拽分类/菜单项调整顺序
691
+ - name: 后台-拖拽排序
692
+ description: 模块:admin 页面:/admin/categories 拖拽排序
693
+ actions:
694
+ - type: navigate
695
+ value: /admin/categories # 分类管理页
696
+ - type: drag
697
+ selector: '.category-item:first-child' # 拖拽第一个分类
698
+ toSelector: '.category-item:last-child' # 放到最后一个位置
699
+ - type: wait
700
+ delay: 1000 # 等待保存接口
701
+ assertions:
110
702
  - type: text
111
- selector: '.booking-success'
112
- contains: 预订成功
703
+ selector: '.category-item:last-child .category-name' # 断言最后一个分类的名称
704
+ contains: 原第一个分类 # 确认拖拽成功
705
+
706
+ # ═══════════════════════════════════════════════════════════════════════════
707
+ # 八、通用能力
708
+ # ═══════════════════════════════════════════════════════════════════════════
113
709
 
114
- # ── 场景5: 滚动 + 元素存在性检查 ──
115
- - name: 首页-滚动加载
710
+ # ── 场景33: Cookie 注入免登录 ──
711
+ # 说明: 直接注入 session Cookie,跳过登录页,适合批量测试业务模块
712
+ # 如何获取 Cookie: 在浏览器开发者工具 → Application → Cookies 中复制
713
+ - name: 通用-Cookie注入免登录
714
+ description: 模块:common Cookie注入跳过登录
715
+ actions:
716
+ - type: cookie
717
+ selector: session_token # Cookie 名称
718
+ value: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEwMDg2fQ.test' # Cookie 值
719
+ domain: example.com # Cookie 域名(必须与测试站点一致)
720
+ path: / # Cookie 路径
721
+ secure: true # 仅 HTTPS 传输
722
+ httpOnly: true # 禁止 JS 读取
723
+ - type: cookie
724
+ selector: user_id # 同时注入 user_id
725
+ value: '10086'
726
+ domain: example.com
727
+ path: /
728
+ - type: navigate
729
+ value: /dashboard # 直接访问需登录页面
730
+ - type: wait
731
+ delay: 1000
732
+ assertions:
733
+ - type: visible
734
+ selector: '.dashboard-container'
735
+ - type: text
736
+ selector: '.user-name'
737
+ contains: test_user
738
+
739
+ # ── 场景34: 首页滚动加载 ──
740
+ - name: 通用-首页滚动加载
116
741
  description: 模块:home 页面:/
117
742
  actions:
118
743
  - type: navigate
119
744
  value: /
120
745
  - type: scroll
121
- selector: bottom
746
+ selector: bottom # 滚动到底部
122
747
  - type: wait
123
- delay: 1000
748
+ delay: 1500
749
+ - type: scroll
750
+ selector: bottom # 再次滚动(触发第二轮加载)
751
+ - type: wait
752
+ delay: 1500
124
753
  assertions:
125
754
  - type: visible
126
- selector: '.footer'
755
+ selector: '.load-more-btn' # 加载更多按钮
756
+ - type: count
757
+ selector: '.product-card' # 商品卡片总数
758
+ count: 20 # 预期加载了 20 个商品
127
759
 
128
- # ── 场景6: 样式断言 ──
129
- - name: 按钮-样式检查
760
+ # ── 场景35: 样式断言 ──
761
+ # 说明: 验证按钮颜色、圆角等样式是否符合设计稿
762
+ - name: 通用-按钮样式检查
130
763
  description: 模块:ui 页面:/
131
764
  actions:
132
765
  - type: navigate
133
766
  value: /
134
767
  assertions:
768
+ - type: style
769
+ selector: '.primary-btn' # 主按钮
770
+ style: background-color # CSS 属性: 背景色
771
+ value: rgb(24, 144, 255) # 预期颜色(根据设计稿调整)
135
772
  - type: style
136
773
  selector: '.primary-btn'
137
- style: background-color
138
- value: rgb(24, 144, 255)
774
+ style: border-radius # CSS 属性: 圆角
775
+ value: 4px # 预期 4px 圆角
776
+
777
+ # ── 场景36: 视觉对比测试 ──
778
+ # 说明: 截图后与基线图片对比,检测 UI 回归
779
+ # 前置条件: 先执行一次生成基线图片,后续对比以此为准
780
+ - name: 通用-视觉对比测试
781
+ description: 模块:ui 页面:/ 视觉回归
782
+ actions:
783
+ - type: navigate
784
+ value: /
785
+ - type: screenshot # 页面截图
786
+ assertions:
787
+ - type: visual
788
+ selector: 'body' # 对比整个页面
789
+ threshold: normal # 阈值: strict/normal/loose
790
+
791
+ # ── 场景37: 键盘操作 ──
792
+ # 说明: 聚焦搜索框 → 输入关键词 → 按回车触发搜索
793
+ - name: 通用-键盘操作
794
+ description: 模块:common 页面:/products 键盘导航
795
+ actions:
796
+ - type: navigate
797
+ value: /products
798
+ - type: focus
799
+ selector: 'input[name="keyword"]' # 聚焦搜索框
800
+ - type: fill
801
+ selector: 'input[name="keyword"]'
802
+ value: MacBook
803
+ - type: press
804
+ key: Enter # 按回车
805
+ - type: wait
806
+ delay: 1500
807
+ assertions:
808
+ - type: visible
809
+ selector: '.search-result-list'
810
+ - type: count
811
+ selector: '.product-item'
812
+ count: 2 # 预期 2 个结果
813
+
814
+ # ── 场景38: hover 效果 ──
815
+ # 说明: 鼠标悬停在商品卡片上,验证阴影/边框等 hover 样式
816
+ - name: 通用-hover效果
817
+ description: 模块:ui 页面:/products hover交互
818
+ actions:
819
+ - type: navigate
820
+ value: /products
821
+ - type: hover
822
+ selector: '.product-item:first-child' # 悬停在第一个商品
823
+ - type: wait
824
+ delay: 500 # 等待 hover 动画
825
+ assertions:
826
+ - type: style
827
+ selector: '.product-item:first-child'
828
+ style: box-shadow # CSS 属性: 阴影
829
+ contains: rgba # 包含 rgba(有阴影)
830
+
831
+ # ── 场景39: 元素隐藏检查 ──
832
+ # 说明: 验证未登录状态下,用户菜单和退出按钮不显示
833
+ - name: 通用-元素隐藏
834
+ description: 模块:ui 页面:/login 未登录状态
835
+ actions:
836
+ - type: navigate
837
+ value: /login # 未登录页面
838
+ assertions:
839
+ - type: hidden
840
+ selector: '.user-menu' # 用户菜单应隐藏
841
+ - type: hidden
842
+ selector: '.logout-btn' # 退出按钮应隐藏
843
+
844
+ # ── 场景40: 表单值断言 ──
845
+ # 说明: 验证表单字段的默认值是否正确
846
+ - name: 通用-表单值检查
847
+ description: 模块:user 页面:/profile/edit 表单默认值
848
+ actions:
849
+ - type: navigate
850
+ value: /profile/edit
851
+ assertions:
852
+ - type: value
853
+ selector: 'input[name="username"]' # 断言表单值
854
+ equals: test_user # 精确匹配
855
+ - type: value
856
+ selector: 'input[name="email"]'
857
+ contains: '@' # 包含 @ 符号
858
+
859
+ # ── 场景41: JavaScript 注入执行 ──
860
+ # 说明: 执行自定义 JS,如修改全局变量、调用前端方法
861
+ - name: 通用-JS脚本注入
862
+ description: 模块:common 页面:/ JS注入测试
863
+ actions:
864
+ - type: navigate
865
+ value: /
866
+ - type: script
867
+ value: 'window.testFlag = "injected";' # 设置全局变量
868
+ - type: wait
869
+ delay: 500
870
+ - type: script
871
+ value: 'return window.testFlag;' # 读取全局变量(返回给引擎)
872
+ assertions:
873
+ - type: text
874
+ selector: 'body'
875
+ contains: injected # 断言页面包含 injected 文本
876
+
877
+ # ── 场景42: 响应式布局测试 ──
878
+ # 说明: 验证移动端下显示移动端导航,隐藏桌面端侧边栏
879
+ # 注意: Playwright 可通过 viewport 配置模拟不同设备尺寸
880
+ - name: 通用-响应式布局
881
+ description: 模块:ui 页面:/ 移动端适配
882
+ actions:
883
+ - type: navigate
884
+ value: /
885
+ - type: wait
886
+ delay: 800
887
+ assertions:
888
+ - type: visible
889
+ selector: '.mobile-nav' # 移动端导航应可见
890
+ - type: hidden
891
+ selector: '.desktop-sidebar' # 桌面端侧边栏应隐藏