@boyingliu01/xp-gate 0.7.0 → 0.8.0
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/bin/xp-gate.js +4 -9
- package/lib/__tests__/audit-log.test.ts +107 -0
- package/lib/__tests__/detect-deps.test.js +212 -42
- package/lib/__tests__/doctor.test.js +1 -0
- package/lib/__tests__/gate-audit.test.ts +59 -0
- package/lib/__tests__/init.test.js +47 -1
- package/lib/__tests__/install-skill.test.js +1 -45
- package/lib/__tests__/ui-detector.test.ts +186 -26
- package/lib/__tests__/ui-review.test.ts +119 -0
- package/lib/__tests__/uninstall.test.js +1 -0
- package/lib/detect-deps.js +180 -37
- package/lib/doctor.js +7 -9
- package/lib/gate-audit.ts +26 -42
- package/lib/init.js +42 -13
- package/lib/install-skill.js +20 -48
- package/lib/rollback.js +1 -16
- package/lib/shared-paths.js +30 -0
- package/lib/shared-utils.js +25 -0
- package/lib/ui-detector.ts +20 -14
- package/lib/ui-review.ts +58 -53
- package/lib/uninstall.js +8 -9
- package/package.json +1 -1
- package/plugins/claude-code/.claude-plugin/plugin.json +1 -1
- package/plugins/claude-code/skills/admin-template-guidelines/SKILL.md +904 -0
- package/plugins/claude-code/skills/delphi-review/.delphi-config.json.example +45 -0
- package/plugins/claude-code/skills/delphi-review/AGENTS.md +66 -0
- package/plugins/claude-code/skills/delphi-review/INSTALL.md +152 -0
- package/plugins/claude-code/skills/delphi-review/SKILL.md +454 -0
- package/plugins/claude-code/skills/delphi-review/opencode.json.delphi.example +56 -0
- package/plugins/claude-code/skills/delphi-review/references/code-walkthrough.md +486 -0
- package/plugins/claude-code/skills/improve-codebase-architecture/SKILL.md +156 -0
- package/plugins/claude-code/skills/ralph-loop/SKILL.md +501 -0
- package/plugins/claude-code/skills/ralph-loop/references/components/memory.md +55 -0
- package/plugins/claude-code/skills/ralph-loop/references/components/middleware.md +54 -0
- package/plugins/claude-code/skills/ralph-loop/references/components/skill-invocations.md +39 -0
- package/plugins/claude-code/skills/ralph-loop/references/components/system-prompt.md +24 -0
- package/plugins/claude-code/skills/ralph-loop/references/components/tool-descriptions.md +32 -0
- package/plugins/claude-code/skills/ralph-loop/references/phase-2-build-ralph.md +89 -0
- package/plugins/claude-code/skills/ralph-loop/templates/progress-log.md +36 -0
- package/plugins/claude-code/skills/sprint-flow/AGENTS.md +68 -0
- package/plugins/claude-code/skills/sprint-flow/SKILL.md +1248 -0
- package/plugins/claude-code/skills/sprint-flow/references/components/memory.md +87 -0
- package/plugins/claude-code/skills/sprint-flow/references/components/middleware.md +72 -0
- package/plugins/claude-code/skills/sprint-flow/references/components/skill-invocations.md +104 -0
- package/plugins/claude-code/skills/sprint-flow/references/components/system-prompt.md +27 -0
- package/plugins/claude-code/skills/sprint-flow/references/components/tool-descriptions.md +96 -0
- package/plugins/claude-code/skills/sprint-flow/references/force-levels.md +203 -0
- package/plugins/claude-code/skills/sprint-flow/references/phase-0-think.md +115 -0
- package/plugins/claude-code/skills/sprint-flow/references/phase-1-plan.md +178 -0
- package/plugins/claude-code/skills/sprint-flow/references/phase-2-build.md +198 -0
- package/plugins/claude-code/skills/sprint-flow/references/phase-3-review.md +213 -0
- package/plugins/claude-code/skills/sprint-flow/references/phase-4-uat.md +125 -0
- package/plugins/claude-code/skills/sprint-flow/references/phase-5-feedback.md +100 -0
- package/plugins/claude-code/skills/sprint-flow/references/phase-6-ship.md +193 -0
- package/plugins/claude-code/skills/sprint-flow/references/phase-7-land.md +140 -0
- package/plugins/claude-code/skills/sprint-flow/references/phase-8-cleanup.md +192 -0
- package/plugins/claude-code/skills/sprint-flow/references/phase-minus-0-5-auto-estimate.md +257 -0
- package/plugins/claude-code/skills/sprint-flow/templates/auto-estimate-learning-log.md +136 -0
- package/plugins/claude-code/skills/sprint-flow/templates/auto-estimate-output-template.md +132 -0
- package/plugins/claude-code/skills/sprint-flow/templates/emergent-issues-template.md +120 -0
- package/plugins/claude-code/skills/sprint-flow/templates/pain-document-template.md +115 -0
- package/plugins/claude-code/skills/sprint-flow/templates/sprint-progress-template.md +151 -0
- package/plugins/claude-code/skills/sprint-flow/templates/sprint-summary-template.md +120 -0
- package/plugins/claude-code/skills/test-driven-development/SKILL.md +71 -0
- package/plugins/claude-code/skills/test-specification-alignment/AGENTS.md +56 -0
- package/plugins/claude-code/skills/test-specification-alignment/SKILL.md +702 -0
- package/plugins/claude-code/skills/test-specification-alignment/references/alignment-verification-algorithm.md +493 -0
- package/plugins/claude-code/skills/test-specification-alignment/references/phase2-constraint-enforcement.md +431 -0
- package/plugins/claude-code/skills/test-specification-alignment/references/specification-format.md +348 -0
- package/plugins/claude-code/skills/to-issues/SKILL.md +277 -0
- package/plugins/opencode/README.md +38 -0
- package/plugins/opencode/index.ts +85 -0
- package/plugins/opencode/package.json +18 -0
- package/plugins/opencode/skills/admin-template-guidelines/SKILL.md +904 -0
- package/plugins/opencode/skills/delphi-review/.delphi-config.json.example +45 -0
- package/plugins/opencode/skills/delphi-review/AGENTS.md +66 -0
- package/plugins/opencode/skills/delphi-review/INSTALL.md +152 -0
- package/plugins/opencode/skills/delphi-review/SKILL.md +454 -0
- package/plugins/opencode/skills/delphi-review/opencode.json.delphi.example +56 -0
- package/plugins/opencode/skills/delphi-review/references/code-walkthrough.md +486 -0
- package/plugins/opencode/skills/improve-codebase-architecture/SKILL.md +156 -0
- package/plugins/opencode/skills/ralph-loop/SKILL.md +501 -0
- package/plugins/opencode/skills/ralph-loop/references/components/memory.md +55 -0
- package/plugins/opencode/skills/ralph-loop/references/components/middleware.md +54 -0
- package/plugins/opencode/skills/ralph-loop/references/components/skill-invocations.md +39 -0
- package/plugins/opencode/skills/ralph-loop/references/components/system-prompt.md +24 -0
- package/plugins/opencode/skills/ralph-loop/references/components/tool-descriptions.md +32 -0
- package/plugins/opencode/skills/ralph-loop/references/phase-2-build-ralph.md +89 -0
- package/plugins/opencode/skills/ralph-loop/templates/progress-log.md +36 -0
- package/plugins/opencode/skills/sprint-flow/AGENTS.md +68 -0
- package/plugins/opencode/skills/sprint-flow/SKILL.md +1248 -0
- package/plugins/opencode/skills/sprint-flow/references/components/memory.md +87 -0
- package/plugins/opencode/skills/sprint-flow/references/components/middleware.md +72 -0
- package/plugins/opencode/skills/sprint-flow/references/components/skill-invocations.md +104 -0
- package/plugins/opencode/skills/sprint-flow/references/components/system-prompt.md +27 -0
- package/plugins/opencode/skills/sprint-flow/references/components/tool-descriptions.md +96 -0
- package/plugins/opencode/skills/sprint-flow/references/force-levels.md +203 -0
- package/plugins/opencode/skills/sprint-flow/references/phase-0-think.md +115 -0
- package/plugins/opencode/skills/sprint-flow/references/phase-1-plan.md +178 -0
- package/plugins/opencode/skills/sprint-flow/references/phase-2-build.md +198 -0
- package/plugins/opencode/skills/sprint-flow/references/phase-3-review.md +213 -0
- package/plugins/opencode/skills/sprint-flow/references/phase-4-uat.md +125 -0
- package/plugins/opencode/skills/sprint-flow/references/phase-5-feedback.md +100 -0
- package/plugins/opencode/skills/sprint-flow/references/phase-6-ship.md +193 -0
- package/plugins/opencode/skills/sprint-flow/references/phase-7-land.md +140 -0
- package/plugins/opencode/skills/sprint-flow/references/phase-8-cleanup.md +192 -0
- package/plugins/opencode/skills/sprint-flow/references/phase-minus-0-5-auto-estimate.md +257 -0
- package/plugins/opencode/skills/sprint-flow/templates/auto-estimate-learning-log.md +136 -0
- package/plugins/opencode/skills/sprint-flow/templates/auto-estimate-output-template.md +132 -0
- package/plugins/opencode/skills/sprint-flow/templates/emergent-issues-template.md +120 -0
- package/plugins/opencode/skills/sprint-flow/templates/pain-document-template.md +115 -0
- package/plugins/opencode/skills/sprint-flow/templates/sprint-progress-template.md +151 -0
- package/plugins/opencode/skills/sprint-flow/templates/sprint-summary-template.md +120 -0
- package/plugins/opencode/skills/test-driven-development/SKILL.md +71 -0
- package/plugins/opencode/skills/test-specification-alignment/AGENTS.md +56 -0
- package/plugins/opencode/skills/test-specification-alignment/SKILL.md +702 -0
- package/plugins/opencode/skills/test-specification-alignment/references/alignment-verification-algorithm.md +493 -0
- package/plugins/opencode/skills/test-specification-alignment/references/phase2-constraint-enforcement.md +431 -0
- package/plugins/opencode/skills/test-specification-alignment/references/specification-format.md +348 -0
- package/plugins/opencode/skills/to-issues/SKILL.md +277 -0
- package/plugins/opencode/tsconfig.json +15 -0
- package/plugins/qoder/skills/admin-template-guidelines/SKILL.md +904 -0
- package/plugins/qoder/skills/delphi-review/.delphi-config.json.example +45 -0
- package/plugins/qoder/skills/delphi-review/AGENTS.md +66 -0
- package/plugins/qoder/skills/delphi-review/INSTALL.md +152 -0
- package/plugins/qoder/skills/delphi-review/SKILL.md +454 -0
- package/plugins/qoder/skills/delphi-review/opencode.json.delphi.example +56 -0
- package/plugins/qoder/skills/delphi-review/references/code-walkthrough.md +486 -0
- package/plugins/qoder/skills/improve-codebase-architecture/SKILL.md +156 -0
- package/plugins/qoder/skills/ralph-loop/SKILL.md +501 -0
- package/plugins/qoder/skills/ralph-loop/references/components/memory.md +55 -0
- package/plugins/qoder/skills/ralph-loop/references/components/middleware.md +54 -0
- package/plugins/qoder/skills/ralph-loop/references/components/skill-invocations.md +39 -0
- package/plugins/qoder/skills/ralph-loop/references/components/system-prompt.md +24 -0
- package/plugins/qoder/skills/ralph-loop/references/components/tool-descriptions.md +32 -0
- package/plugins/qoder/skills/ralph-loop/references/phase-2-build-ralph.md +89 -0
- package/plugins/qoder/skills/ralph-loop/templates/progress-log.md +36 -0
- package/plugins/qoder/skills/sprint-flow/AGENTS.md +68 -0
- package/plugins/qoder/skills/sprint-flow/SKILL.md +1248 -0
- package/plugins/qoder/skills/sprint-flow/references/components/memory.md +87 -0
- package/plugins/qoder/skills/sprint-flow/references/components/middleware.md +72 -0
- package/plugins/qoder/skills/sprint-flow/references/components/skill-invocations.md +104 -0
- package/plugins/qoder/skills/sprint-flow/references/components/system-prompt.md +27 -0
- package/plugins/qoder/skills/sprint-flow/references/components/tool-descriptions.md +96 -0
- package/plugins/qoder/skills/sprint-flow/references/force-levels.md +203 -0
- package/plugins/qoder/skills/sprint-flow/references/phase-0-think.md +115 -0
- package/plugins/qoder/skills/sprint-flow/references/phase-1-plan.md +178 -0
- package/plugins/qoder/skills/sprint-flow/references/phase-2-build.md +198 -0
- package/plugins/qoder/skills/sprint-flow/references/phase-3-review.md +213 -0
- package/plugins/qoder/skills/sprint-flow/references/phase-4-uat.md +125 -0
- package/plugins/qoder/skills/sprint-flow/references/phase-5-feedback.md +100 -0
- package/plugins/qoder/skills/sprint-flow/references/phase-6-ship.md +193 -0
- package/plugins/qoder/skills/sprint-flow/references/phase-7-land.md +140 -0
- package/plugins/qoder/skills/sprint-flow/references/phase-8-cleanup.md +192 -0
- package/plugins/qoder/skills/sprint-flow/references/phase-minus-0-5-auto-estimate.md +257 -0
- package/plugins/qoder/skills/sprint-flow/templates/auto-estimate-learning-log.md +136 -0
- package/plugins/qoder/skills/sprint-flow/templates/auto-estimate-output-template.md +132 -0
- package/plugins/qoder/skills/sprint-flow/templates/emergent-issues-template.md +120 -0
- package/plugins/qoder/skills/sprint-flow/templates/pain-document-template.md +115 -0
- package/plugins/qoder/skills/sprint-flow/templates/sprint-progress-template.md +151 -0
- package/plugins/qoder/skills/sprint-flow/templates/sprint-summary-template.md +120 -0
- package/plugins/qoder/skills/test-driven-development/SKILL.md +71 -0
- package/plugins/qoder/skills/test-specification-alignment/AGENTS.md +56 -0
- package/plugins/qoder/skills/test-specification-alignment/SKILL.md +702 -0
- package/plugins/qoder/skills/test-specification-alignment/references/alignment-verification-algorithm.md +493 -0
- package/plugins/qoder/skills/test-specification-alignment/references/phase2-constraint-enforcement.md +431 -0
- package/plugins/qoder/skills/test-specification-alignment/references/specification-format.md +348 -0
- package/plugins/qoder/skills/to-issues/SKILL.md +277 -0
- package/skills/admin-template-guidelines/SKILL.md +904 -0
- package/skills/delphi-review/SKILL.md +112 -77
- package/skills/improve-codebase-architecture/SKILL.md +156 -0
- package/skills/ralph-loop/SKILL.md +165 -34
- package/skills/sprint-flow/SKILL.md +448 -107
- package/skills/sprint-flow/references/components/skill-invocations.md +1 -1
- package/skills/sprint-flow/references/components/tool-descriptions.md +1 -1
- package/skills/sprint-flow/references/force-levels.md +203 -0
- package/skills/sprint-flow/references/phase-1-plan.md +4 -4
- package/skills/sprint-flow/references/phase-minus-0-5-auto-estimate.md +20 -1
- package/skills/sprint-flow/templates/auto-estimate-output-template.md +7 -5
- package/skills/sprint-flow/templates/sprint-progress-template.md +151 -0
- package/skills/test-driven-development/SKILL.md +71 -0
- package/skills/test-specification-alignment/SKILL.md +98 -24
- package/skills/to-issues/SKILL.md +277 -0
- package/plugins/qoder/AGENTS.md +0 -93
- package/plugins/qoder/README.md +0 -87
- package/plugins/qoder/widgets/quality-report.html +0 -163
- package/plugins/qoder/widgets/sprint-dashboard.html +0 -172
- package/skills/delphi-review/evals/evals.json +0 -82
- package/skills/delphi-review/references/qoder-multi-model.md +0 -191
- package/skills/ralph-loop/evals/evals.json +0 -311
- package/skills/ralph-loop/evolution-history.json +0 -59
- package/skills/ralph-loop/evolution-log.md +0 -16
- package/skills/sprint-flow/evals/evals.json +0 -130
- package/skills/sprint-flow/evolution-history.json +0 -39
- package/skills/sprint-flow/evolution-log.md +0 -23
- package/skills/sprint-flow/references/qoder-adaptation.md +0 -173
- package/skills/test-specification-alignment/evals/evals.json +0 -75
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
<style>
|
|
2
|
-
:root {
|
|
3
|
-
--qr-bg: var(--vscode-editor-background, #1e1e1e);
|
|
4
|
-
--qr-fg: var(--vscode-editor-foreground, #d4d4d4);
|
|
5
|
-
--qr-border: var(--vscode-panel-border, #333);
|
|
6
|
-
--qr-pass: var(--vscode-testing-iconPassed, #73c991);
|
|
7
|
-
--qr-fail: var(--vscode-testing-iconFailed, #f14c4c);
|
|
8
|
-
--qr-skip: var(--vscode-descriptionForeground, #888);
|
|
9
|
-
--qr-accent: var(--vscode-focusBorder, #007acc);
|
|
10
|
-
--qr-card-bg: var(--vscode-editor-widget-background, #252526);
|
|
11
|
-
}
|
|
12
|
-
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
13
|
-
body { font-family: var(--vscode-font-family, 'Segoe UI', sans-serif); color: var(--qr-fg); background: var(--qr-bg); padding: 16px; }
|
|
14
|
-
.qr-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
|
|
15
|
-
.qr-header h2 { font-size: 16px; font-weight: 600; }
|
|
16
|
-
.qr-verdict { padding: 4px 12px; border-radius: 4px; font-size: 13px; font-weight: 600; }
|
|
17
|
-
.qr-verdict.pass { background: color-mix(in srgb, var(--qr-pass) 20%, transparent); color: var(--qr-pass); border: 1px solid var(--qr-pass); }
|
|
18
|
-
.qr-verdict.fail { background: color-mix(in srgb, var(--qr-fail) 20%, transparent); color: var(--qr-fail); border: 1px solid var(--qr-fail); }
|
|
19
|
-
.qr-meta { font-size: 12px; color: var(--qr-skip); margin-bottom: 16px; display: flex; gap: 16px; }
|
|
20
|
-
.qr-score-bar { display: flex; align-items: center; gap: 8px; margin-bottom: 20px; }
|
|
21
|
-
.qr-score-bar .bar-track { flex: 1; height: 8px; background: var(--qr-border); border-radius: 4px; overflow: hidden; }
|
|
22
|
-
.qr-score-bar .bar-fill { height: 100%; border-radius: 4px; transition: width 0.4s ease; }
|
|
23
|
-
.qr-score-bar .bar-fill.pass { background: var(--qr-pass); }
|
|
24
|
-
.qr-score-bar .bar-fill.fail { background: var(--qr-fail); }
|
|
25
|
-
.qr-score-bar .score-label { font-size: 14px; font-weight: 600; min-width: 48px; text-align: right; }
|
|
26
|
-
.qr-gates { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; margin-bottom: 20px; }
|
|
27
|
-
.qr-gate-card { background: var(--qr-card-bg); border: 1px solid var(--qr-border); border-radius: 6px; padding: 12px; display: flex; align-items: flex-start; gap: 10px; }
|
|
28
|
-
.qr-gate-icon { width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 14px; flex-shrink: 0; }
|
|
29
|
-
.qr-gate-icon.pass { background: color-mix(in srgb, var(--qr-pass) 20%, transparent); color: var(--qr-pass); }
|
|
30
|
-
.qr-gate-icon.fail { background: color-mix(in srgb, var(--qr-fail) 20%, transparent); color: var(--qr-fail); }
|
|
31
|
-
.qr-gate-icon.skip { background: color-mix(in srgb, var(--qr-skip) 20%, transparent); color: var(--qr-skip); }
|
|
32
|
-
.qr-gate-info { flex: 1; min-width: 0; }
|
|
33
|
-
.qr-gate-name { font-size: 13px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
34
|
-
.qr-gate-detail { font-size: 11px; color: var(--qr-skip); margin-top: 2px; }
|
|
35
|
-
.qr-section { margin-bottom: 16px; }
|
|
36
|
-
.qr-section h3 { font-size: 14px; font-weight: 600; margin-bottom: 10px; padding-bottom: 6px; border-bottom: 1px solid var(--qr-border); }
|
|
37
|
-
.qr-delphi-row { display: flex; align-items: center; gap: 10px; padding: 6px 0; font-size: 13px; }
|
|
38
|
-
.qr-delphi-row .expert-badge { padding: 2px 8px; border-radius: 3px; font-size: 11px; font-weight: 600; background: var(--qr-card-bg); border: 1px solid var(--qr-border); }
|
|
39
|
-
.qr-delphi-row .verdict-tag { margin-left: auto; font-weight: 500; }
|
|
40
|
-
.qr-delphi-row .verdict-tag.approved { color: var(--qr-pass); }
|
|
41
|
-
.qr-delphi-row .verdict-tag.rejected { color: var(--qr-fail); }
|
|
42
|
-
.qr-metrics { display: flex; gap: 12px; flex-wrap: wrap; }
|
|
43
|
-
.qr-metric { background: var(--qr-card-bg); border: 1px solid var(--qr-border); border-radius: 6px; padding: 12px 16px; text-align: center; min-width: 120px; }
|
|
44
|
-
.qr-metric .value { font-size: 24px; font-weight: 700; }
|
|
45
|
-
.qr-metric .label { font-size: 11px; color: var(--qr-skip); margin-top: 4px; }
|
|
46
|
-
.qr-metric .value.pass { color: var(--qr-pass); }
|
|
47
|
-
.qr-metric .value.fail { color: var(--qr-fail); }
|
|
48
|
-
.qr-empty { text-align: center; padding: 32px; color: var(--qr-skip); font-size: 13px; }
|
|
49
|
-
</style>
|
|
50
|
-
|
|
51
|
-
<div id="qr-root"></div>
|
|
52
|
-
|
|
53
|
-
<script>
|
|
54
|
-
(function() {
|
|
55
|
-
const data = window.__WIDGET_DATA__ || {};
|
|
56
|
-
const root = document.getElementById('qr-root');
|
|
57
|
-
|
|
58
|
-
if (!data || (!data.overall && !data.gates)) {
|
|
59
|
-
root.innerHTML = '<div class="qr-empty">No quality report data available.<br>Run the quality gates pipeline to generate a report.</div>';
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const overall = data.overall || {};
|
|
64
|
-
const gates = data.gates || {};
|
|
65
|
-
const delphi = data.delphi || null;
|
|
66
|
-
const testAlign = data.testAlignment || null;
|
|
67
|
-
const isPass = overall.verdict === 'PASS';
|
|
68
|
-
|
|
69
|
-
let html = '';
|
|
70
|
-
|
|
71
|
-
// Header
|
|
72
|
-
html += '<div class="qr-header">';
|
|
73
|
-
html += '<h2>Quality Report' + (data.project ? ' — ' + esc(data.project) : '') + '</h2>';
|
|
74
|
-
html += '<span class="qr-verdict ' + (isPass ? 'pass' : 'fail') + '">' + esc(overall.verdict || 'N/A') + '</span>';
|
|
75
|
-
html += '</div>';
|
|
76
|
-
|
|
77
|
-
// Meta
|
|
78
|
-
if (data.generatedAt || data.commit) {
|
|
79
|
-
html += '<div class="qr-meta">';
|
|
80
|
-
if (data.generatedAt) html += '<span>Generated: ' + esc(formatDate(data.generatedAt)) + '</span>';
|
|
81
|
-
if (data.commit) html += '<span>Commit: ' + esc(data.commit.substring(0, 8)) + '</span>';
|
|
82
|
-
if (data.language) html += '<span>Language: ' + esc(data.language) + '</span>';
|
|
83
|
-
html += '</div>';
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Score bar
|
|
87
|
-
const passed = overall.gatesPassed || 0;
|
|
88
|
-
const total = overall.gatesTotal || 0;
|
|
89
|
-
const score = overall.score || 0;
|
|
90
|
-
const pct = total > 0 ? Math.round((passed / total) * 100) : 0;
|
|
91
|
-
html += '<div class="qr-score-bar">';
|
|
92
|
-
html += '<div class="bar-track"><div class="bar-fill ' + (isPass ? 'pass' : 'fail') + '" style="width:' + pct + '%"></div></div>';
|
|
93
|
-
html += '<span class="score-label">' + passed + '/' + total + '</span>';
|
|
94
|
-
html += '</div>';
|
|
95
|
-
|
|
96
|
-
// Gate cards
|
|
97
|
-
html += '<div class="qr-gates">';
|
|
98
|
-
const gateKeys = Object.keys(gates).sort();
|
|
99
|
-
for (const key of gateKeys) {
|
|
100
|
-
const g = gates[key];
|
|
101
|
-
const status = (g.status || 'SKIP').toUpperCase();
|
|
102
|
-
const icon = status === 'PASS' ? '✓' : status === 'FAIL' ? '✗' : '—';
|
|
103
|
-
const cls = status === 'PASS' ? 'pass' : status === 'FAIL' ? 'fail' : 'skip';
|
|
104
|
-
html += '<div class="qr-gate-card">';
|
|
105
|
-
html += '<div class="qr-gate-icon ' + cls + '">' + icon + '</div>';
|
|
106
|
-
html += '<div class="qr-gate-info">';
|
|
107
|
-
html += '<div class="qr-gate-name">' + esc(g.name || key) + '</div>';
|
|
108
|
-
let detail = '';
|
|
109
|
-
if (g.tool) detail += 'Tool: ' + esc(g.tool);
|
|
110
|
-
if (g.metric) detail += (detail ? ' · ' : '') + esc(g.metric);
|
|
111
|
-
if (g.threshold) detail += (detail ? ' · ' : '') + 'Threshold: ' + esc(g.threshold);
|
|
112
|
-
if (g.coverage) detail += (detail ? ' · ' : '') + 'Coverage: ' + esc(g.coverage);
|
|
113
|
-
if (g.warnings !== undefined) detail += (detail ? ' · ' : '') + 'Warnings: ' + g.warnings;
|
|
114
|
-
if (!detail) detail = status;
|
|
115
|
-
html += '<div class="qr-gate-detail">' + detail + '</div>';
|
|
116
|
-
html += '</div></div>';
|
|
117
|
-
}
|
|
118
|
-
html += '</div>';
|
|
119
|
-
|
|
120
|
-
// Delphi Review section
|
|
121
|
-
if (delphi) {
|
|
122
|
-
html += '<div class="qr-section"><h3>Delphi Review</h3>';
|
|
123
|
-
if (delphi.experts) {
|
|
124
|
-
for (const exp of delphi.experts) {
|
|
125
|
-
const vCls = (exp.verdict || '').toUpperCase() === 'APPROVED' ? 'approved' : 'rejected';
|
|
126
|
-
html += '<div class="qr-delphi-row">';
|
|
127
|
-
html += '<span class="expert-badge">' + esc(exp.id || '?') + '</span>';
|
|
128
|
-
html += '<span>' + esc(exp.role || '') + '</span>';
|
|
129
|
-
html += '<span class="verdict-tag ' + vCls + '">' + esc(exp.verdict || 'N/A') + '</span>';
|
|
130
|
-
html += '</div>';
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
if (delphi.consensus !== undefined) {
|
|
134
|
-
html += '<div class="qr-delphi-row"><span>Consensus</span><span class="verdict-tag ' + (delphi.consensus >= 0.95 ? 'approved' : 'rejected') + '">' + Math.round(delphi.consensus * 100) + '%</span></div>';
|
|
135
|
-
}
|
|
136
|
-
html += '</div>';
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Metrics section (test alignment + coverage)
|
|
140
|
-
const hasMetrics = testAlign || (overall.coverage_pct !== undefined);
|
|
141
|
-
if (hasMetrics) {
|
|
142
|
-
html += '<div class="qr-section"><h3>Metrics</h3><div class="qr-metrics">';
|
|
143
|
-
if (testAlign) {
|
|
144
|
-
const alignScore = testAlign.score || 0;
|
|
145
|
-
const alignCls = alignScore >= 80 ? 'pass' : 'fail';
|
|
146
|
-
html += '<div class="qr-metric"><div class="value ' + alignCls + '">' + alignScore + '%</div><div class="label">Test-Spec Alignment</div></div>';
|
|
147
|
-
}
|
|
148
|
-
if (overall.coverage_pct !== undefined) {
|
|
149
|
-
const covCls = overall.coverage_pct >= 80 ? 'pass' : 'fail';
|
|
150
|
-
html += '<div class="qr-metric"><div class="value ' + covCls + '">' + overall.coverage_pct + '%</div><div class="label">Coverage</div></div>';
|
|
151
|
-
}
|
|
152
|
-
if (overall.score !== undefined) {
|
|
153
|
-
html += '<div class="qr-metric"><div class="value">' + overall.score + '</div><div class="label">Overall Score</div></div>';
|
|
154
|
-
}
|
|
155
|
-
html += '</div></div>';
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
root.innerHTML = html;
|
|
159
|
-
|
|
160
|
-
function esc(s) { const d = document.createElement('div'); d.textContent = String(s); return d.innerHTML; }
|
|
161
|
-
function formatDate(iso) { try { return new Date(iso).toLocaleString(); } catch { return iso; } }
|
|
162
|
-
})();
|
|
163
|
-
</script>
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
<style>
|
|
2
|
-
:root {
|
|
3
|
-
--sd-bg: var(--vscode-editor-background, #1e1e1e);
|
|
4
|
-
--sd-fg: var(--vscode-editor-foreground, #d4d4d4);
|
|
5
|
-
--sd-border: var(--vscode-panel-border, #333);
|
|
6
|
-
--sd-pass: var(--vscode-testing-iconPassed, #73c991);
|
|
7
|
-
--sd-fail: var(--vscode-testing-iconFailed, #f14c4c);
|
|
8
|
-
--sd-skip: var(--vscode-descriptionForeground, #888);
|
|
9
|
-
--sd-accent: var(--vscode-focusBorder, #007acc);
|
|
10
|
-
--sd-card-bg: var(--vscode-editor-widget-background, #252526);
|
|
11
|
-
--sd-active: var(--vscode-charts-yellow, #e5c07b);
|
|
12
|
-
}
|
|
13
|
-
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
14
|
-
body { font-family: var(--vscode-font-family, 'Segoe UI', sans-serif); color: var(--sd-fg); background: var(--sd-bg); padding: 16px; }
|
|
15
|
-
.sd-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
|
|
16
|
-
.sd-header h2 { font-size: 16px; font-weight: 600; }
|
|
17
|
-
.sd-status-badge { padding: 4px 12px; border-radius: 4px; font-size: 12px; font-weight: 600; text-transform: uppercase; }
|
|
18
|
-
.sd-status-badge.running { background: color-mix(in srgb, var(--sd-accent) 20%, transparent); color: var(--sd-accent); border: 1px solid var(--sd-accent); }
|
|
19
|
-
.sd-status-badge.paused { background: color-mix(in srgb, var(--sd-active) 20%, transparent); color: var(--sd-active); border: 1px solid var(--sd-active); }
|
|
20
|
-
.sd-status-badge.completed, .sd-status-badge.merged { background: color-mix(in srgb, var(--sd-pass) 20%, transparent); color: var(--sd-pass); border: 1px solid var(--sd-pass); }
|
|
21
|
-
.sd-meta { font-size: 12px; color: var(--sd-skip); margin-bottom: 16px; }
|
|
22
|
-
.sd-phase-track { display: flex; align-items: center; gap: 4px; margin-bottom: 20px; overflow-x: auto; padding-bottom: 4px; }
|
|
23
|
-
.sd-phase { display: flex; flex-direction: column; align-items: center; min-width: 72px; }
|
|
24
|
-
.sd-phase-dot { width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; border: 2px solid var(--sd-border); color: var(--sd-skip); background: var(--sd-bg); }
|
|
25
|
-
.sd-phase-dot.done { background: color-mix(in srgb, var(--sd-pass) 20%, transparent); border-color: var(--sd-pass); color: var(--sd-pass); }
|
|
26
|
-
.sd-phase-dot.active { background: color-mix(in srgb, var(--sd-accent) 25%, transparent); border-color: var(--sd-accent); color: var(--sd-accent); animation: pulse 1.5s infinite; }
|
|
27
|
-
.sd-phase-dot.future { border-color: var(--sd-border); color: var(--sd-skip); }
|
|
28
|
-
.sd-phase-label { font-size: 10px; margin-top: 4px; color: var(--sd-skip); text-align: center; white-space: nowrap; }
|
|
29
|
-
.sd-phase-label.active { color: var(--sd-accent); font-weight: 600; }
|
|
30
|
-
.sd-phase-label.done { color: var(--sd-pass); }
|
|
31
|
-
.sd-phase-line { width: 16px; height: 2px; background: var(--sd-border); margin-bottom: 20px; }
|
|
32
|
-
.sd-phase-line.done { background: var(--sd-pass); }
|
|
33
|
-
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } }
|
|
34
|
-
.sd-section { margin-bottom: 16px; }
|
|
35
|
-
.sd-section h3 { font-size: 14px; font-weight: 600; margin-bottom: 10px; padding-bottom: 6px; border-bottom: 1px solid var(--sd-border); }
|
|
36
|
-
.sd-progress-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
|
|
37
|
-
.sd-progress-row .label { font-size: 13px; min-width: 100px; }
|
|
38
|
-
.sd-progress-row .bar-track { flex: 1; height: 10px; background: var(--sd-border); border-radius: 5px; overflow: hidden; }
|
|
39
|
-
.sd-progress-row .bar-fill { height: 100%; border-radius: 5px; background: var(--sd-accent); transition: width 0.4s ease; }
|
|
40
|
-
.sd-progress-row .count { font-size: 13px; font-weight: 600; min-width: 60px; text-align: right; }
|
|
41
|
-
.sd-outputs { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 8px; }
|
|
42
|
-
.sd-output-item { background: var(--sd-card-bg); border: 1px solid var(--sd-border); border-radius: 4px; padding: 8px 10px; font-size: 12px; }
|
|
43
|
-
.sd-output-item .key { color: var(--sd-skip); font-size: 11px; }
|
|
44
|
-
.sd-output-item .val { margin-top: 2px; font-weight: 500; word-break: break-all; }
|
|
45
|
-
.sd-metrics { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
|
|
46
|
-
.sd-metric-card { background: var(--sd-card-bg); border: 1px solid var(--sd-border); border-radius: 6px; padding: 10px 14px; text-align: center; min-width: 100px; }
|
|
47
|
-
.sd-metric-card .value { font-size: 22px; font-weight: 700; color: var(--sd-accent); }
|
|
48
|
-
.sd-metric-card .label { font-size: 11px; color: var(--sd-skip); margin-top: 2px; }
|
|
49
|
-
.sd-learnings { list-style: none; }
|
|
50
|
-
.sd-learnings li { padding: 6px 0; font-size: 12px; border-bottom: 1px solid var(--sd-border); }
|
|
51
|
-
.sd-learnings li:last-child { border-bottom: none; }
|
|
52
|
-
.sd-learnings .cat { display: inline-block; padding: 1px 6px; border-radius: 3px; font-size: 10px; font-weight: 600; background: var(--sd-card-bg); border: 1px solid var(--sd-border); margin-right: 6px; }
|
|
53
|
-
.sd-empty { text-align: center; padding: 32px; color: var(--sd-skip); font-size: 13px; }
|
|
54
|
-
</style>
|
|
55
|
-
|
|
56
|
-
<div id="sd-root"></div>
|
|
57
|
-
|
|
58
|
-
<script>
|
|
59
|
-
(function() {
|
|
60
|
-
const data = window.__WIDGET_DATA__ || {};
|
|
61
|
-
const root = document.getElementById('sd-root');
|
|
62
|
-
|
|
63
|
-
if (!data || (!data.phase && !data.id && !data.status)) {
|
|
64
|
-
root.innerHTML = '<div class="sd-empty">No sprint state data available.<br>Start a sprint with /sprint-flow to see the dashboard.</div>';
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const PHASES = [
|
|
69
|
-
{ num: -1, name: 'ISOLATE' },
|
|
70
|
-
{ num: 0, name: 'THINK' },
|
|
71
|
-
{ num: 1, name: 'PLAN' },
|
|
72
|
-
{ num: 2, name: 'BUILD' },
|
|
73
|
-
{ num: 3, name: 'REVIEW' },
|
|
74
|
-
{ num: 4, name: 'UAT' },
|
|
75
|
-
{ num: 5, name: 'FEEDBACK' },
|
|
76
|
-
{ num: 6, name: 'SHIP' },
|
|
77
|
-
{ num: 7, name: 'LAND' },
|
|
78
|
-
{ num: 8, name: 'CLEANUP' }
|
|
79
|
-
];
|
|
80
|
-
|
|
81
|
-
const currentPhase = data.phase !== undefined ? data.phase : -2;
|
|
82
|
-
const status = data.status || 'unknown';
|
|
83
|
-
const outputs = data.outputs || {};
|
|
84
|
-
const metrics = data.metrics || {};
|
|
85
|
-
const learnings = data.learnings || [];
|
|
86
|
-
|
|
87
|
-
let html = '';
|
|
88
|
-
|
|
89
|
-
// Header
|
|
90
|
-
html += '<div class="sd-header">';
|
|
91
|
-
html += '<h2>Sprint' + (data.id ? ' — ' + esc(data.id) : '') + '</h2>';
|
|
92
|
-
const statusCls = ['running', 'paused', 'completed', 'merged'].includes(status) ? status : 'running';
|
|
93
|
-
html += '<span class="sd-status-badge ' + statusCls + '">' + esc(status) + '</span>';
|
|
94
|
-
html += '</div>';
|
|
95
|
-
|
|
96
|
-
// Phase progress track
|
|
97
|
-
html += '<div class="sd-phase-track">';
|
|
98
|
-
for (let i = 0; i < PHASES.length; i++) {
|
|
99
|
-
const p = PHASES[i];
|
|
100
|
-
if (i > 0) {
|
|
101
|
-
const lineCls = p.num <= currentPhase ? 'done' : '';
|
|
102
|
-
html += '<div class="sd-phase-line ' + lineCls + '"></div>';
|
|
103
|
-
}
|
|
104
|
-
let dotCls = 'future';
|
|
105
|
-
if (p.num < currentPhase) dotCls = 'done';
|
|
106
|
-
else if (p.num === currentPhase) dotCls = 'active';
|
|
107
|
-
const lblCls = p.num < currentPhase ? 'done' : p.num === currentPhase ? 'active' : '';
|
|
108
|
-
const icon = p.num < currentPhase ? '✓' : p.num === currentPhase ? '▶' : String(p.num);
|
|
109
|
-
html += '<div class="sd-phase">';
|
|
110
|
-
html += '<div class="sd-phase-dot ' + dotCls + '">' + icon + '</div>';
|
|
111
|
-
html += '<div class="sd-phase-label ' + lblCls + '">' + esc(p.name) + '</div>';
|
|
112
|
-
html += '</div>';
|
|
113
|
-
}
|
|
114
|
-
html += '</div>';
|
|
115
|
-
|
|
116
|
-
// Metrics cards
|
|
117
|
-
if (metrics.tests_passed !== undefined || metrics.coverage_pct !== undefined || metrics.tests_failed !== undefined) {
|
|
118
|
-
html += '<div class="sd-metrics">';
|
|
119
|
-
if (metrics.tests_passed !== undefined) {
|
|
120
|
-
html += '<div class="sd-metric-card"><div class="value">' + metrics.tests_passed + '</div><div class="label">Tests Passed</div></div>';
|
|
121
|
-
}
|
|
122
|
-
if (metrics.tests_failed !== undefined) {
|
|
123
|
-
html += '<div class="sd-metric-card"><div class="value" style="color:' + (metrics.tests_failed > 0 ? 'var(--sd-fail)' : 'var(--sd-pass)') + '">' + metrics.tests_failed + '</div><div class="label">Tests Failed</div></div>';
|
|
124
|
-
}
|
|
125
|
-
if (metrics.coverage_pct !== undefined) {
|
|
126
|
-
html += '<div class="sd-metric-card"><div class="value" style="color:' + (metrics.coverage_pct >= 80 ? 'var(--sd-pass)' : 'var(--sd-fail)') + '">' + metrics.coverage_pct + '%</div><div class="label">Coverage</div></div>';
|
|
127
|
-
}
|
|
128
|
-
html += '</div>';
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// REQ progress
|
|
132
|
-
if (data.req_progress || data.reqs) {
|
|
133
|
-
const rp = data.req_progress || {};
|
|
134
|
-
const done = rp.done || 0;
|
|
135
|
-
const totalReqs = rp.total || (data.reqs ? data.reqs.length : 0);
|
|
136
|
-
const pct = totalReqs > 0 ? Math.round((done / totalReqs) * 100) : 0;
|
|
137
|
-
html += '<div class="sd-section"><h3>REQ Progress</h3>';
|
|
138
|
-
html += '<div class="sd-progress-row">';
|
|
139
|
-
html += '<span class="label">Completed</span>';
|
|
140
|
-
html += '<div class="bar-track"><div class="bar-fill" style="width:' + pct + '%"></div></div>';
|
|
141
|
-
html += '<span class="count">' + done + '/' + totalReqs + '</span>';
|
|
142
|
-
html += '</div></div>';
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Phase outputs
|
|
146
|
-
const outputKeys = Object.keys(outputs);
|
|
147
|
-
if (outputKeys.length > 0) {
|
|
148
|
-
html += '<div class="sd-section"><h3>Phase Outputs</h3>';
|
|
149
|
-
html += '<div class="sd-outputs">';
|
|
150
|
-
for (const key of outputKeys) {
|
|
151
|
-
html += '<div class="sd-output-item"><div class="key">' + esc(key) + '</div><div class="val">' + esc(outputs[key]) + '</div></div>';
|
|
152
|
-
}
|
|
153
|
-
html += '</div></div>';
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Learnings
|
|
157
|
-
if (learnings.length > 0) {
|
|
158
|
-
html += '<div class="sd-section"><h3>Recent Learnings</h3>';
|
|
159
|
-
html += '<ul class="sd-learnings">';
|
|
160
|
-
const recent = learnings.slice(-5).reverse();
|
|
161
|
-
for (const l of recent) {
|
|
162
|
-
const cat = l.category || 'general';
|
|
163
|
-
html += '<li><span class="cat">' + esc(cat) + '</span>' + esc(l.summary || l.text || JSON.stringify(l)) + '</li>';
|
|
164
|
-
}
|
|
165
|
-
html += '</ul></div>';
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
root.innerHTML = html;
|
|
169
|
-
|
|
170
|
-
function esc(s) { const d = document.createElement('div'); d.textContent = String(s); return d.innerHTML; }
|
|
171
|
-
})();
|
|
172
|
-
</script>
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"skill_name": "delphi-review",
|
|
3
|
-
"skill_path": "skills/delphi-review/SKILL.md",
|
|
4
|
-
"evals": [
|
|
5
|
-
{
|
|
6
|
-
"id": 1,
|
|
7
|
-
"name": "design-mode-full-review",
|
|
8
|
-
"category": "normal",
|
|
9
|
-
"prompt": "我需要评审一份设计文档:我们要给XP-Gate项目添加一个自动生成CHANGELOG的功能。功能包括:1) 从git log提取commit信息 2) 按照conventional commits分类 3) 生成markdown格式的changelog 4) 支持自定义模板。请用delphi-review评审这个设计。",
|
|
10
|
-
"expected_output": "执行完整的Delphi评审流程:Phase 0验证→Round 1匿名独立评审(至少2位Expert)→Round 2交换意见→共识检查(>=95%)→Terminal State Checklist→如果APPROVED则生成specification.yaml。绝不能只做Round 1就停止。",
|
|
11
|
-
"files": [],
|
|
12
|
-
"assertions": [
|
|
13
|
-
{"name": "round-1-executed", "type": "contains", "value": "Round 1"},
|
|
14
|
-
{"name": "round-2-executed", "type": "contains", "value": "Round 2"},
|
|
15
|
-
{"name": "consensus-check", "type": "contains", "value": "95%"},
|
|
16
|
-
{"name": "terminal-state-checklist", "type": "contains", "value": "Terminal State"},
|
|
17
|
-
{"name": "expert-a-present", "type": "contains", "value": "Expert A"},
|
|
18
|
-
{"name": "expert-b-present", "type": "contains", "value": "Expert B"},
|
|
19
|
-
{"name": "anonymity-mentioned", "type": "contains", "value": "匿名"},
|
|
20
|
-
{"name": "verdict-present", "type": "regex", "value": "(APPROVED|REQUEST_CHANGES|REJECTED)"}
|
|
21
|
-
]
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
"id": 2,
|
|
25
|
-
"name": "design-mode-flawed-document",
|
|
26
|
-
"category": "boundary",
|
|
27
|
-
"prompt": "请评审以下架构决策:我们打算用单个SQLite文件存储所有用户数据、日志、审计记录和缓存。这样部署简单,只需要一个文件。请用delphi-review评审。",
|
|
28
|
-
"expected_output": "Expert应该识别出这个设计的严重问题(单文件SQLite不适合多用途、缺乏扩展性、并发问题等),给出REQUEST_CHANGES而非盲目APPROVED。仍需执行完整多轮流程。",
|
|
29
|
-
"files": [],
|
|
30
|
-
"assertions": [
|
|
31
|
-
{"name": "round-1-executed", "type": "contains", "value": "Round 1"},
|
|
32
|
-
{"name": "critical-issues-found", "type": "contains", "value": "Critical"},
|
|
33
|
-
{"name": "verdict-not-blind-approved", "type": "contains", "value": "REQUEST_CHANGES"}
|
|
34
|
-
]
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
"id": 3,
|
|
38
|
-
"name": "code-walkthrough-mode",
|
|
39
|
-
"category": "normal",
|
|
40
|
-
"prompt": "我修改了几个文件准备push,需要做代码走查。变更包括:1) 新增了boy-scout.ts的calculateDelta函数 2) 修改了baseline.ts的loadBaseline函数 3) 添加了3个新的clean-code规则。请用code-walkthrough模式评审。",
|
|
41
|
-
"expected_output": "执行code-walkthrough模式:运行Principles Checker→Expert A架构评审(含principles_findings)→Expert B实现评审(含principles_findings)→共识检查→写入.code-walkthrough-result.json文件。",
|
|
42
|
-
"files": [],
|
|
43
|
-
"assertions": [
|
|
44
|
-
{"name": "code-walkthrough-mode", "type": "contains", "value": "code-walkthrough"},
|
|
45
|
-
{"name": "principles-findings", "type": "contains", "value": "Principles Findings"},
|
|
46
|
-
{"name": "expert-a-review", "type": "contains", "value": "Expert A"},
|
|
47
|
-
{"name": "expert-b-review", "type": "contains", "value": "Expert B"},
|
|
48
|
-
{"name": "result-file-generated", "type": "contains", "value": ".code-walkthrough-result.json"},
|
|
49
|
-
{"name": "consensus-check", "type": "contains", "value": "共识"}
|
|
50
|
-
]
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"id": 4,
|
|
54
|
-
"name": "zero-tolerance-enforcement",
|
|
55
|
-
"category": "boundary",
|
|
56
|
-
"prompt": "评审时发现了一个Critical Issue,但我觉得这个问题不大,可以忽略。评审还需要继续吗?",
|
|
57
|
-
"expected_output": "必须坚持零容忍原则:Critical Issues不可忽略,必须修复后重新评审。不能因为用户认为问题不大就跳过。应明确告知零容忍原则并拒绝跳过。",
|
|
58
|
-
"files": [],
|
|
59
|
-
"assertions": [
|
|
60
|
-
{"name": "zero-tolerance-enforced", "type": "contains", "value": "零容忍"},
|
|
61
|
-
{"name": "critical-not-skippable", "type": "not_contains", "value": "可以忽略"},
|
|
62
|
-
{"name": "requires-fix", "type": "contains", "value": "修复"}
|
|
63
|
-
]
|
|
64
|
-
}
|
|
65
|
-
],
|
|
66
|
-
"trigger_evals": {
|
|
67
|
-
"should_trigger": [
|
|
68
|
-
"我需要多个专家来评审这个架构设计",
|
|
69
|
-
"评审这份需求文档,确保没有遗漏",
|
|
70
|
-
"设计评审:我们的微服务拆分方案",
|
|
71
|
-
"代码走查,准备push了",
|
|
72
|
-
"delphi review this design doc"
|
|
73
|
-
],
|
|
74
|
-
"should_not_trigger": [
|
|
75
|
-
"帮我写一个单元测试",
|
|
76
|
-
"这段代码有bug,帮我修一下",
|
|
77
|
-
"创建一个新的React组件",
|
|
78
|
-
"部署到生产环境",
|
|
79
|
-
"解释一下这个函数的作用"
|
|
80
|
-
]
|
|
81
|
-
}
|
|
82
|
-
}
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
# Qoder Multi-Model Review Guide for Delphi Review
|
|
2
|
-
|
|
3
|
-
**Version:** v0.6.0
|
|
4
|
-
**Platform:** Qoder IDE
|
|
5
|
-
**Status:** Active
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 1. Overview
|
|
10
|
-
|
|
11
|
-
Delphi Review requires multi-expert anonymous consensus review using at least 2 different LLM providers. In Qoder, this is achieved through Agent subagent dispatch, leveraging Qoder's built-in multi-model capability.
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## 2. Expert Configuration
|
|
16
|
-
|
|
17
|
-
### 2.1 Configuration File
|
|
18
|
-
|
|
19
|
-
Create `.qoder/delphi-config.json` in project root:
|
|
20
|
-
|
|
21
|
-
```json
|
|
22
|
-
{
|
|
23
|
-
"experts": {
|
|
24
|
-
"A": {
|
|
25
|
-
"role": "architecture",
|
|
26
|
-
"focus": "System design, scalability, maintainability, SOLID principles",
|
|
27
|
-
"model_hint": "deepseek-v4-pro"
|
|
28
|
-
},
|
|
29
|
-
"B": {
|
|
30
|
-
"role": "implementation",
|
|
31
|
-
"focus": "Code quality, testing strategy, error handling, performance",
|
|
32
|
-
"model_hint": "kimi-k2.6"
|
|
33
|
-
},
|
|
34
|
-
"C": {
|
|
35
|
-
"role": "feasibility",
|
|
36
|
-
"focus": "Practical constraints, timeline, team capability, risk assessment",
|
|
37
|
-
"model_hint": "qwen3.6-plus"
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
"consensus_threshold": 0.95,
|
|
41
|
-
"max_rounds": 5,
|
|
42
|
-
"providers_required": 2
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### 2.2 Model Selection Rules
|
|
47
|
-
|
|
48
|
-
- Experts MUST come from **at least 2 different providers**
|
|
49
|
-
- **Forbidden**: Anthropic, OpenAI, Google (foreign models)
|
|
50
|
-
- **Recommended domestic providers**: DeepSeek, Qwen (Alibaba), Kimi (Moonshot), GLM (Zhipu), MiniMax
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## 3. Execution Flow in Qoder
|
|
55
|
-
|
|
56
|
-
### 3.1 Round 1: Independent Anonymous Review
|
|
57
|
-
|
|
58
|
-
For each expert, dispatch an Agent subagent with the expert's specific prompt:
|
|
59
|
-
|
|
60
|
-
**Expert A (Architecture) — plan-agent**:
|
|
61
|
-
```
|
|
62
|
-
Agent(subagent_type="plan-agent", prompt="""
|
|
63
|
-
You are Expert A in a Delphi consensus review. Your role: Architecture Reviewer.
|
|
64
|
-
Focus: System design, scalability, maintainability, SOLID principles.
|
|
65
|
-
|
|
66
|
-
Review the following design/code and provide your assessment:
|
|
67
|
-
[REVIEW MATERIAL]
|
|
68
|
-
|
|
69
|
-
Output format:
|
|
70
|
-
{
|
|
71
|
-
"expert_id": "A",
|
|
72
|
-
"verdict": "APPROVED|REQUEST_CHANGES|REJECTED",
|
|
73
|
-
"issues": [...],
|
|
74
|
-
"strengths": [...],
|
|
75
|
-
"suggestions": [...]
|
|
76
|
-
}
|
|
77
|
-
""")
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
**Expert B (Implementation) — CodeReview subagent**:
|
|
81
|
-
```
|
|
82
|
-
Agent(subagent_type="CodeReview", prompt="""
|
|
83
|
-
You are Expert B in a Delphi consensus review. Your role: Implementation Reviewer.
|
|
84
|
-
Focus: Code quality, testing strategy, error handling, performance.
|
|
85
|
-
|
|
86
|
-
Review the following code changes:
|
|
87
|
-
[CHANGED FILES]
|
|
88
|
-
""")
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
**Expert C (Feasibility) — plan-agent**:
|
|
92
|
-
```
|
|
93
|
-
Agent(subagent_type="plan-agent", prompt="""
|
|
94
|
-
You are Expert C in a Delphi consensus review. Your role: Feasibility Arbiter.
|
|
95
|
-
Focus: Practical constraints, timeline, team capability, risk assessment.
|
|
96
|
-
|
|
97
|
-
Review the following design/code and provide your assessment:
|
|
98
|
-
[REVIEW MATERIAL]
|
|
99
|
-
|
|
100
|
-
Output format:
|
|
101
|
-
{
|
|
102
|
-
"expert_id": "C",
|
|
103
|
-
"verdict": "APPROVED|REQUEST_CHANGES|REJECTED",
|
|
104
|
-
...
|
|
105
|
-
}
|
|
106
|
-
""")
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### 3.2 Consensus Aggregation
|
|
110
|
-
|
|
111
|
-
After all experts respond:
|
|
112
|
-
1. Parse each expert's JSON output
|
|
113
|
-
2. Compare verdicts:
|
|
114
|
-
- All APPROVED → **Consensus: APPROVED**
|
|
115
|
-
- All REQUEST_CHANGES → Merge issues, present to user
|
|
116
|
-
- Mixed verdicts → **No consensus**, proceed to Round 2
|
|
117
|
-
3. Calculate issue consensus ratio: issues agreed by ≥95% of experts → resolved
|
|
118
|
-
|
|
119
|
-
### 3.3 Round 2+: Controlled Feedback
|
|
120
|
-
|
|
121
|
-
In subsequent rounds, each expert receives other experts' anonymized opinions:
|
|
122
|
-
```
|
|
123
|
-
Agent(subagent_type="plan-agent", prompt="""
|
|
124
|
-
You are Expert A. In Round 1, your verdict was: REQUEST_CHANGES.
|
|
125
|
-
Other experts' anonymized feedback:
|
|
126
|
-
- Expert X: APPROVED, noted [strengths]
|
|
127
|
-
- Expert Y: REQUEST_CHANGES, noted [issues]
|
|
128
|
-
|
|
129
|
-
Review your assessment in light of others' feedback. Maintain your independence.
|
|
130
|
-
[REVIEW MATERIAL]
|
|
131
|
-
""")
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### 3.4 Terminal States
|
|
135
|
-
|
|
136
|
-
| Condition | Action |
|
|
137
|
-
|-----------|--------|
|
|
138
|
-
| All experts APPROVED + ≥95% issue consensus | **APPROVED** — write `.sprint-state/delphi-reviewed.json` |
|
|
139
|
-
| Max rounds reached without consensus | **REJECTED** — present disagreement summary |
|
|
140
|
-
| Any expert REJECTED with critical issues | **REQUEST_CHANGES** — user must fix and re-review |
|
|
141
|
-
|
|
142
|
-
---
|
|
143
|
-
|
|
144
|
-
## 4. Degraded Mode
|
|
145
|
-
|
|
146
|
-
When multi-model subagent dispatch is unavailable:
|
|
147
|
-
|
|
148
|
-
### 4.1 Single-Model Multi-Role Mode
|
|
149
|
-
|
|
150
|
-
The orchestrator plays all expert roles sequentially with different prompts:
|
|
151
|
-
|
|
152
|
-
```
|
|
153
|
-
⚠️ [DEGRADED] 单模型多角色模式
|
|
154
|
-
失去跨 provider 匿名性保护,但保留多视角评审结构。
|
|
155
|
-
建议:在条件允许时恢复多模型模式重新评审。
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### 4.2 Degraded Output Format
|
|
159
|
-
|
|
160
|
-
```json
|
|
161
|
-
{
|
|
162
|
-
"mode": "design",
|
|
163
|
-
"verdict": "APPROVED",
|
|
164
|
-
"degraded": true,
|
|
165
|
-
"degradation_reason": "Multi-model subagent unavailable",
|
|
166
|
-
"experts": ["A", "B", "C"],
|
|
167
|
-
"model": "single"
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
---
|
|
172
|
-
|
|
173
|
-
## 5. Integration with Sprint Flow
|
|
174
|
-
|
|
175
|
-
### 5.1 Phase 1 (Design Review)
|
|
176
|
-
|
|
177
|
-
- Default: 2 experts (A + B)
|
|
178
|
-
- Complex designs: 3 experts (A + B + C)
|
|
179
|
-
- Output: `.sprint-state/delphi-reviewed.json` + `specification.yaml`
|
|
180
|
-
|
|
181
|
-
### 5.2 Phase 3 (Code Walkthrough)
|
|
182
|
-
|
|
183
|
-
- Default: 2 experts (A + B)
|
|
184
|
-
- Use `CodeReview` subagent for Expert B
|
|
185
|
-
- Output: `.code-walkthrough-result.json`
|
|
186
|
-
|
|
187
|
-
### 5.3 HARD-GATE Enforcement
|
|
188
|
-
|
|
189
|
-
- Phase 2 BUILD cannot start until delphi-review verdict is APPROVED
|
|
190
|
-
- In Qoder: Pre-Edit Gate checks `.sprint-state/delphi-reviewed.json`
|
|
191
|
-
- See sprint-flow SKILL.md for Pre-Edit Gate details
|