@boyingliu01/xp-gate 0.18.0 → 0.18.2
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/adapter-common.sh +0 -0
- package/adapters/cpp.sh +0 -0
- package/adapters/dart.sh +0 -0
- package/adapters/flutter.sh +0 -0
- package/adapters/gate-3.sh +68 -0
- package/adapters/gate-4.sh +80 -0
- package/adapters/gate-7.sh +45 -0
- package/adapters/gate-8.sh +56 -0
- package/adapters/gate-9.sh +104 -0
- package/adapters/go.sh +0 -0
- package/adapters/iac.sh +0 -0
- package/adapters/java.sh +0 -0
- package/adapters/kotlin.sh +0 -0
- package/adapters/objectivec.sh +0 -0
- package/adapters/plugins/book299-20132-python/scripts/install-gradle.sh +0 -0
- package/adapters/plugins/book299-20132-python/scripts/install-maven.sh +0 -0
- package/adapters/plugins/book299-4081-c/scripts/install-gradle.sh +0 -0
- package/adapters/plugins/book299-4081-c/scripts/install-maven.sh +0 -0
- package/adapters/plugins/book299-4083-javascriptes5/scripts/install-gradle.sh +0 -0
- package/adapters/plugins/book299-4083-javascriptes5/scripts/install-maven.sh +0 -0
- package/adapters/powershell.sh +0 -0
- package/adapters/python.sh +0 -0
- package/adapters/shell.sh +0 -0
- package/adapters/swift.sh +0 -0
- package/adapters/typescript.sh +0 -0
- package/bin/xp-gate.js +0 -0
- package/gate-3.sh +0 -0
- package/gate-4.sh +0 -0
- package/gate-7.sh +0 -0
- package/gate-8.sh +0 -0
- package/gate-9.sh +0 -0
- package/hooks/adapter-common.sh +0 -0
- package/hooks/gate-3.sh +0 -0
- package/hooks/gate-4.sh +0 -0
- package/hooks/gate-7.sh +0 -0
- package/hooks/gate-8.sh +0 -0
- package/hooks/gate-9.sh +0 -0
- package/hooks/pre-commit +0 -0
- package/hooks/pre-push +0 -0
- package/hooks/sprint-gate.sh +0 -0
- package/lib/__tests__/phase-transition.test.js +512 -512
- package/lib/__tests__/sprint-audit.test.js +207 -207
- package/lib/language-tools.js +833 -833
- package/lib/mattpocock-license-verdict.json +1 -1
- package/lib/phase-transition.js +499 -499
- package/lib/sprint-audit.js +235 -235
- package/lib/sprint-init.js +207 -207
- package/mock-policy/AGENTS.md +3 -3
- package/mutation/AGENTS.md +3 -3
- package/package.json +1 -1
- package/plugins/claude-code/.claude-plugin/plugin.json +1 -1
- package/plugins/claude-code/bin/delphi-review-guard.sh +0 -0
- package/plugins/claude-code/bin/xp-gate-check +0 -0
- package/plugins/claude-code/skills/delphi-review/AGENTS.md +3 -3
- package/plugins/claude-code/skills/grilling/SKILL.md +12 -12
- package/plugins/claude-code/skills/sprint-flow/AGENTS.md +3 -3
- package/plugins/claude-code/skills/test-specification-alignment/AGENTS.md +3 -3
- package/plugins/opencode/package.json +1 -1
- package/plugins/opencode/skills/delphi-review/AGENTS.md +3 -3
- package/plugins/opencode/skills/grilling/SKILL.md +12 -12
- package/plugins/opencode/skills/sprint-flow/AGENTS.md +3 -3
- package/plugins/opencode/skills/test-specification-alignment/AGENTS.md +3 -3
- package/plugins/qoder/agents/delphi-architecture.md +48 -48
- package/plugins/qoder/agents/delphi-feasibility.md +48 -48
- package/plugins/qoder/agents/delphi-technical.md +48 -48
- package/plugins/qoder/bin/sprint-flow-guard.sh +0 -0
- package/plugins/qoder/bin/xp-gate-check +0 -0
- package/plugins/qoder/plugin.json +1 -1
- package/plugins/qoder/skills/delphi-review/AGENTS.md +3 -3
- package/plugins/qoder/skills/sprint-flow/AGENTS.md +3 -3
- package/plugins/qoder/skills/test-specification-alignment/AGENTS.md +3 -3
- package/principles/AGENTS.md +3 -3
- package/scripts/delphi-external-review.cjs +432 -432
- package/skills/delphi-review/AGENTS.md +3 -3
- package/skills/grilling/SKILL.md +12 -12
- package/skills/sprint-flow/AGENTS.md +3 -3
- package/skills/test-specification-alignment/AGENTS.md +3 -3
package/lib/sprint-init.js
CHANGED
|
@@ -1,207 +1,207 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* xp-gate sprint-init — Programmatic sprint initialization.
|
|
3
|
-
*
|
|
4
|
-
* Resolves #366 (phase-transition never called by orchestrator).
|
|
5
|
-
* Layer 1 of the three-layer enforcement mechanism.
|
|
6
|
-
*
|
|
7
|
-
* Creates .sprint-state/sprint-state.json as the single entry point
|
|
8
|
-
* for sprint initialization. Replaces manual state file creation.
|
|
9
|
-
*
|
|
10
|
-
* Usage:
|
|
11
|
-
* xp-gate sprint-init "<task_description>" [--issues "<#123,#456>"] [--force] [--dry-run] [--dir <path>]
|
|
12
|
-
*
|
|
13
|
-
* Non-interactive design (LLM orchestrator cannot handle stdin):
|
|
14
|
-
* - Default: existing active sprint → error exit 1
|
|
15
|
-
* - --force: override existing sprint, backup old state to .sprint-history/
|
|
16
|
-
* - --dry-run: pre-check conflicts, no writes
|
|
17
|
-
* - Idempotent: same task_description + branch → output dashboard, exit 0
|
|
18
|
-
*
|
|
19
|
-
* @module sprint-init
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
'use strict';
|
|
23
|
-
|
|
24
|
-
const fs = require('fs');
|
|
25
|
-
const path = require('path');
|
|
26
|
-
const { execFileSync } = require('child_process');
|
|
27
|
-
const { SprintStateManager } = require('./sprint-state-manager');
|
|
28
|
-
const { renderDashboard } = require('./phase-transition');
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Detect current git branch.
|
|
32
|
-
* @param {string} cwd - Working directory
|
|
33
|
-
* @returns {string} Branch name or 'detached'
|
|
34
|
-
*/
|
|
35
|
-
function detectBranch(cwd) {
|
|
36
|
-
try {
|
|
37
|
-
const branch = execFileSync('git', ['branch', '--show-current'], {
|
|
38
|
-
cwd, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'],
|
|
39
|
-
}).trim();
|
|
40
|
-
return branch || 'detached';
|
|
41
|
-
} catch {
|
|
42
|
-
return 'unknown';
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Generate sprint ID from date and sequence.
|
|
48
|
-
* @returns {string} Sprint ID like "sprint-20260722-01"
|
|
49
|
-
*/
|
|
50
|
-
function generateSprintId() {
|
|
51
|
-
const now = new Date();
|
|
52
|
-
const dateStr = now.toISOString().slice(0, 10).replace(/-/g, '');
|
|
53
|
-
const seq = String(Math.floor(Math.random() * 99) + 1).padStart(2, '0');
|
|
54
|
-
return `sprint-${dateStr}-${seq}`;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Backup existing sprint state to .sprint-history/.
|
|
59
|
-
* @param {string} projectRoot - Project root directory
|
|
60
|
-
* @param {object} state - Current sprint state
|
|
61
|
-
*/
|
|
62
|
-
function backupSprintState(projectRoot, state) {
|
|
63
|
-
const historyDir = path.join(projectRoot, '.sprint-history');
|
|
64
|
-
if (!fs.existsSync(historyDir)) {
|
|
65
|
-
fs.mkdirSync(historyDir, { recursive: true });
|
|
66
|
-
}
|
|
67
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
68
|
-
const backupFile = path.join(historyDir, `sprint-state-${state.id || 'unknown'}-${timestamp}.json`);
|
|
69
|
-
fs.writeFileSync(backupFile, JSON.stringify(state, null, 2), 'utf8');
|
|
70
|
-
return backupFile;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* CLI entry point for sprint-init command.
|
|
75
|
-
* @param {string[]} args - CLI arguments
|
|
76
|
-
* @returns {Promise<number>} Exit code
|
|
77
|
-
*/
|
|
78
|
-
async function handleSprintInit(args = []) {
|
|
79
|
-
if (args.includes('--help')) {
|
|
80
|
-
console.log('Usage: xp-gate sprint-init "<task_description>" [options]');
|
|
81
|
-
console.log('');
|
|
82
|
-
console.log('Arguments:');
|
|
83
|
-
console.log(' task_description Sprint task description (required)');
|
|
84
|
-
console.log('');
|
|
85
|
-
console.log('Options:');
|
|
86
|
-
console.log(' --issues <list> Comma-separated issue numbers (e.g. "#123,#456")');
|
|
87
|
-
console.log(' --force Override existing active sprint (backs up old state)');
|
|
88
|
-
console.log(' --dry-run Pre-check conflicts without writing');
|
|
89
|
-
console.log(' --dir <path> Project directory (default: cwd)');
|
|
90
|
-
console.log('');
|
|
91
|
-
console.log('Examples:');
|
|
92
|
-
console.log(' xp-gate sprint-init "Implement user auth"');
|
|
93
|
-
console.log(' xp-gate sprint-init "Fix #366" --issues "#366" --force');
|
|
94
|
-
return 0;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Parse arguments
|
|
98
|
-
const forceFlag = args.includes('--force');
|
|
99
|
-
const dryRunFlag = args.includes('--dry-run');
|
|
100
|
-
const dirIdx = args.indexOf('--dir');
|
|
101
|
-
const projectDir = dirIdx >= 0 ? args[dirIdx + 1] : process.cwd();
|
|
102
|
-
const issuesIdx = args.indexOf('--issues');
|
|
103
|
-
const issues = issuesIdx >= 0 ? args[issuesIdx + 1] : '';
|
|
104
|
-
|
|
105
|
-
// First non-flag argument is task_description
|
|
106
|
-
const taskDescription = args.find(a => !a.startsWith('--') && a !== projectDir && a !== issues);
|
|
107
|
-
if (!taskDescription) {
|
|
108
|
-
console.error('Error: Missing task_description. Usage: xp-gate sprint-init "<task_description>"');
|
|
109
|
-
return 1;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const manager = new SprintStateManager(projectDir);
|
|
113
|
-
const branch = detectBranch(projectDir);
|
|
114
|
-
|
|
115
|
-
// Check existing sprint state
|
|
116
|
-
let existingState = null;
|
|
117
|
-
try {
|
|
118
|
-
existingState = manager.read();
|
|
119
|
-
} catch {
|
|
120
|
-
// Corrupted state — treat as no state (will be overwritten)
|
|
121
|
-
existingState = null;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (existingState) {
|
|
125
|
-
// Idempotent check: same task_description + branch → output dashboard, exit 0
|
|
126
|
-
const normalizedExisting = (existingState.task_description || '').trim();
|
|
127
|
-
const normalizedNew = taskDescription.trim();
|
|
128
|
-
const existingBranch = existingState.isolation?.branch || '';
|
|
129
|
-
|
|
130
|
-
if (normalizedExisting === normalizedNew && existingBranch === branch && branch !== 'detached') {
|
|
131
|
-
console.log('ℹ️ Sprint already initialized (idempotent call). Current state:');
|
|
132
|
-
console.log('');
|
|
133
|
-
console.log(renderDashboard(existingState));
|
|
134
|
-
return 0;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Conflict: existing active sprint
|
|
138
|
-
if (!forceFlag) {
|
|
139
|
-
if (dryRunFlag) {
|
|
140
|
-
console.log(JSON.stringify({
|
|
141
|
-
decision: 'deny',
|
|
142
|
-
reason: `Active sprint "${existingState.id}" exists (task: "${normalizedExisting}")`,
|
|
143
|
-
hint: 'Use --force to override (backs up old state)',
|
|
144
|
-
}));
|
|
145
|
-
return 0;
|
|
146
|
-
}
|
|
147
|
-
console.error(`Error: Active sprint "${existingState.id}" already exists.`);
|
|
148
|
-
console.error(` Task: "${normalizedExisting}"`);
|
|
149
|
-
console.error(` Branch: ${existingBranch}`);
|
|
150
|
-
console.error(' Use --force to override (backs up old state to .sprint-history/)');
|
|
151
|
-
return 1;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// --force: backup and override
|
|
155
|
-
const backupPath = backupSprintState(projectDir, existingState);
|
|
156
|
-
console.log(`📦 Backed up existing sprint to: ${backupPath}`);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if (dryRunFlag) {
|
|
160
|
-
console.log(JSON.stringify({
|
|
161
|
-
decision: 'allow',
|
|
162
|
-
reason: existingState ? 'Would override existing sprint (--force)' : 'No existing sprint',
|
|
163
|
-
branch,
|
|
164
|
-
task_description: taskDescription.trim(),
|
|
165
|
-
}));
|
|
166
|
-
return 0;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Create new sprint state
|
|
170
|
-
const sprintId = generateSprintId();
|
|
171
|
-
const newState = {
|
|
172
|
-
_schema_version: 1,
|
|
173
|
-
id: sprintId,
|
|
174
|
-
task_description: taskDescription.trim(),
|
|
175
|
-
phase: 1,
|
|
176
|
-
status: 'in_progress',
|
|
177
|
-
started_at: new Date().toISOString(),
|
|
178
|
-
phase_history: [
|
|
179
|
-
{
|
|
180
|
-
phase: 1,
|
|
181
|
-
name: 'PREP',
|
|
182
|
-
status: 'in_progress',
|
|
183
|
-
started_at: new Date().toISOString(),
|
|
184
|
-
},
|
|
185
|
-
],
|
|
186
|
-
isolation: {
|
|
187
|
-
worktree_path: projectDir,
|
|
188
|
-
branch,
|
|
189
|
-
},
|
|
190
|
-
outputs: issues ? { issues } : {},
|
|
191
|
-
metrics: {},
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
// Write state atomically
|
|
195
|
-
manager.write(newState);
|
|
196
|
-
|
|
197
|
-
console.log(`✅ Sprint initialized: ${sprintId}`);
|
|
198
|
-
console.log(` Task: ${taskDescription.trim()}`);
|
|
199
|
-
console.log(` Branch: ${branch}`);
|
|
200
|
-
if (issues) console.log(` Issues: ${issues}`);
|
|
201
|
-
console.log('');
|
|
202
|
-
console.log(renderDashboard(newState));
|
|
203
|
-
|
|
204
|
-
return 0;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
module.exports = { handleSprintInit, detectBranch, generateSprintId, backupSprintState };
|
|
1
|
+
/**
|
|
2
|
+
* xp-gate sprint-init — Programmatic sprint initialization.
|
|
3
|
+
*
|
|
4
|
+
* Resolves #366 (phase-transition never called by orchestrator).
|
|
5
|
+
* Layer 1 of the three-layer enforcement mechanism.
|
|
6
|
+
*
|
|
7
|
+
* Creates .sprint-state/sprint-state.json as the single entry point
|
|
8
|
+
* for sprint initialization. Replaces manual state file creation.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* xp-gate sprint-init "<task_description>" [--issues "<#123,#456>"] [--force] [--dry-run] [--dir <path>]
|
|
12
|
+
*
|
|
13
|
+
* Non-interactive design (LLM orchestrator cannot handle stdin):
|
|
14
|
+
* - Default: existing active sprint → error exit 1
|
|
15
|
+
* - --force: override existing sprint, backup old state to .sprint-history/
|
|
16
|
+
* - --dry-run: pre-check conflicts, no writes
|
|
17
|
+
* - Idempotent: same task_description + branch → output dashboard, exit 0
|
|
18
|
+
*
|
|
19
|
+
* @module sprint-init
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
'use strict';
|
|
23
|
+
|
|
24
|
+
const fs = require('fs');
|
|
25
|
+
const path = require('path');
|
|
26
|
+
const { execFileSync } = require('child_process');
|
|
27
|
+
const { SprintStateManager } = require('./sprint-state-manager');
|
|
28
|
+
const { renderDashboard } = require('./phase-transition');
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Detect current git branch.
|
|
32
|
+
* @param {string} cwd - Working directory
|
|
33
|
+
* @returns {string} Branch name or 'detached'
|
|
34
|
+
*/
|
|
35
|
+
function detectBranch(cwd) {
|
|
36
|
+
try {
|
|
37
|
+
const branch = execFileSync('git', ['branch', '--show-current'], {
|
|
38
|
+
cwd, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'],
|
|
39
|
+
}).trim();
|
|
40
|
+
return branch || 'detached';
|
|
41
|
+
} catch {
|
|
42
|
+
return 'unknown';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Generate sprint ID from date and sequence.
|
|
48
|
+
* @returns {string} Sprint ID like "sprint-20260722-01"
|
|
49
|
+
*/
|
|
50
|
+
function generateSprintId() {
|
|
51
|
+
const now = new Date();
|
|
52
|
+
const dateStr = now.toISOString().slice(0, 10).replace(/-/g, '');
|
|
53
|
+
const seq = String(Math.floor(Math.random() * 99) + 1).padStart(2, '0');
|
|
54
|
+
return `sprint-${dateStr}-${seq}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Backup existing sprint state to .sprint-history/.
|
|
59
|
+
* @param {string} projectRoot - Project root directory
|
|
60
|
+
* @param {object} state - Current sprint state
|
|
61
|
+
*/
|
|
62
|
+
function backupSprintState(projectRoot, state) {
|
|
63
|
+
const historyDir = path.join(projectRoot, '.sprint-history');
|
|
64
|
+
if (!fs.existsSync(historyDir)) {
|
|
65
|
+
fs.mkdirSync(historyDir, { recursive: true });
|
|
66
|
+
}
|
|
67
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
68
|
+
const backupFile = path.join(historyDir, `sprint-state-${state.id || 'unknown'}-${timestamp}.json`);
|
|
69
|
+
fs.writeFileSync(backupFile, JSON.stringify(state, null, 2), 'utf8');
|
|
70
|
+
return backupFile;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* CLI entry point for sprint-init command.
|
|
75
|
+
* @param {string[]} args - CLI arguments
|
|
76
|
+
* @returns {Promise<number>} Exit code
|
|
77
|
+
*/
|
|
78
|
+
async function handleSprintInit(args = []) {
|
|
79
|
+
if (args.includes('--help')) {
|
|
80
|
+
console.log('Usage: xp-gate sprint-init "<task_description>" [options]');
|
|
81
|
+
console.log('');
|
|
82
|
+
console.log('Arguments:');
|
|
83
|
+
console.log(' task_description Sprint task description (required)');
|
|
84
|
+
console.log('');
|
|
85
|
+
console.log('Options:');
|
|
86
|
+
console.log(' --issues <list> Comma-separated issue numbers (e.g. "#123,#456")');
|
|
87
|
+
console.log(' --force Override existing active sprint (backs up old state)');
|
|
88
|
+
console.log(' --dry-run Pre-check conflicts without writing');
|
|
89
|
+
console.log(' --dir <path> Project directory (default: cwd)');
|
|
90
|
+
console.log('');
|
|
91
|
+
console.log('Examples:');
|
|
92
|
+
console.log(' xp-gate sprint-init "Implement user auth"');
|
|
93
|
+
console.log(' xp-gate sprint-init "Fix #366" --issues "#366" --force');
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Parse arguments
|
|
98
|
+
const forceFlag = args.includes('--force');
|
|
99
|
+
const dryRunFlag = args.includes('--dry-run');
|
|
100
|
+
const dirIdx = args.indexOf('--dir');
|
|
101
|
+
const projectDir = dirIdx >= 0 ? args[dirIdx + 1] : process.cwd();
|
|
102
|
+
const issuesIdx = args.indexOf('--issues');
|
|
103
|
+
const issues = issuesIdx >= 0 ? args[issuesIdx + 1] : '';
|
|
104
|
+
|
|
105
|
+
// First non-flag argument is task_description
|
|
106
|
+
const taskDescription = args.find(a => !a.startsWith('--') && a !== projectDir && a !== issues);
|
|
107
|
+
if (!taskDescription) {
|
|
108
|
+
console.error('Error: Missing task_description. Usage: xp-gate sprint-init "<task_description>"');
|
|
109
|
+
return 1;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const manager = new SprintStateManager(projectDir);
|
|
113
|
+
const branch = detectBranch(projectDir);
|
|
114
|
+
|
|
115
|
+
// Check existing sprint state
|
|
116
|
+
let existingState = null;
|
|
117
|
+
try {
|
|
118
|
+
existingState = manager.read();
|
|
119
|
+
} catch {
|
|
120
|
+
// Corrupted state — treat as no state (will be overwritten)
|
|
121
|
+
existingState = null;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (existingState) {
|
|
125
|
+
// Idempotent check: same task_description + branch → output dashboard, exit 0
|
|
126
|
+
const normalizedExisting = (existingState.task_description || '').trim();
|
|
127
|
+
const normalizedNew = taskDescription.trim();
|
|
128
|
+
const existingBranch = existingState.isolation?.branch || '';
|
|
129
|
+
|
|
130
|
+
if (normalizedExisting === normalizedNew && existingBranch === branch && branch !== 'detached') {
|
|
131
|
+
console.log('ℹ️ Sprint already initialized (idempotent call). Current state:');
|
|
132
|
+
console.log('');
|
|
133
|
+
console.log(renderDashboard(existingState));
|
|
134
|
+
return 0;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Conflict: existing active sprint
|
|
138
|
+
if (!forceFlag) {
|
|
139
|
+
if (dryRunFlag) {
|
|
140
|
+
console.log(JSON.stringify({
|
|
141
|
+
decision: 'deny',
|
|
142
|
+
reason: `Active sprint "${existingState.id}" exists (task: "${normalizedExisting}")`,
|
|
143
|
+
hint: 'Use --force to override (backs up old state)',
|
|
144
|
+
}));
|
|
145
|
+
return 0;
|
|
146
|
+
}
|
|
147
|
+
console.error(`Error: Active sprint "${existingState.id}" already exists.`);
|
|
148
|
+
console.error(` Task: "${normalizedExisting}"`);
|
|
149
|
+
console.error(` Branch: ${existingBranch}`);
|
|
150
|
+
console.error(' Use --force to override (backs up old state to .sprint-history/)');
|
|
151
|
+
return 1;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// --force: backup and override
|
|
155
|
+
const backupPath = backupSprintState(projectDir, existingState);
|
|
156
|
+
console.log(`📦 Backed up existing sprint to: ${backupPath}`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (dryRunFlag) {
|
|
160
|
+
console.log(JSON.stringify({
|
|
161
|
+
decision: 'allow',
|
|
162
|
+
reason: existingState ? 'Would override existing sprint (--force)' : 'No existing sprint',
|
|
163
|
+
branch,
|
|
164
|
+
task_description: taskDescription.trim(),
|
|
165
|
+
}));
|
|
166
|
+
return 0;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Create new sprint state
|
|
170
|
+
const sprintId = generateSprintId();
|
|
171
|
+
const newState = {
|
|
172
|
+
_schema_version: 1,
|
|
173
|
+
id: sprintId,
|
|
174
|
+
task_description: taskDescription.trim(),
|
|
175
|
+
phase: 1,
|
|
176
|
+
status: 'in_progress',
|
|
177
|
+
started_at: new Date().toISOString(),
|
|
178
|
+
phase_history: [
|
|
179
|
+
{
|
|
180
|
+
phase: 1,
|
|
181
|
+
name: 'PREP',
|
|
182
|
+
status: 'in_progress',
|
|
183
|
+
started_at: new Date().toISOString(),
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
isolation: {
|
|
187
|
+
worktree_path: projectDir,
|
|
188
|
+
branch,
|
|
189
|
+
},
|
|
190
|
+
outputs: issues ? { issues } : {},
|
|
191
|
+
metrics: {},
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
// Write state atomically
|
|
195
|
+
manager.write(newState);
|
|
196
|
+
|
|
197
|
+
console.log(`✅ Sprint initialized: ${sprintId}`);
|
|
198
|
+
console.log(` Task: ${taskDescription.trim()}`);
|
|
199
|
+
console.log(` Branch: ${branch}`);
|
|
200
|
+
if (issues) console.log(` Issues: ${issues}`);
|
|
201
|
+
console.log('');
|
|
202
|
+
console.log(renderDashboard(newState));
|
|
203
|
+
|
|
204
|
+
return 0;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
module.exports = { handleSprintInit, detectBranch, generateSprintId, backupSprintState };
|
package/mock-policy/AGENTS.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SRC/MOCK-POLICY KNOWLEDGE BASE
|
|
2
2
|
|
|
3
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-27
|
|
4
|
+
**Commit:** f112d8d
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.18.
|
|
6
|
+
**Version:** 0.18.2.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.
|
package/mutation/AGENTS.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SRC/MUTATION KNOWLEDGE BASE
|
|
2
2
|
|
|
3
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-27
|
|
4
|
+
**Commit:** f112d8d
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.18.
|
|
6
|
+
**Version:** 0.18.2.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": "xp-gate",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.2",
|
|
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": {
|
|
File without changes
|
|
File without changes
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/DELPHI-REVIEW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-27
|
|
4
|
+
**Commit:** f112d8d
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.18.
|
|
6
|
+
**Version:** 0.18.2.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.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: grilling
|
|
3
|
-
description: Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
Interview me relentlessly about every aspect of this until we reach a shared understanding. Walk down each branch of the decision tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer.
|
|
7
|
-
|
|
8
|
-
Ask the questions one at a time, waiting for feedback on each question before continuing. Asking multiple questions at once is bewildering.
|
|
9
|
-
|
|
10
|
-
If a *fact* can be found by exploring the environment (filesystem, tools, etc.), look it up rather than asking me. The *decisions*, though, are mine — put each one to me and wait for my answer.
|
|
11
|
-
|
|
12
|
-
Do not act on it until I confirm we have reached a shared understanding.
|
|
1
|
+
---
|
|
2
|
+
name: grilling
|
|
3
|
+
description: Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Interview me relentlessly about every aspect of this until we reach a shared understanding. Walk down each branch of the decision tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer.
|
|
7
|
+
|
|
8
|
+
Ask the questions one at a time, waiting for feedback on each question before continuing. Asking multiple questions at once is bewildering.
|
|
9
|
+
|
|
10
|
+
If a *fact* can be found by exploring the environment (filesystem, tools, etc.), look it up rather than asking me. The *decisions*, though, are mine — put each one to me and wait for my answer.
|
|
11
|
+
|
|
12
|
+
Do not act on it until I confirm we have reached a shared understanding.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/SPRINT-FLOW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-27
|
|
4
|
+
**Commit:** f112d8d
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.18.
|
|
6
|
+
**Version:** 0.18.2.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
**6-phase** development pipeline (v2.0 compact redesign, Issue #290): PREP → DESIGN → BUILD → VERIFY → SHIP → CLOSE. Phase 3/6 BUILD default build mode is **ralph-loop** (REQ-level iteration, 40-67% token savings vs parallel). HARD-GATE between DESIGN (2/6) and BUILD (3/6): 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-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-27
|
|
4
|
+
**Commit:** f112d8d
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.18.
|
|
6
|
+
**Version:** 0.18.2.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Test-Specification Alignment Engine — two-stage validation ensuring tests accurately reflect requirements and design specs.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/DELPHI-REVIEW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-27
|
|
4
|
+
**Commit:** f112d8d
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.18.
|
|
6
|
+
**Version:** 0.18.2.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.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: grilling
|
|
3
|
-
description: Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
Interview me relentlessly about every aspect of this until we reach a shared understanding. Walk down each branch of the decision tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer.
|
|
7
|
-
|
|
8
|
-
Ask the questions one at a time, waiting for feedback on each question before continuing. Asking multiple questions at once is bewildering.
|
|
9
|
-
|
|
10
|
-
If a *fact* can be found by exploring the environment (filesystem, tools, etc.), look it up rather than asking me. The *decisions*, though, are mine — put each one to me and wait for my answer.
|
|
11
|
-
|
|
12
|
-
Do not act on it until I confirm we have reached a shared understanding.
|
|
1
|
+
---
|
|
2
|
+
name: grilling
|
|
3
|
+
description: Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Interview me relentlessly about every aspect of this until we reach a shared understanding. Walk down each branch of the decision tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer.
|
|
7
|
+
|
|
8
|
+
Ask the questions one at a time, waiting for feedback on each question before continuing. Asking multiple questions at once is bewildering.
|
|
9
|
+
|
|
10
|
+
If a *fact* can be found by exploring the environment (filesystem, tools, etc.), look it up rather than asking me. The *decisions*, though, are mine — put each one to me and wait for my answer.
|
|
11
|
+
|
|
12
|
+
Do not act on it until I confirm we have reached a shared understanding.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SKILLS/SPRINT-FLOW KNOWLEDGE BASE
|
|
2
2
|
|
|
3
|
-
**Generated:** 2026-07-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-27
|
|
4
|
+
**Commit:** f112d8d
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.18.
|
|
6
|
+
**Version:** 0.18.2.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
**6-phase** development pipeline (v2.0 compact redesign, Issue #290): PREP → DESIGN → BUILD → VERIFY → SHIP → CLOSE. Phase 3/6 BUILD default build mode is **ralph-loop** (REQ-level iteration, 40-67% token savings vs parallel). HARD-GATE between DESIGN (2/6) and BUILD (3/6): 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-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-07-27
|
|
4
|
+
**Commit:** f112d8d
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.18.
|
|
6
|
+
**Version:** 0.18.2.0
|
|
7
7
|
|
|
8
8
|
## OVERVIEW
|
|
9
9
|
Test-Specification Alignment Engine — two-stage validation ensuring tests accurately reflect requirements and design specs.
|