@boyingliu01/xp-gate 0.12.1 → 0.12.3

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.
Files changed (31) hide show
  1. package/bin/xp-gate.js +22 -0
  2. package/gate-3.sh +68 -0
  3. package/gate-4.sh +80 -0
  4. package/gate-7.sh +45 -0
  5. package/gate-8.sh +56 -0
  6. package/gate-9.sh +130 -0
  7. package/lib/__tests__/update-hooks.test.js +573 -0
  8. package/lib/update-hooks.js +288 -0
  9. package/mock-policy/AGENTS.md +3 -3
  10. package/mutation/AGENTS.md +3 -3
  11. package/package.json +7 -2
  12. package/plugins/claude-code/.claude-plugin/plugin.json +1 -1
  13. package/plugins/claude-code/skills/delphi-review/AGENTS.md +6 -6
  14. package/plugins/claude-code/skills/delphi-review/SKILL.md +34 -12
  15. package/plugins/claude-code/skills/sprint-flow/AGENTS.md +3 -3
  16. package/plugins/claude-code/skills/test-specification-alignment/AGENTS.md +3 -3
  17. package/plugins/opencode/package.json +1 -1
  18. package/plugins/opencode/skills/delphi-review/AGENTS.md +6 -6
  19. package/plugins/opencode/skills/delphi-review/SKILL.md +34 -12
  20. package/plugins/opencode/skills/sprint-flow/AGENTS.md +3 -3
  21. package/plugins/opencode/skills/test-specification-alignment/AGENTS.md +3 -3
  22. package/plugins/qoder/plugin.json +1 -1
  23. package/plugins/qoder/skills/delphi-review/AGENTS.md +6 -6
  24. package/plugins/qoder/skills/delphi-review/SKILL.md +198 -264
  25. package/plugins/qoder/skills/sprint-flow/AGENTS.md +3 -3
  26. package/plugins/qoder/skills/test-specification-alignment/AGENTS.md +3 -3
  27. package/principles/AGENTS.md +3 -3
  28. package/skills/delphi-review/AGENTS.md +6 -6
  29. package/skills/delphi-review/SKILL.md +34 -12
  30. package/skills/sprint-flow/AGENTS.md +3 -3
  31. package/skills/test-specification-alignment/AGENTS.md +3 -3
@@ -0,0 +1,288 @@
1
+ /**
2
+ * @test REQ-265 update-hooks command
3
+ * @intent Sync latest hook versions from xp-gate package to project or global directory
4
+ * @covers AC-265-01, AC-265-02, AC-265-03, AC-265-04
5
+ */
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+ const { GLOBAL_HOOKS_DIR, GLOBAL_ADAPTERS_DIR } = require('./shared-paths.js');
9
+
10
+ /**
11
+ * Get the xp-gate package root directory (src/npm-package/).
12
+ * @returns {string}
13
+ */
14
+ function getPackageRoot() {
15
+ return path.resolve(__dirname, '..');
16
+ }
17
+
18
+ /**
19
+ * Get the project's git hooks directory.
20
+ * @throws {Error} If not in a git repository
21
+ * @returns {string}
22
+ */
23
+ function getProjectHooksDir() {
24
+ const gitDir = path.join(process.cwd(), '.git');
25
+ if (!fs.existsSync(gitDir)) {
26
+ throw new Error('Not a Git repository: .git directory not found');
27
+ }
28
+ return path.join(gitDir, 'hooks');
29
+ }
30
+
31
+ /**
32
+ * Detect locally modified hook files by comparing source and destination contents.
33
+ * @param {string} srcDir - Package root directory
34
+ * @param {string} hooksDestDir - Destination hooks directory
35
+ * @param {string} adaptersDestDir - Destination adapters directory
36
+ * @returns {string[]} List of locally modified file names
37
+ */
38
+ function detectLocalModifications(srcDir, hooksDestDir, adaptersDestDir) {
39
+ const modified = [];
40
+
41
+ // Check hook files: pre-commit, pre-push
42
+ ['pre-commit', 'pre-push'].forEach(hook => {
43
+ const srcPath = path.join(srcDir, 'hooks', hook);
44
+ const destPath = path.join(hooksDestDir, hook);
45
+ if (fs.existsSync(destPath) && fs.existsSync(srcPath)) {
46
+ const srcContent = fs.readFileSync(srcPath, 'utf8');
47
+ const destContent = fs.readFileSync(destPath, 'utf8');
48
+ if (srcContent !== destContent) {
49
+ modified.push(hook);
50
+ }
51
+ }
52
+ });
53
+
54
+ // Check adapter-common.sh
55
+ const adapterCommonSrc = path.join(srcDir, 'adapter-common.sh');
56
+ const adapterCommonDest = path.join(adaptersDestDir, 'adapter-common.sh');
57
+ if (fs.existsSync(adapterCommonDest) && fs.existsSync(adapterCommonSrc)) {
58
+ const srcContent = fs.readFileSync(adapterCommonSrc, 'utf8');
59
+ const destContent = fs.readFileSync(adapterCommonDest, 'utf8');
60
+ if (srcContent !== destContent) {
61
+ modified.push('adapter-common.sh');
62
+ }
63
+ }
64
+
65
+ // Check adapters/*.sh
66
+ const srcAdaptersDir = path.join(srcDir, 'adapters');
67
+ if (fs.existsSync(srcAdaptersDir)) {
68
+ fs.readdirSync(srcAdaptersDir).forEach(f => {
69
+ if (f.endsWith('.sh')) {
70
+ const srcPath = path.join(srcAdaptersDir, f);
71
+ const destPath = path.join(adaptersDestDir, 'adapters', f);
72
+ if (fs.existsSync(destPath) && fs.existsSync(srcPath)) {
73
+ const srcContent = fs.readFileSync(srcPath, 'utf8');
74
+ const destContent = fs.readFileSync(destPath, 'utf8');
75
+ if (srcContent !== destContent) {
76
+ modified.push(`adapters/${f}`);
77
+ }
78
+ }
79
+ }
80
+ });
81
+ }
82
+
83
+ // Check gate-*.sh scripts
84
+ if (fs.existsSync(srcDir)) {
85
+ fs.readdirSync(srcDir).forEach(f => {
86
+ if (f.startsWith('gate-') && f.endsWith('.sh')) {
87
+ const srcPath = path.join(srcDir, f);
88
+ const destPath = path.join(adaptersDestDir, f);
89
+ if (fs.existsSync(destPath) && fs.existsSync(srcPath)) {
90
+ const srcContent = fs.readFileSync(srcPath, 'utf8');
91
+ const destContent = fs.readFileSync(destPath, 'utf8');
92
+ if (srcContent !== destContent) {
93
+ modified.push(f);
94
+ }
95
+ }
96
+ }
97
+ });
98
+ }
99
+
100
+ return modified;
101
+ }
102
+
103
+ /**
104
+ * Atomically copy a file: write to .tmp then rename. Create .bak backup if enabled.
105
+ * @param {string} src - Source file path
106
+ * @param {string} dest - Destination file path
107
+ * @param {boolean} dryRun - If true, only log what would happen
108
+ * @param {boolean} noBackup - If true, skip backup creation
109
+ * @param {string} label - Human-readable label for logging
110
+ * @returns {boolean} Whether the file was copied
111
+ */
112
+ function atomicCopyFile(src, dest, dryRun, noBackup, label) {
113
+ if (!fs.existsSync(src)) {
114
+ console.warn(` ⚠ ${label} not found, skipping`);
115
+ return false;
116
+ }
117
+
118
+ if (dryRun) {
119
+ console.log(` would update: ${label}`);
120
+ return true;
121
+ }
122
+
123
+ // Ensure destination directory exists
124
+ const destDir = path.dirname(dest);
125
+ fs.mkdirSync(destDir, { recursive: true });
126
+
127
+ // Create backup if enabled
128
+ if (!noBackup && fs.existsSync(dest)) {
129
+ fs.copyFileSync(dest, `${dest}.bak`);
130
+ }
131
+
132
+ // Atomic write: temp file + rename
133
+ const tmpDest = `${dest}.tmp`;
134
+ fs.copyFileSync(src, tmpDest);
135
+ fs.renameSync(tmpDest, dest);
136
+ fs.chmodSync(dest, 0o755);
137
+ console.log(` ✓ ${label}`);
138
+ return true;
139
+ }
140
+
141
+ /**
142
+ * Copy hook files (pre-commit, pre-push) from package to destination.
143
+ * @param {string} srcDir - Package root directory
144
+ * @param {string} destDir - Destination hooks directory
145
+ * @param {boolean} dryRun
146
+ * @param {boolean} noBackup
147
+ */
148
+ function copyHooks(srcDir, destDir, dryRun, noBackup) {
149
+ const hooksSrcDir = path.join(srcDir, 'hooks');
150
+ ['pre-commit', 'pre-push'].forEach(hook => {
151
+ const src = path.join(hooksSrcDir, hook);
152
+ const dest = path.join(destDir, hook);
153
+ atomicCopyFile(src, dest, dryRun, noBackup, hook);
154
+ });
155
+ }
156
+
157
+ /**
158
+ * Copy adapter files (adapter-common.sh + adapters/*.sh) from package to destination.
159
+ * @param {string} srcDir - Package root directory
160
+ * @param {string} destDir - Destination directory (githooks/ for local, adapters/ for global)
161
+ * @param {boolean} dryRun
162
+ * @param {boolean} noBackup
163
+ */
164
+ function copyAdapters(srcDir, destDir, dryRun, noBackup) {
165
+ // Copy adapter-common.sh from package root
166
+ const adapterCommonSrc = path.join(srcDir, 'adapter-common.sh');
167
+ const adapterCommonDest = path.join(destDir, 'adapter-common.sh');
168
+ atomicCopyFile(adapterCommonSrc, adapterCommonDest, dryRun, noBackup, 'adapter-common.sh');
169
+
170
+ // Copy adapters/*.sh
171
+ const srcAdaptersDir = path.join(srcDir, 'adapters');
172
+ if (fs.existsSync(srcAdaptersDir)) {
173
+ fs.readdirSync(srcAdaptersDir).forEach(f => {
174
+ if (f.endsWith('.sh')) {
175
+ const src = path.join(srcAdaptersDir, f);
176
+ const dest = path.join(destDir, 'adapters', f);
177
+ atomicCopyFile(src, dest, dryRun, noBackup, `adapters/${f}`);
178
+ }
179
+ });
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Copy gate-*.sh scripts from package root to destination.
185
+ * @param {string} srcDir - Package root directory
186
+ * @param {string} destDir - Destination directory
187
+ * @param {boolean} dryRun
188
+ * @param {boolean} noBackup
189
+ */
190
+ function copyGateScripts(srcDir, destDir, dryRun, noBackup) {
191
+ if (!fs.existsSync(srcDir)) return;
192
+ fs.readdirSync(srcDir).forEach(f => {
193
+ if (f.startsWith('gate-') && f.endsWith('.sh')) {
194
+ const src = path.join(srcDir, f);
195
+ const dest = path.join(destDir, f);
196
+ atomicCopyFile(src, dest, dryRun, noBackup, f);
197
+ }
198
+ });
199
+ }
200
+
201
+ /**
202
+ * Main entry point: sync latest hook versions from xp-gate package to project or global directory.
203
+ *
204
+ * @param {Object} options
205
+ * @param {boolean} [options.global=false] - Update global hooks (~/.config/xp-gate/)
206
+ * @param {boolean} [options.force=false] - Skip local modification detection
207
+ * @param {boolean} [options.dryRun=false] - Show what would be updated without writing
208
+ * @param {boolean} [options.noBackup=false] - Skip creating .bak backup files
209
+ * @param {string} [options.scope='all'] - Selectively update: 'hooks', 'adapters', or 'all'
210
+ * @returns {number} Exit code (0 = success, 1 = error/warn)
211
+ */
212
+ function updateHooks(options = {}) {
213
+ const { global = false, force = false, dryRun = false, noBackup = false, scope = 'all' } = options;
214
+
215
+ // Use module.exports.getPackageRoot() so tests can mock via mod.getPackageRoot
216
+ const srcDir = (module.exports && module.exports.getPackageRoot)
217
+ ? module.exports.getPackageRoot()
218
+ : getPackageRoot();
219
+
220
+ // Determine destination directories based on mode
221
+ let hooksDestDir;
222
+ let adaptersDestDir;
223
+
224
+ if (global) {
225
+ hooksDestDir = GLOBAL_HOOKS_DIR;
226
+ adaptersDestDir = GLOBAL_ADAPTERS_DIR;
227
+ } else {
228
+ hooksDestDir = getProjectHooksDir();
229
+ // For local mode, adapters go to project's githooks/ directory
230
+ adaptersDestDir = path.join(process.cwd(), 'githooks');
231
+ }
232
+
233
+ // Ensure destination directories exist
234
+ fs.mkdirSync(hooksDestDir, { recursive: true });
235
+ fs.mkdirSync(adaptersDestDir, { recursive: true });
236
+ fs.mkdirSync(path.join(adaptersDestDir, 'adapters'), { recursive: true });
237
+
238
+ console.log(`XP-Gate Update Hooks`);
239
+ console.log(`====================`);
240
+ console.log(`Mode: ${global ? 'Global' : 'Local'}`);
241
+ console.log(`Source: ${srcDir}`);
242
+ console.log(`Hooks destination: ${hooksDestDir}`);
243
+ console.log(`Adapters destination: ${adaptersDestDir}`);
244
+ console.log(`Scope: ${scope}`);
245
+ if (dryRun) console.log(`Dry run: yes (no files will be modified)`);
246
+ console.log('');
247
+
248
+ // Detect local modifications and warn (unless force or dryRun)
249
+ if (!force && !dryRun) {
250
+ const localMods = detectLocalModifications(srcDir, hooksDestDir, adaptersDestDir);
251
+ if (localMods.length > 0) {
252
+ console.warn(`[WARN] Detected ${localMods.length} locally modified file(s):`);
253
+ localMods.forEach(f => console.warn(` - ${f}`));
254
+ console.warn('Use --force to overwrite, or manually backup first.');
255
+ return 1;
256
+ }
257
+ }
258
+
259
+ // Copy files based on scope
260
+ if (scope === 'all' || scope === 'hooks') {
261
+ console.log('Updating hooks...');
262
+ copyHooks(srcDir, hooksDestDir, dryRun, noBackup);
263
+ }
264
+ if (scope === 'all' || scope === 'adapters') {
265
+ console.log('Updating adapters...');
266
+ copyAdapters(srcDir, adaptersDestDir, dryRun, noBackup);
267
+ }
268
+ if (scope === 'all') {
269
+ console.log('Updating gate scripts...');
270
+ copyGateScripts(srcDir, adaptersDestDir, dryRun, noBackup);
271
+ }
272
+
273
+ if (!dryRun) {
274
+ console.log('\nUpdate complete!');
275
+ }
276
+ return 0;
277
+ }
278
+
279
+ module.exports = {
280
+ updateHooks,
281
+ detectLocalModifications,
282
+ copyHooks,
283
+ copyAdapters,
284
+ copyGateScripts,
285
+ atomicCopyFile,
286
+ getPackageRoot,
287
+ getProjectHooksDir,
288
+ };
@@ -1,9 +1,9 @@
1
1
  # SRC/MOCK-POLICY KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-07-01
4
- **Commit:** 99e2300
3
+ **Generated:** 2026-07-03
4
+ **Commit:** 83b39b6
5
5
  **Branch:** main
6
- **Version:** 0.12.1.0
6
+ **Version:** 0.12.3.0
7
7
 
8
8
  ## OVERVIEW
9
9
  Mock layering policy enforcement — Gate M3 of pre-push hook. Ensures integration tests use real implementations for internal dependencies, mock external dependencies, and annotate pending mocks with removal plans. Combines project scope scanning, mock decision engine, and per-file validation into a single pipeline.
@@ -1,9 +1,9 @@
1
1
  # SRC/MUTATION KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-07-01
4
- **Commit:** 99e2300
3
+ **Generated:** 2026-07-03
4
+ **Commit:** 83b39b6
5
5
  **Branch:** main
6
- **Version:** 0.12.1.0
6
+ **Version:** 0.12.3.0
7
7
 
8
8
  ## OVERVIEW
9
9
  **Gate M** (incremental mutation testing) + **Gate M2** helpers (test-layer detection used by `src/mock-policy/`). Pre-push quality gate. TypeScript-only; uses Stryker.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boyingliu01/xp-gate",
3
- "version": "0.12.1",
3
+ "version": "0.12.3",
4
4
  "description": "AI-driven development workflow: 6 quality gates + Delphi review + Sprint Flow",
5
5
  "bin": {
6
6
  "xp-gate": "./bin/xp-gate.js"
@@ -16,7 +16,12 @@
16
16
  "principles/",
17
17
  "mutation/",
18
18
  "mock-policy/",
19
- "build-integrity/"
19
+ "build-integrity/",
20
+ "gate-3.sh",
21
+ "gate-4.sh",
22
+ "gate-7.sh",
23
+ "gate-8.sh",
24
+ "gate-9.sh"
20
25
  ],
21
26
  "exports": {
22
27
  "./tui": "./plugins/opencode/tui-plugin.ts"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xp-gate",
3
- "version": "0.12.1",
3
+ "version": "0.12.3",
4
4
  "displayName": "XP-Gate",
5
5
  "description": "Extreme Programming quality gates + AI workflow skills for Claude Code. Includes 10 quality gates (Gate 0-9), Sprint Flow (11 phases), and Delphi multi-expert review (>=90% consensus).",
6
6
  "author": {
@@ -1,9 +1,9 @@
1
1
  # SKILLS/DELPHI-REVIEW KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-07-01
4
- **Commit:** 99e2300
3
+ **Generated:** 2026-07-03
4
+ **Commit:** 83b39b6
5
5
  **Branch:** main
6
- **Version:** 0.12.1.0
6
+ **Version:** 0.12.3.0
7
7
 
8
8
  ## OVERVIEW
9
9
  Delphi Consensus Review — multi-round anonymous expert review (≥90% threshold, 3 experts from ≥2 providers, domestic models only). Supports design + code-walkthrough modes.
@@ -32,9 +32,9 @@ skills/delphi-review/
32
32
  - 3 experts anonymous in Round 1 (no cross-expert bias)
33
33
  - ≥90% consensus threshold (was 95%, now unified to 90%)
34
34
  - Max 5 rounds before forcing decision
35
- - Cross-provider required: experts from ≥2 different providers
36
- - Domestic models only: glm, kimi, minimax, qwen, deepseek
37
- - Foreign models forbidden: Anthropic, OpenAI, Google
35
+ - Cross-provider required: experts from ≥2 different providers (model list read from `opencode.json` agent config, not hardcoded)
36
+ - Model selection: reads `delphi-reviewer-*` agent `model` fields from `opencode.json`
37
+ - No hardcoded model lists — models defined by user's `opencode.json` configuration
38
38
  - Code-walkthrough mode: triggered on git push, stores result in .code-walkthrough-result.json
39
39
  - Code-walkthrough skipped on main/master pushes (by design)
40
40
 
@@ -88,22 +88,44 @@ Permitted variants (all satisfy L1 trigger):
88
88
  | 2 专家(默认) | A(架构) + B(实现) | 代码变更、小型设计 |
89
89
  | 3 专家 | A(架构) + B(实现) + C(可行性) | 架构决策、需求文档 |
90
90
 
91
- ### 模型选择策略(强制)
91
+ ### 模型选择策略(强制 — 从 opencode.json 读取)
92
92
 
93
- **MUST 使用国产开源模型**,**严禁** Anthropic/GPT/Gemini 等国外模型。
93
+ **MUST `opencode.json` 的 agent 配置中读取模型**,**严禁** hardcode 模型名称。
94
94
 
95
- | 厂家 | 可用模型 |
96
- |------|---------|
97
- | 深度求索 DeepSeek | `deepseek-v4-pro`, `deepseek-v4-lite` |
98
- | 月之暗面 Kimi | `kimi-k2.6`, `kimi-k2.5` |
99
- | 阿里 Qwen | `qwen3.6-plus`, `qwen3.5-plus` |
100
- | 智谱 GLM | `glm-5.1`, `glm-5.0` |
101
- | MiniMax | `minimax-m2.7`, `minimax-m2.5` |
95
+ 模型选择流程:
96
+ 1. 读取 `opencode.json` 中 `agent` 字段下 `delphi-reviewer-architecture`、`delphi-reviewer-technical`、`delphi-reviewer-feasibility` 三个 agent 定义
97
+ 2. 提取每个 agent `model` 字段(格式:`provider/model-name`)
98
+ 3. 分别作为 Expert A(架构)、Expert B(技术)、Expert C(可行性) 的模型
102
99
 
103
100
  **关键原则**:
104
- - ✅ 三个专家必须来自 **至少 2 家不同厂家**
105
- - ❌ 禁止使用 Anthropic、OpenAI、Google 等国外模型
106
- - ❌ 禁止三个专家全部使用同一厂家模型
101
+ - ✅ 三个专家必须来自 **至少 2 家不同 provider**(通过 `model` 字段的 `provider/` 前缀判断)
102
+ - ❌ 禁止 hardcode 模型名称(模型列表以 `opencode.json` 为准)
103
+ - ❌ 禁止三个专家全部使用同一 provider 的模型
104
+
105
+ **`opencode.json` agent 配置示例**(参考 `opencode.json.delphi.example`):
106
+ ```json
107
+ {
108
+ "agent": {
109
+ "delphi-reviewer-architecture": {
110
+ "description": "...",
111
+ "mode": "subagent",
112
+ "model": "deepseek/deepseek-chat",
113
+ "tools": { "read": true, "bash": true, "write": false, "edit": false }
114
+ },
115
+ "delphi-reviewer-technical": {
116
+ "mode": "subagent",
117
+ "model": "bailian-coding-plan/qwen3.6-plus",
118
+ "tools": { "read": true, "bash": true, "write": false, "edit": false }
119
+ },
120
+ "delphi-reviewer-feasibility": {
121
+ "mode": "subagent",
122
+ "model": "deepseek/deepseek-chat",
123
+ "tools": { "read": true, "bash": true, "write": false, "edit": false }
124
+ }
125
+ }
126
+ }
127
+ ```
128
+ > 上例中 3 个专家使用了 2 个不同 provider(deepseek + bailian-coding-plan),满足跨 provider 要求。**实际模型名称以你的 `opencode.json` 配置为准,无需在 SKILL.md 维护模型列表。**
107
129
 
108
130
  ### 共识阈值
109
131
 
@@ -1,9 +1,9 @@
1
1
  # SKILLS/SPRINT-FLOW KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-07-01
4
- **Commit:** 99e2300
3
+ **Generated:** 2026-07-03
4
+ **Commit:** 83b39b6
5
5
  **Branch:** main
6
- **Version:** 0.12.1.0
6
+ **Version:** 0.12.3.0
7
7
 
8
8
  ## OVERVIEW
9
9
  **11-phase** development pipeline: ISOLATE → AUTO-ESTIMATE → THINK → PLAN → BUILD → REVIEW → SHIP → LAND → USER ACCEPTANCE → FEEDBACK → CLEANUP. Phase 2 default build mode is **ralph-loop** (REQ-level iteration, 40-67% token savings vs parallel). HARD-GATE in Phase 1: design must pass Delphi review (≥90% consensus) before any coding.
@@ -1,9 +1,9 @@
1
1
  # SKILLS/TEST-SPECIFICATION-ALIGNMENT KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-07-01
4
- **Commit:** 99e2300
3
+ **Generated:** 2026-07-03
4
+ **Commit:** 83b39b6
5
5
  **Branch:** main
6
- **Version:** 0.12.1.0
6
+ **Version:** 0.12.3.0
7
7
 
8
8
  ## OVERVIEW
9
9
  Test-Specification Alignment Engine — two-stage validation ensuring tests accurately reflect requirements and design specs.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boyingliu01/opencode-plugin",
3
- "version": "0.12.1",
3
+ "version": "0.12.3",
4
4
  "type": "module",
5
5
  "main": "index.ts",
6
6
  "description": "XP-Gate quality gates + AI workflow skills + Sprint Flow TUI sidebar for OpenCode",
@@ -1,9 +1,9 @@
1
1
  # SKILLS/DELPHI-REVIEW KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-07-01
4
- **Commit:** 99e2300
3
+ **Generated:** 2026-07-03
4
+ **Commit:** 83b39b6
5
5
  **Branch:** main
6
- **Version:** 0.12.1.0
6
+ **Version:** 0.12.3.0
7
7
 
8
8
  ## OVERVIEW
9
9
  Delphi Consensus Review — multi-round anonymous expert review (≥90% threshold, 3 experts from ≥2 providers, domestic models only). Supports design + code-walkthrough modes.
@@ -32,9 +32,9 @@ skills/delphi-review/
32
32
  - 3 experts anonymous in Round 1 (no cross-expert bias)
33
33
  - ≥90% consensus threshold (was 95%, now unified to 90%)
34
34
  - Max 5 rounds before forcing decision
35
- - Cross-provider required: experts from ≥2 different providers
36
- - Domestic models only: glm, kimi, minimax, qwen, deepseek
37
- - Foreign models forbidden: Anthropic, OpenAI, Google
35
+ - Cross-provider required: experts from ≥2 different providers (model list read from `opencode.json` agent config, not hardcoded)
36
+ - Model selection: reads `delphi-reviewer-*` agent `model` fields from `opencode.json`
37
+ - No hardcoded model lists — models defined by user's `opencode.json` configuration
38
38
  - Code-walkthrough mode: triggered on git push, stores result in .code-walkthrough-result.json
39
39
  - Code-walkthrough skipped on main/master pushes (by design)
40
40
 
@@ -88,22 +88,44 @@ Permitted variants (all satisfy L1 trigger):
88
88
  | 2 专家(默认) | A(架构) + B(实现) | 代码变更、小型设计 |
89
89
  | 3 专家 | A(架构) + B(实现) + C(可行性) | 架构决策、需求文档 |
90
90
 
91
- ### 模型选择策略(强制)
91
+ ### 模型选择策略(强制 — 从 opencode.json 读取)
92
92
 
93
- **MUST 使用国产开源模型**,**严禁** Anthropic/GPT/Gemini 等国外模型。
93
+ **MUST `opencode.json` 的 agent 配置中读取模型**,**严禁** hardcode 模型名称。
94
94
 
95
- | 厂家 | 可用模型 |
96
- |------|---------|
97
- | 深度求索 DeepSeek | `deepseek-v4-pro`, `deepseek-v4-lite` |
98
- | 月之暗面 Kimi | `kimi-k2.6`, `kimi-k2.5` |
99
- | 阿里 Qwen | `qwen3.6-plus`, `qwen3.5-plus` |
100
- | 智谱 GLM | `glm-5.1`, `glm-5.0` |
101
- | MiniMax | `minimax-m2.7`, `minimax-m2.5` |
95
+ 模型选择流程:
96
+ 1. 读取 `opencode.json` 中 `agent` 字段下 `delphi-reviewer-architecture`、`delphi-reviewer-technical`、`delphi-reviewer-feasibility` 三个 agent 定义
97
+ 2. 提取每个 agent `model` 字段(格式:`provider/model-name`)
98
+ 3. 分别作为 Expert A(架构)、Expert B(技术)、Expert C(可行性) 的模型
102
99
 
103
100
  **关键原则**:
104
- - ✅ 三个专家必须来自 **至少 2 家不同厂家**
105
- - ❌ 禁止使用 Anthropic、OpenAI、Google 等国外模型
106
- - ❌ 禁止三个专家全部使用同一厂家模型
101
+ - ✅ 三个专家必须来自 **至少 2 家不同 provider**(通过 `model` 字段的 `provider/` 前缀判断)
102
+ - ❌ 禁止 hardcode 模型名称(模型列表以 `opencode.json` 为准)
103
+ - ❌ 禁止三个专家全部使用同一 provider 的模型
104
+
105
+ **`opencode.json` agent 配置示例**(参考 `opencode.json.delphi.example`):
106
+ ```json
107
+ {
108
+ "agent": {
109
+ "delphi-reviewer-architecture": {
110
+ "description": "...",
111
+ "mode": "subagent",
112
+ "model": "deepseek/deepseek-chat",
113
+ "tools": { "read": true, "bash": true, "write": false, "edit": false }
114
+ },
115
+ "delphi-reviewer-technical": {
116
+ "mode": "subagent",
117
+ "model": "bailian-coding-plan/qwen3.6-plus",
118
+ "tools": { "read": true, "bash": true, "write": false, "edit": false }
119
+ },
120
+ "delphi-reviewer-feasibility": {
121
+ "mode": "subagent",
122
+ "model": "deepseek/deepseek-chat",
123
+ "tools": { "read": true, "bash": true, "write": false, "edit": false }
124
+ }
125
+ }
126
+ }
127
+ ```
128
+ > 上例中 3 个专家使用了 2 个不同 provider(deepseek + bailian-coding-plan),满足跨 provider 要求。**实际模型名称以你的 `opencode.json` 配置为准,无需在 SKILL.md 维护模型列表。**
107
129
 
108
130
  ### 共识阈值
109
131
 
@@ -1,9 +1,9 @@
1
1
  # SKILLS/SPRINT-FLOW KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-07-01
4
- **Commit:** 99e2300
3
+ **Generated:** 2026-07-03
4
+ **Commit:** 83b39b6
5
5
  **Branch:** main
6
- **Version:** 0.12.1.0
6
+ **Version:** 0.12.3.0
7
7
 
8
8
  ## OVERVIEW
9
9
  **11-phase** development pipeline: ISOLATE → AUTO-ESTIMATE → THINK → PLAN → BUILD → REVIEW → SHIP → LAND → USER ACCEPTANCE → FEEDBACK → CLEANUP. Phase 2 default build mode is **ralph-loop** (REQ-level iteration, 40-67% token savings vs parallel). HARD-GATE in Phase 1: design must pass Delphi review (≥90% consensus) before any coding.
@@ -1,9 +1,9 @@
1
1
  # SKILLS/TEST-SPECIFICATION-ALIGNMENT KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-07-01
4
- **Commit:** 99e2300
3
+ **Generated:** 2026-07-03
4
+ **Commit:** 83b39b6
5
5
  **Branch:** main
6
- **Version:** 0.12.1.0
6
+ **Version:** 0.12.3.0
7
7
 
8
8
  ## OVERVIEW
9
9
  Test-Specification Alignment Engine — two-stage validation ensuring tests accurately reflect requirements and design specs.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xp-gate",
3
- "version": "0.12.1",
3
+ "version": "0.12.3",
4
4
  "displayName": "XP-Gate",
5
5
  "description": "Extreme Programming quality gates + AI workflow skills for Qoder. Includes 10 quality gates (Gate 0-9), Sprint Flow (11 phases), and Delphi multi-expert review (>=90% consensus).",
6
6
  "author": {
@@ -1,9 +1,9 @@
1
1
  # SKILLS/DELPHI-REVIEW KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-07-01
4
- **Commit:** 99e2300
3
+ **Generated:** 2026-07-03
4
+ **Commit:** 83b39b6
5
5
  **Branch:** main
6
- **Version:** 0.12.1.0
6
+ **Version:** 0.12.3.0
7
7
 
8
8
  ## OVERVIEW
9
9
  Delphi Consensus Review — multi-round anonymous expert review (≥90% threshold, 3 experts from ≥2 providers, domestic models only). Supports design + code-walkthrough modes.
@@ -32,9 +32,9 @@ skills/delphi-review/
32
32
  - 3 experts anonymous in Round 1 (no cross-expert bias)
33
33
  - ≥90% consensus threshold (was 95%, now unified to 90%)
34
34
  - Max 5 rounds before forcing decision
35
- - Cross-provider required: experts from ≥2 different providers
36
- - Domestic models only: glm, kimi, minimax, qwen, deepseek
37
- - Foreign models forbidden: Anthropic, OpenAI, Google
35
+ - Cross-provider required: experts from ≥2 different providers (model list read from `opencode.json` agent config, not hardcoded)
36
+ - Model selection: reads `delphi-reviewer-*` agent `model` fields from `opencode.json`
37
+ - No hardcoded model lists — models defined by user's `opencode.json` configuration
38
38
  - Code-walkthrough mode: triggered on git push, stores result in .code-walkthrough-result.json
39
39
  - Code-walkthrough skipped on main/master pushes (by design)
40
40