@boyingliu01/xp-gate 0.18.5 → 0.19.1
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 +27 -0
- package/adapters/gate-3.sh +0 -0
- package/adapters/gate-4.sh +0 -0
- package/adapters/gate-7.sh +0 -0
- package/adapters/gate-8.sh +0 -0
- package/adapters/gate-9.sh +0 -0
- package/adapters/powershell.sh +114 -35
- package/adapters/typescript.sh +8 -8
- package/build-integrity/__tests__/import-resolver.test.ts +22 -0
- package/build-integrity/__tests__/orchestrator.test.ts +1 -2
- package/build-integrity/gate-10.ts +7 -0
- package/gate-12-file-hygiene.sh +230 -0
- package/hooks/adapter-common.sh +27 -0
- package/hooks/gate-10.sh +105 -0
- package/hooks/gate-12-file-hygiene.sh +0 -0
- package/hooks/lib/validate-code-walkthrough.cjs +125 -0
- package/hooks/pre-commit +130 -33
- package/hooks/pre-push +15 -91
- package/lib/__tests__/check-version.test.js +67 -46
- package/lib/__tests__/doctor.test.js +7 -6
- package/lib/__tests__/gate-runner.test.js +267 -0
- package/lib/__tests__/init.test.js +32 -0
- package/lib/__tests__/npm-package.test.js +13 -0
- package/lib/__tests__/phase-transition.test.js +604 -12
- package/lib/__tests__/sprint-discovery.test.ts +0 -1
- package/lib/__tests__/sprint-status-rework.test.js +100 -1
- package/lib/__tests__/update-hooks.test.js +143 -10
- package/lib/__tests__/upgrade-exec.test.js +73 -45
- package/lib/__tests__/upgrade-skill-sync.test.js +1 -1
- package/lib/__tests__/upgrade.test.js +12 -11
- package/lib/doctor.js +2 -1
- package/lib/gate-runner.js +68 -23
- package/lib/init.js +34 -5
- package/lib/install-skill.js +1 -0
- package/lib/mattpocock-license-verdict.json +1 -1
- package/lib/phase-transition.js +203 -23
- package/lib/shared-paths.js +2 -0
- package/lib/sprint-status.js +15 -4
- package/lib/test-alignment.ts +3 -13
- package/lib/update-hooks.js +129 -15
- package/mock-policy/AGENTS.md +4 -4
- package/mock-policy/__tests__/gate-m3.test.ts +0 -5
- package/mock-policy/__tests__/scope-scanner.test.ts +8 -2
- package/mutation/AGENTS.md +3 -3
- package/mutation/__tests__/mutmut-runner.test.ts +443 -2
- package/mutation/__tests__/update-baseline.test.ts +0 -2
- package/mutation/runners/mutmut-runner.ts +67 -17
- package/package.json +9 -3
- package/plugins/claude-code/.claude-plugin/plugin.json +1 -1
- package/plugins/claude-code/skills/clipboard-vision/SKILL.md +47 -0
- package/plugins/claude-code/skills/clipboard-vision/__tests__/clipboard-vision-distribution.test.cjs +65 -0
- package/plugins/claude-code/skills/clipboard-vision/__tests__/clipboard-vision-security.test.cjs +185 -0
- package/plugins/claude-code/skills/clipboard-vision/__tests__/clipboard-vision.Tests.ps1 +138 -0
- package/plugins/claude-code/skills/clipboard-vision/__tests__/clipboard-vision.test.cjs +273 -0
- package/plugins/claude-code/skills/clipboard-vision/describe-clipboard.ps1 +115 -0
- package/plugins/claude-code/skills/clipboard-vision/describe-clipboard.sh +161 -0
- package/plugins/claude-code/skills/clipboard-vision/scripts/clipboard-vision.ps1 +86 -0
- package/plugins/claude-code/skills/clipboard-vision/scripts/clipboard-vision.sh +137 -0
- package/plugins/claude-code/skills/delphi-review/.delphi-config.json.example +24 -27
- package/plugins/claude-code/skills/delphi-review/AGENTS.md +12 -11
- package/plugins/claude-code/skills/delphi-review/INSTALL.md +15 -17
- package/plugins/claude-code/skills/delphi-review/SKILL.md +30 -29
- package/plugins/claude-code/skills/delphi-review/opencode.json.delphi.example +6 -10
- package/plugins/claude-code/skills/delphi-review/references/code-walkthrough.md +33 -49
- package/plugins/claude-code/skills/delphi-review/references/requirements.md +66 -54
- package/plugins/claude-code/skills/delphi-review/references/round-templates.md +7 -7
- package/plugins/claude-code/skills/sprint-flow/AGENTS.md +4 -4
- package/plugins/claude-code/skills/sprint-flow/SKILL.md +4 -4
- package/plugins/claude-code/skills/sprint-flow/references/components/skill-invocations.md +2 -2
- package/plugins/claude-code/skills/sprint-flow/references/force-levels.md +37 -35
- package/plugins/claude-code/skills/sprint-flow/references/orchestration-rules.md +1 -1
- package/plugins/claude-code/skills/sprint-flow/references/phase-1-prep.md +1 -1
- package/plugins/claude-code/skills/sprint-flow/references/phase-2-design.md +24 -14
- package/plugins/claude-code/skills/sprint-flow/references/phase-4-verify.md +6 -6
- package/plugins/claude-code/skills/sprint-flow/references/phase-overview.md +2 -2
- package/plugins/claude-code/skills/test-specification-alignment/AGENTS.md +3 -3
- package/plugins/dsh/README.md +25 -0
- package/plugins/dsh/cordis.patch.yml +7 -0
- package/plugins/dsh/package.json +70 -0
- package/plugins/dsh/scripts/prepack.cjs +82 -0
- package/plugins/dsh/skills/admin-template-guidelines/SKILL.md +113 -0
- package/plugins/dsh/skills/admin-template-guidelines/references/rule-1.md +91 -0
- package/plugins/dsh/skills/admin-template-guidelines/references/rule-2.md +155 -0
- package/plugins/dsh/skills/admin-template-guidelines/references/rule-3.md +70 -0
- package/plugins/dsh/skills/admin-template-guidelines/references/rule-4.md +154 -0
- package/plugins/dsh/skills/admin-template-guidelines/references/rule-5.md +126 -0
- package/plugins/dsh/skills/admin-template-guidelines/references/rule-6.md +180 -0
- package/plugins/dsh/skills/batch-grill-me/SKILL.md +15 -0
- package/plugins/dsh/skills/clipboard-vision/SKILL.md +47 -0
- package/plugins/dsh/skills/clipboard-vision/__tests__/clipboard-vision-distribution.test.cjs +65 -0
- package/plugins/dsh/skills/clipboard-vision/__tests__/clipboard-vision-security.test.cjs +185 -0
- package/plugins/dsh/skills/clipboard-vision/__tests__/clipboard-vision.Tests.ps1 +138 -0
- package/plugins/dsh/skills/clipboard-vision/__tests__/clipboard-vision.test.cjs +273 -0
- package/plugins/dsh/skills/clipboard-vision/describe-clipboard.ps1 +115 -0
- package/plugins/dsh/skills/clipboard-vision/describe-clipboard.sh +161 -0
- package/plugins/dsh/skills/clipboard-vision/scripts/clipboard-vision.ps1 +86 -0
- package/plugins/dsh/skills/clipboard-vision/scripts/clipboard-vision.sh +137 -0
- package/plugins/dsh/skills/delphi-review/.delphi-config.json.example +70 -0
- package/plugins/dsh/skills/delphi-review/AGENTS.md +67 -0
- package/plugins/dsh/skills/delphi-review/INSTALL.md +150 -0
- package/plugins/dsh/skills/delphi-review/SKILL.md +559 -0
- package/plugins/dsh/skills/delphi-review/hooks.md +19 -0
- package/plugins/dsh/skills/delphi-review/opencode.json.delphi.example +52 -0
- package/plugins/dsh/skills/delphi-review/references/code-walkthrough.md +470 -0
- package/plugins/dsh/skills/delphi-review/references/orchestrator-dispatch.md +64 -0
- package/plugins/dsh/skills/delphi-review/references/requirements.md +402 -0
- package/plugins/dsh/skills/delphi-review/references/round-templates.md +134 -0
- package/plugins/dsh/skills/delphi-review/scripts/verify-consensus.sh +43 -0
- package/plugins/dsh/skills/delphi-review/tools.md +29 -0
- package/plugins/dsh/skills/domain-modeling/ADR-FORMAT.md +64 -0
- package/plugins/dsh/skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
- package/plugins/dsh/skills/domain-modeling/SKILL.md +74 -0
- package/plugins/dsh/skills/grill-with-docs/SKILL.md +7 -0
- package/plugins/dsh/skills/grilling/SKILL.md +12 -0
- package/plugins/dsh/skills/improve-codebase-architecture/SKILL.md +156 -0
- package/plugins/dsh/skills/ralph-loop/SKILL.md +198 -0
- package/plugins/dsh/skills/ralph-loop/references/components.md +113 -0
- package/plugins/dsh/skills/ralph-loop/references/phase-2-build-ralph.md +89 -0
- package/plugins/dsh/skills/ralph-loop/references/workflow-details.md +99 -0
- package/plugins/dsh/skills/ralph-loop/templates/progress-log.md +36 -0
- package/plugins/dsh/skills/sprint-flow/AGENTS.md +103 -0
- package/plugins/dsh/skills/sprint-flow/SKILL.md +411 -0
- package/plugins/dsh/skills/sprint-flow/__tests__/sprint-flow.test.cjs +457 -0
- package/plugins/dsh/skills/sprint-flow/hooks.md +18 -0
- package/plugins/dsh/skills/sprint-flow/references/components/memory.md +87 -0
- package/plugins/dsh/skills/sprint-flow/references/components/middleware.md +75 -0
- package/plugins/dsh/skills/sprint-flow/references/components/skill-invocations.md +105 -0
- package/plugins/dsh/skills/sprint-flow/references/components/system-prompt.md +27 -0
- package/plugins/dsh/skills/sprint-flow/references/components/tool-descriptions.md +95 -0
- package/plugins/dsh/skills/sprint-flow/references/force-levels.md +204 -0
- package/plugins/dsh/skills/sprint-flow/references/orchestration-rules.md +236 -0
- package/plugins/dsh/skills/sprint-flow/references/phase-1-prep.md +294 -0
- package/plugins/dsh/skills/sprint-flow/references/phase-2-design.md +273 -0
- package/plugins/dsh/skills/sprint-flow/references/phase-3-build.md +348 -0
- package/plugins/dsh/skills/sprint-flow/references/phase-4-verify.md +225 -0
- package/plugins/dsh/skills/sprint-flow/references/phase-5-ship.md +222 -0
- package/plugins/dsh/skills/sprint-flow/references/phase-6-close.md +266 -0
- package/plugins/dsh/skills/sprint-flow/references/phase-overview.md +486 -0
- package/plugins/dsh/skills/sprint-flow/scripts/verify-sprint-state.sh +38 -0
- package/plugins/dsh/skills/sprint-flow/templates/auto-estimate-learning-log.md +136 -0
- package/plugins/dsh/skills/sprint-flow/templates/auto-estimate-output-template.md +110 -0
- package/plugins/dsh/skills/sprint-flow/templates/emergent-issues-template.md +120 -0
- package/plugins/dsh/skills/sprint-flow/templates/pain-document-template.md +115 -0
- package/plugins/dsh/skills/sprint-flow/templates/sprint-progress-template.md +140 -0
- package/plugins/dsh/skills/sprint-flow/templates/sprint-summary-template.md +121 -0
- package/plugins/dsh/skills/sprint-flow/tools.md +29 -0
- package/plugins/dsh/skills/test-driven-development/SKILL.md +371 -0
- package/plugins/dsh/skills/test-driven-development/testing-anti-patterns.md +299 -0
- package/plugins/dsh/skills/test-specification-alignment/AGENTS.md +56 -0
- package/plugins/dsh/skills/test-specification-alignment/SKILL.md +205 -0
- package/plugins/dsh/skills/test-specification-alignment/references/alignment-verification-algorithm.md +493 -0
- package/plugins/dsh/skills/test-specification-alignment/references/phase2-constraint-enforcement.md +431 -0
- package/plugins/dsh/skills/test-specification-alignment/references/specification-format.md +348 -0
- package/plugins/dsh/skills/to-issues/SKILL.md +277 -0
- package/plugins/dsh/src/command.test.ts +102 -0
- package/plugins/dsh/src/command.ts +75 -0
- package/plugins/dsh/src/contract.test.ts +62 -0
- package/plugins/dsh/src/gate-runner.test.ts +100 -0
- package/plugins/dsh/src/gate-runner.ts +58 -0
- package/plugins/dsh/src/index.test.ts +97 -0
- package/plugins/dsh/src/index.ts +94 -0
- package/plugins/dsh/src/skills.test.ts +58 -0
- package/plugins/dsh/tsconfig.build.json +13 -0
- package/plugins/dsh/tsconfig.json +19 -0
- package/plugins/dsh/vitest.config.ts +8 -0
- package/plugins/opencode/package.json +1 -1
- package/plugins/opencode/scripts/prepack.cjs +1 -0
- package/plugins/opencode/skills/clipboard-vision/SKILL.md +47 -0
- package/plugins/opencode/skills/clipboard-vision/__tests__/clipboard-vision-distribution.test.cjs +65 -0
- package/plugins/opencode/skills/clipboard-vision/__tests__/clipboard-vision-security.test.cjs +185 -0
- package/plugins/opencode/skills/clipboard-vision/__tests__/clipboard-vision.Tests.ps1 +138 -0
- package/plugins/opencode/skills/clipboard-vision/__tests__/clipboard-vision.test.cjs +273 -0
- package/plugins/opencode/skills/clipboard-vision/describe-clipboard.ps1 +115 -0
- package/plugins/opencode/skills/clipboard-vision/describe-clipboard.sh +161 -0
- package/plugins/opencode/skills/clipboard-vision/scripts/clipboard-vision.ps1 +86 -0
- package/plugins/opencode/skills/clipboard-vision/scripts/clipboard-vision.sh +137 -0
- package/plugins/opencode/skills/delphi-review/.delphi-config.json.example +24 -27
- package/plugins/opencode/skills/delphi-review/AGENTS.md +12 -11
- package/plugins/opencode/skills/delphi-review/INSTALL.md +15 -17
- package/plugins/opencode/skills/delphi-review/SKILL.md +30 -29
- package/plugins/opencode/skills/delphi-review/opencode.json.delphi.example +6 -10
- package/plugins/opencode/skills/delphi-review/references/code-walkthrough.md +33 -49
- package/plugins/opencode/skills/delphi-review/references/requirements.md +66 -54
- package/plugins/opencode/skills/delphi-review/references/round-templates.md +7 -7
- package/plugins/opencode/skills/sprint-flow/AGENTS.md +4 -4
- package/plugins/opencode/skills/sprint-flow/SKILL.md +4 -4
- package/plugins/opencode/skills/sprint-flow/references/components/skill-invocations.md +2 -2
- package/plugins/opencode/skills/sprint-flow/references/force-levels.md +37 -35
- package/plugins/opencode/skills/sprint-flow/references/orchestration-rules.md +1 -1
- package/plugins/opencode/skills/sprint-flow/references/phase-1-prep.md +1 -1
- package/plugins/opencode/skills/sprint-flow/references/phase-2-design.md +24 -14
- package/plugins/opencode/skills/sprint-flow/references/phase-4-verify.md +6 -6
- package/plugins/opencode/skills/sprint-flow/references/phase-overview.md +2 -2
- package/plugins/opencode/skills/test-specification-alignment/AGENTS.md +3 -3
- package/plugins/qoder/plugin.json +1 -1
- package/plugins/qoder/skills/clipboard-vision/SKILL.md +47 -0
- package/plugins/qoder/skills/clipboard-vision/__tests__/clipboard-vision-distribution.test.cjs +65 -0
- package/plugins/qoder/skills/clipboard-vision/__tests__/clipboard-vision-security.test.cjs +185 -0
- package/plugins/qoder/skills/clipboard-vision/__tests__/clipboard-vision.Tests.ps1 +138 -0
- package/plugins/qoder/skills/clipboard-vision/__tests__/clipboard-vision.test.cjs +273 -0
- package/plugins/qoder/skills/clipboard-vision/clipboard-vision/SKILL.md +47 -0
- package/plugins/qoder/skills/clipboard-vision/clipboard-vision/__tests__/clipboard-vision-distribution.test.cjs +65 -0
- package/plugins/qoder/skills/clipboard-vision/clipboard-vision/__tests__/clipboard-vision-security.test.cjs +185 -0
- package/plugins/qoder/skills/clipboard-vision/clipboard-vision/__tests__/clipboard-vision.Tests.ps1 +138 -0
- package/plugins/qoder/skills/clipboard-vision/clipboard-vision/__tests__/clipboard-vision.test.cjs +273 -0
- package/plugins/qoder/skills/clipboard-vision/clipboard-vision/scripts/clipboard-vision.ps1 +86 -0
- package/plugins/qoder/skills/clipboard-vision/clipboard-vision/scripts/clipboard-vision.sh +137 -0
- package/plugins/qoder/skills/clipboard-vision/scripts/clipboard-vision.ps1 +86 -0
- package/plugins/qoder/skills/clipboard-vision/scripts/clipboard-vision.sh +137 -0
- package/plugins/qoder/skills/delphi-review/.delphi-config.json.example +3 -11
- package/plugins/qoder/skills/delphi-review/AGENTS.md +14 -16
- package/plugins/qoder/skills/delphi-review/INSTALL.md +12 -12
- package/plugins/qoder/skills/delphi-review/SKILL.md +58 -25
- package/plugins/qoder/skills/delphi-review/opencode.json.delphi.example +1 -1
- package/plugins/qoder/skills/delphi-review/references/code-walkthrough.md +33 -49
- package/plugins/qoder/skills/sprint-flow/AGENTS.md +4 -4
- package/plugins/qoder/skills/sprint-flow/SKILL.md +2 -2
- package/plugins/qoder/skills/sprint-flow/references/force-levels.md +38 -35
- package/plugins/qoder/skills/sprint-flow/references/phase-1-prep.md +1 -1
- package/plugins/qoder/skills/sprint-flow/references/phase-2-design.md +48 -6
- package/plugins/qoder/skills/sprint-flow/references/phase-4-verify.md +5 -6
- package/plugins/qoder/skills/test-specification-alignment/AGENTS.md +3 -3
- package/principles/AGENTS.md +3 -3
- package/scripts/__tests__/sync-package-content.test.js +30 -0
- package/scripts/delphi-external-review.cjs +194 -63
- package/scripts/sync-package-content.js +9 -2
- package/skills/clipboard-vision/SKILL.md +47 -0
- package/skills/clipboard-vision/__tests__/clipboard-vision-distribution.test.cjs +65 -0
- package/skills/clipboard-vision/__tests__/clipboard-vision-security.test.cjs +185 -0
- package/skills/clipboard-vision/__tests__/clipboard-vision.Tests.ps1 +138 -0
- package/skills/clipboard-vision/__tests__/clipboard-vision.test.cjs +273 -0
- package/skills/clipboard-vision/describe-clipboard.ps1 +115 -0
- package/skills/clipboard-vision/describe-clipboard.sh +161 -0
- package/skills/clipboard-vision/scripts/clipboard-vision.ps1 +86 -0
- package/skills/clipboard-vision/scripts/clipboard-vision.sh +137 -0
- package/skills/delphi-review/.delphi-config.json.example +24 -27
- package/skills/delphi-review/AGENTS.md +12 -11
- package/skills/delphi-review/INSTALL.md +15 -17
- package/skills/delphi-review/SKILL.md +30 -29
- package/skills/delphi-review/opencode.json.delphi.example +6 -10
- package/skills/delphi-review/references/code-walkthrough.md +33 -49
- package/skills/delphi-review/references/requirements.md +66 -54
- package/skills/delphi-review/references/round-templates.md +7 -7
- package/skills/sprint-flow/AGENTS.md +4 -4
- package/skills/sprint-flow/SKILL.md +4 -4
- package/skills/sprint-flow/references/components/skill-invocations.md +2 -2
- package/skills/sprint-flow/references/force-levels.md +37 -35
- package/skills/sprint-flow/references/orchestration-rules.md +1 -1
- package/skills/sprint-flow/references/phase-1-prep.md +1 -1
- package/skills/sprint-flow/references/phase-2-design.md +24 -14
- package/skills/sprint-flow/references/phase-4-verify.md +6 -6
- package/skills/sprint-flow/references/phase-overview.md +2 -2
- package/skills/test-specification-alignment/AGENTS.md +3 -3
- package/sprint-gate.sh +291 -0
package/lib/test-alignment.ts
CHANGED
|
@@ -198,16 +198,6 @@ export function parseSpecification(specPath: string): SpecificationMap {
|
|
|
198
198
|
// Step 2: parseTestFiles()
|
|
199
199
|
// ============================================================================
|
|
200
200
|
|
|
201
|
-
const REQ_ID_PATTERN = /REQ-[A-Z0-9]+-[A-Z0-9]+/;
|
|
202
|
-
|
|
203
|
-
function extractTag(text: string, tag: string): string | null {
|
|
204
|
-
// Match @tag value (single line extraction, stops at newline or */)
|
|
205
|
-
const regex = new RegExp('@' + tag.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '\\s+(.+?)(?:\\n|\\*\\/)', 's');
|
|
206
|
-
const match = text.match(regex);
|
|
207
|
-
if (!match) return null;
|
|
208
|
-
return match[1]!.trim();
|
|
209
|
-
}
|
|
210
|
-
|
|
211
201
|
function extractAllTags(text: string, tag: string): string[] {
|
|
212
202
|
const escapedTag = tag.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
213
203
|
const regex = new RegExp('@' + escapedTag + '\\s+(.+?)(?:\\n|\\*\\/)', 'gs');
|
|
@@ -396,7 +386,7 @@ export function verifyAlignment(
|
|
|
396
386
|
// Collect all requirement IDs and acceptance criteria IDs from spec
|
|
397
387
|
const allReqIds = new Set<string>();
|
|
398
388
|
const allAcIds = new Set<string>();
|
|
399
|
-
|
|
389
|
+
const totalEdgeCases = 0;
|
|
400
390
|
|
|
401
391
|
for (const req of specMap.requirements) {
|
|
402
392
|
allReqIds.add(req.id);
|
|
@@ -583,7 +573,7 @@ export function runFullAlignment(options: AlignmentOptions): TestAlignmentReport
|
|
|
583
573
|
let spec: SpecificationMap;
|
|
584
574
|
try {
|
|
585
575
|
spec = parseSpecification(specPath);
|
|
586
|
-
} catch (e
|
|
576
|
+
} catch (e) {
|
|
587
577
|
return {
|
|
588
578
|
alignment_status: 'BLOCKED',
|
|
589
579
|
phase: 0,
|
|
@@ -593,7 +583,7 @@ export function runFullAlignment(options: AlignmentOptions): TestAlignmentReport
|
|
|
593
583
|
timestamp: new Date().toISOString(),
|
|
594
584
|
misaligned_tests: [],
|
|
595
585
|
anti_pattern_detected: false,
|
|
596
|
-
errors: [`Failed to parse specification: ${e.message}`],
|
|
586
|
+
errors: [`Failed to parse specification: ${e instanceof Error ? e.message : String(e)}`],
|
|
597
587
|
};
|
|
598
588
|
}
|
|
599
589
|
|
package/lib/update-hooks.js
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* @intent Sync latest hook versions from xp-gate package to project or global directory
|
|
4
4
|
* @covers AC-265-01, AC-265-02, AC-265-03, AC-265-04
|
|
5
5
|
*/
|
|
6
|
-
const fs = require('fs');
|
|
7
|
-
const path = require('path');
|
|
8
|
-
const { GLOBAL_HOOKS_DIR, GLOBAL_ADAPTERS_DIR } = require('./shared-paths.js');
|
|
6
|
+
const fs = require('node:fs');
|
|
7
|
+
const path = require('node:path');
|
|
8
|
+
const { GLOBAL_HOOKS_DIR, GLOBAL_ADAPTERS_DIR, GLOBAL_MODULES_DIR, CONFIG_DIR } = require('./shared-paths.js');
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Get the xp-gate package root directory (src/npm-package/).
|
|
@@ -97,6 +97,17 @@ function detectLocalModifications(srcDir, hooksDestDir, adaptersDestDir) {
|
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
// Check sprint-gate.sh in the hooks directory (Gate MS resolves it there)
|
|
101
|
+
const sprintGateSrc = path.join(srcDir, 'sprint-gate.sh');
|
|
102
|
+
const sprintGateDest = path.join(hooksDestDir, 'sprint-gate.sh');
|
|
103
|
+
if (fs.existsSync(sprintGateDest) && fs.existsSync(sprintGateSrc)) {
|
|
104
|
+
const srcContent = fs.readFileSync(sprintGateSrc, 'utf8');
|
|
105
|
+
const destContent = fs.readFileSync(sprintGateDest, 'utf8');
|
|
106
|
+
if (srcContent !== destContent) {
|
|
107
|
+
modified.push('sprint-gate.sh');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
100
111
|
return modified;
|
|
101
112
|
}
|
|
102
113
|
|
|
@@ -152,6 +163,21 @@ function copyHooks(srcDir, destDir, dryRun, noBackup) {
|
|
|
152
163
|
const dest = path.join(destDir, hook);
|
|
153
164
|
atomicCopyFile(src, dest, dryRun, noBackup, hook);
|
|
154
165
|
});
|
|
166
|
+
const libSrcDir = path.join(hooksSrcDir, 'lib');
|
|
167
|
+
if (fs.existsSync(libSrcDir)) {
|
|
168
|
+
fs.readdirSync(libSrcDir, { withFileTypes: true })
|
|
169
|
+
.filter(entry => entry.isFile())
|
|
170
|
+
.forEach(entry => {
|
|
171
|
+
const label = `lib/${entry.name}`;
|
|
172
|
+
atomicCopyFile(
|
|
173
|
+
path.join(libSrcDir, entry.name),
|
|
174
|
+
path.join(destDir, label),
|
|
175
|
+
dryRun,
|
|
176
|
+
noBackup,
|
|
177
|
+
label
|
|
178
|
+
);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
155
181
|
}
|
|
156
182
|
|
|
157
183
|
/**
|
|
@@ -190,7 +216,7 @@ function copyAdapters(srcDir, destDir, dryRun, noBackup) {
|
|
|
190
216
|
function copyGateScripts(srcDir, destDir, dryRun, noBackup) {
|
|
191
217
|
if (!fs.existsSync(srcDir)) return;
|
|
192
218
|
fs.readdirSync(srcDir).forEach(f => {
|
|
193
|
-
if (
|
|
219
|
+
if (f.startsWith('gate-') && f.endsWith('.sh')) {
|
|
194
220
|
const src = path.join(srcDir, f);
|
|
195
221
|
const dest = path.join(destDir, f);
|
|
196
222
|
atomicCopyFile(src, dest, dryRun, noBackup, f);
|
|
@@ -198,31 +224,92 @@ function copyGateScripts(srcDir, destDir, dryRun, noBackup) {
|
|
|
198
224
|
});
|
|
199
225
|
}
|
|
200
226
|
|
|
227
|
+
/**
|
|
228
|
+
* Copy sprint-gate.sh from package root to the hooks directory.
|
|
229
|
+
* The pre-push Gate MS resolves it at $(dirname "$0")/sprint-gate.sh, i.e.
|
|
230
|
+
* alongside pre-commit/pre-push — NOT the adapters directory.
|
|
231
|
+
* @param {string} srcDir - Package root directory
|
|
232
|
+
* @param {string} hooksDestDir - Destination hooks directory
|
|
233
|
+
* @param {boolean} dryRun
|
|
234
|
+
* @param {boolean} noBackup
|
|
235
|
+
*/
|
|
236
|
+
function copySprintGate(srcDir, hooksDestDir, dryRun, noBackup) {
|
|
237
|
+
const src = path.join(srcDir, 'sprint-gate.sh');
|
|
238
|
+
if (!fs.existsSync(src)) return;
|
|
239
|
+
atomicCopyFile(src, path.join(hooksDestDir, 'sprint-gate.sh'), dryRun, noBackup, 'sprint-gate.sh');
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Copy quality gate modules (principles, mutation, mock-policy, build-integrity)
|
|
244
|
+
* into the modules directory. These ship in the npm package but were never
|
|
245
|
+
* installed by an already-initialized global setup, so update-hooks must
|
|
246
|
+
* re-deploy them to repair Gate 9/10 (build-integrity) on existing installs.
|
|
247
|
+
* @param {string} srcDir - Package root directory
|
|
248
|
+
* @param {string} modulesDestDir - Destination modules directory
|
|
249
|
+
* @param {boolean} dryRun
|
|
250
|
+
* @param {boolean} noBackup
|
|
251
|
+
*/
|
|
252
|
+
const MODULES = ['principles', 'mutation', 'mock-policy', 'build-integrity'];
|
|
253
|
+
function copyModules(srcDir, modulesDestDir, dryRun, noBackup) {
|
|
254
|
+
MODULES.forEach(module => {
|
|
255
|
+
const srcDirPath = path.join(srcDir, module);
|
|
256
|
+
if (!fs.existsSync(srcDirPath)) return;
|
|
257
|
+
const destDirPath = path.join(modulesDestDir, module);
|
|
258
|
+
fs.mkdirSync(destDirPath, { recursive: true });
|
|
259
|
+
fs.readdirSync(srcDirPath).forEach(entry => {
|
|
260
|
+
const srcEntry = path.join(srcDirPath, entry);
|
|
261
|
+
const destEntry = path.join(destDirPath, entry);
|
|
262
|
+
const stats = fs.statSync(srcEntry);
|
|
263
|
+
if (stats.isDirectory()) {
|
|
264
|
+
copyRecursiveDir(srcEntry, destEntry, dryRun, noBackup, module);
|
|
265
|
+
} else if (!dryRun) {
|
|
266
|
+
atomicCopyFile(srcEntry, destEntry, dryRun, noBackup, `${module}/${entry}`);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
if (!dryRun) console.log(` ${module}/ -> ${modulesDestDir}/${module}/`);
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function copyRecursiveDir(src, dest, dryRun, noBackup, label) {
|
|
274
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
275
|
+
fs.readdirSync(src).forEach(entry => {
|
|
276
|
+
const srcEntry = path.join(src, entry);
|
|
277
|
+
const destEntry = path.join(dest, entry);
|
|
278
|
+
if (fs.statSync(srcEntry).isDirectory()) {
|
|
279
|
+
copyRecursiveDir(srcEntry, destEntry, dryRun, noBackup, label);
|
|
280
|
+
} else {
|
|
281
|
+
atomicCopyFile(srcEntry, destEntry, dryRun, noBackup, `${label}/${entry}`);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
|
|
201
286
|
function resolveSrcDir() {
|
|
202
|
-
return
|
|
287
|
+
return module.exports?.getPackageRoot
|
|
203
288
|
? module.exports.getPackageRoot()
|
|
204
289
|
: getPackageRoot();
|
|
205
290
|
}
|
|
206
291
|
|
|
207
292
|
function resolveDirs(global) {
|
|
208
|
-
if (global) return { hooksDestDir: GLOBAL_HOOKS_DIR, adaptersDestDir: GLOBAL_ADAPTERS_DIR };
|
|
209
|
-
return { hooksDestDir: getProjectHooksDir(), adaptersDestDir: path.join(process.cwd(), 'githooks') };
|
|
293
|
+
if (global) return { hooksDestDir: GLOBAL_HOOKS_DIR, adaptersDestDir: GLOBAL_ADAPTERS_DIR, modulesDestDir: GLOBAL_MODULES_DIR };
|
|
294
|
+
return { hooksDestDir: getProjectHooksDir(), adaptersDestDir: path.join(process.cwd(), 'githooks'), modulesDestDir: path.join(process.cwd(), '.xp-gate', 'modules') };
|
|
210
295
|
}
|
|
211
296
|
|
|
212
|
-
function ensureDirsExist(adaptersDestDir, hooksDestDir) {
|
|
297
|
+
function ensureDirsExist(adaptersDestDir, hooksDestDir, modulesDestDir) {
|
|
213
298
|
fs.mkdirSync(hooksDestDir, { recursive: true });
|
|
214
299
|
fs.mkdirSync(adaptersDestDir, { recursive: true });
|
|
215
300
|
fs.mkdirSync(path.join(adaptersDestDir, 'adapters'), { recursive: true });
|
|
301
|
+
if (modulesDestDir) fs.mkdirSync(modulesDestDir, { recursive: true });
|
|
216
302
|
}
|
|
217
303
|
|
|
218
304
|
function printUpdateHeader(opts) {
|
|
219
|
-
const { global, srcDir, hooksDestDir, adaptersDestDir, scope, dryRun } = opts;
|
|
305
|
+
const { global, srcDir, hooksDestDir, adaptersDestDir, modulesDestDir, scope, dryRun } = opts;
|
|
220
306
|
console.log(`XP-Gate Update Hooks`);
|
|
221
307
|
console.log(`====================`);
|
|
222
308
|
console.log(`Mode: ${global ? 'Global' : 'Local'}`);
|
|
223
309
|
console.log(`Source: ${srcDir}`);
|
|
224
310
|
console.log(`Hooks destination: ${hooksDestDir}`);
|
|
225
311
|
console.log(`Adapters destination: ${adaptersDestDir}`);
|
|
312
|
+
if (modulesDestDir) console.log(`Modules destination: ${modulesDestDir}`);
|
|
226
313
|
console.log(`Scope: ${scope}`);
|
|
227
314
|
if (dryRun) console.log(`Dry run: yes (no files will be modified)`);
|
|
228
315
|
console.log('');
|
|
@@ -233,13 +320,15 @@ function checkLocalModifications(srcDir, hooksDestDir, adaptersDestDir, force, d
|
|
|
233
320
|
const localMods = detectLocalModifications(srcDir, hooksDestDir, adaptersDestDir);
|
|
234
321
|
if (localMods.length === 0) return 0;
|
|
235
322
|
console.warn(`[WARN] Detected ${localMods.length} locally modified file(s):`);
|
|
236
|
-
localMods.forEach(f =>
|
|
323
|
+
localMods.forEach(f => {
|
|
324
|
+
console.warn(` - ${f}`);
|
|
325
|
+
});
|
|
237
326
|
console.warn('Use --force to overwrite, or manually backup first.');
|
|
238
327
|
return 1;
|
|
239
328
|
}
|
|
240
329
|
|
|
241
330
|
function copyByScope(opts) {
|
|
242
|
-
const { scope, srcDir, hooksDestDir, adaptersDestDir, dryRun, noBackup } = opts;
|
|
331
|
+
const { scope, srcDir, hooksDestDir, adaptersDestDir, modulesDestDir, dryRun, noBackup } = opts;
|
|
243
332
|
if (scope === 'all' || scope === 'hooks') {
|
|
244
333
|
printInfo('hooks');
|
|
245
334
|
copyHooks(srcDir, hooksDestDir, dryRun, noBackup);
|
|
@@ -251,6 +340,27 @@ function copyByScope(opts) {
|
|
|
251
340
|
if (scope === 'all') {
|
|
252
341
|
printInfo('gate scripts');
|
|
253
342
|
copyGateScripts(srcDir, adaptersDestDir, dryRun, noBackup);
|
|
343
|
+
if (modulesDestDir) {
|
|
344
|
+
printInfo('modules');
|
|
345
|
+
copyModules(srcDir, modulesDestDir, dryRun, noBackup);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
if (scope === 'all' || scope === 'hooks') {
|
|
349
|
+
copySprintGate(srcDir, hooksDestDir, dryRun, noBackup);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function warnMissingModuleDeps(global, dryRun) {
|
|
354
|
+
if (!global || dryRun) return;
|
|
355
|
+
// Copied gate modules (e.g. mock-policy) import js-yaml/zod installed into
|
|
356
|
+
// <CONFIG_DIR>/node_modules by setup-global. If absent (e.g. an install made
|
|
357
|
+
// before that step existed), Gate ML would crash at push — guide the user to
|
|
358
|
+
// re-run setup-global rather than silently failing.
|
|
359
|
+
const depsDir = path.join(CONFIG_DIR, 'node_modules', 'js-yaml');
|
|
360
|
+
if (!fs.existsSync(depsDir)) {
|
|
361
|
+
console.warn('\n[warn] Global quality-gate module runtime deps not found.');
|
|
362
|
+
console.warn(` Expected: ${path.join(CONFIG_DIR, 'node_modules')}`);
|
|
363
|
+
console.warn(' Run `xp-gate setup-global` once to install them (Gate ML needs js-yaml/zod).');
|
|
254
364
|
}
|
|
255
365
|
}
|
|
256
366
|
|
|
@@ -262,15 +372,16 @@ function printInfo(label) { console.log(`Updating ${label}...`); }
|
|
|
262
372
|
function updateHooks(options = {}) {
|
|
263
373
|
const { global = false, force = false, dryRun = false, noBackup = false, scope = 'all' } = options;
|
|
264
374
|
const srcDir = resolveSrcDir();
|
|
265
|
-
const { hooksDestDir, adaptersDestDir } = resolveDirs(global);
|
|
375
|
+
const { hooksDestDir, adaptersDestDir, modulesDestDir } = resolveDirs(global);
|
|
266
376
|
|
|
267
|
-
ensureDirsExist(adaptersDestDir, hooksDestDir);
|
|
268
|
-
printUpdateHeader({ global, srcDir, hooksDestDir, adaptersDestDir, scope, dryRun });
|
|
377
|
+
ensureDirsExist(adaptersDestDir, hooksDestDir, modulesDestDir);
|
|
378
|
+
printUpdateHeader({ global, srcDir, hooksDestDir, adaptersDestDir, modulesDestDir, scope, dryRun });
|
|
269
379
|
|
|
270
380
|
const modCheck = checkLocalModifications(srcDir, hooksDestDir, adaptersDestDir, force, dryRun);
|
|
271
381
|
if (modCheck !== 0) return modCheck;
|
|
272
382
|
|
|
273
|
-
copyByScope({ scope, srcDir, hooksDestDir, adaptersDestDir, dryRun, noBackup });
|
|
383
|
+
copyByScope({ scope, srcDir, hooksDestDir, adaptersDestDir, modulesDestDir, dryRun, noBackup });
|
|
384
|
+
warnMissingModuleDeps(global, dryRun);
|
|
274
385
|
|
|
275
386
|
if (!dryRun) console.log('\nUpdate complete!');
|
|
276
387
|
return 0;
|
|
@@ -282,6 +393,9 @@ module.exports = {
|
|
|
282
393
|
copyHooks,
|
|
283
394
|
copyAdapters,
|
|
284
395
|
copyGateScripts,
|
|
396
|
+
copySprintGate,
|
|
397
|
+
copyModules,
|
|
398
|
+
warnMissingModuleDeps,
|
|
285
399
|
atomicCopyFile,
|
|
286
400
|
getPackageRoot,
|
|
287
401
|
getProjectHooksDir,
|
package/mock-policy/AGENTS.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SRC/MOCK-POLICY KNOWLEDGE BASE
|
|
2
2
|
|
|
3
|
-
**Generated:** 2026-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-08-30
|
|
4
|
+
**Commit:** 0848858
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.19.1.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.
|
|
@@ -88,7 +88,7 @@ npx vitest run src/mock-policy/__tests__/integration.test.ts
|
|
|
88
88
|
|
|
89
89
|
## NOTES
|
|
90
90
|
- Gate M3 is invoked by pre-push hook after Gate M (mutation) and Gate M2 (AI test detection)
|
|
91
|
-
-
|
|
91
|
+
- code walkthrough scope: no hard file-count or LOC threshold; large diffs require complete review or user-directed splitting, never a size-based bypass
|
|
92
92
|
- Coverage exclude: src/mock-policy/ controlled by vitest config
|
|
93
93
|
- The integration test creates real temporary directories under os.tmpdir()
|
|
94
94
|
- Dependencies on: `src/mutation/detect-ai-test.ts` (detectTestLayer)
|
|
@@ -271,9 +271,7 @@ describe('runGateM3', () => {
|
|
|
271
271
|
// ---------------------------------------------------------------------------
|
|
272
272
|
describe('main', () => {
|
|
273
273
|
let tmpDir: string;
|
|
274
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
275
274
|
let consoleErrorSpy: any;
|
|
276
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
277
275
|
let consoleLogSpy: any;
|
|
278
276
|
|
|
279
277
|
beforeEach(() => {
|
|
@@ -335,7 +333,6 @@ describe('main', () => {
|
|
|
335
333
|
const exitCode = await main([testFile]);
|
|
336
334
|
|
|
337
335
|
const logCalls: string[] = consoleLogSpy.mock.calls.map(
|
|
338
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
339
336
|
(c: any[]) => String(c[0]),
|
|
340
337
|
);
|
|
341
338
|
expect(logCalls.some((msg) => msg.includes('Gate M3'))).toBe(true);
|
|
@@ -357,7 +354,6 @@ describe('main', () => {
|
|
|
357
354
|
await main([testFile]);
|
|
358
355
|
|
|
359
356
|
const logCalls: string[] = consoleLogSpy.mock.calls.map(
|
|
360
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
361
357
|
(c: any[]) => String(c[0]),
|
|
362
358
|
);
|
|
363
359
|
const hasPassLabel = logCalls.some(
|
|
@@ -373,7 +369,6 @@ describe('main', () => {
|
|
|
373
369
|
await main([testFile]);
|
|
374
370
|
|
|
375
371
|
const logCalls: string[] = consoleLogSpy.mock.calls.map(
|
|
376
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
377
372
|
(c: any[]) => String(c[0]),
|
|
378
373
|
);
|
|
379
374
|
const hasFileCount = logCalls.some(
|
|
@@ -196,9 +196,12 @@ describe('resolveToRealPath', () => {
|
|
|
196
196
|
// ---------------------------------------------------------------------------
|
|
197
197
|
describe('loadExternalDependencies', () => {
|
|
198
198
|
let tmpDir: string;
|
|
199
|
+
let tmpCounter = 0;
|
|
199
200
|
|
|
200
201
|
beforeEach(() => {
|
|
201
|
-
|
|
202
|
+
// Monotonic counter avoids Date.now() collisions when tests run fast
|
|
203
|
+
tmpCounter += 1;
|
|
204
|
+
tmpDir = join(tmpdir(), `scope-scanner-test-${process.pid}-${tmpCounter}`);
|
|
202
205
|
mkdirSync(tmpDir, { recursive: true });
|
|
203
206
|
});
|
|
204
207
|
|
|
@@ -361,9 +364,12 @@ describe('classifyDependency', () => {
|
|
|
361
364
|
// ---------------------------------------------------------------------------
|
|
362
365
|
describe('scanProjectScope', () => {
|
|
363
366
|
let tmpDir: string;
|
|
367
|
+
let tmpCounter = 0;
|
|
364
368
|
|
|
365
369
|
beforeEach(() => {
|
|
366
|
-
|
|
370
|
+
// Monotonic counter avoids Date.now() collisions when tests run fast
|
|
371
|
+
tmpCounter += 1;
|
|
372
|
+
tmpDir = join(tmpdir(), `scope-scanner-integration-${process.pid}-${tmpCounter}`);
|
|
367
373
|
mkdirSync(tmpDir, { recursive: true });
|
|
368
374
|
|
|
369
375
|
// Create a real project structure
|
package/mutation/AGENTS.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SRC/MUTATION KNOWLEDGE BASE
|
|
2
2
|
|
|
3
|
-
**Generated:** 2026-
|
|
4
|
-
**Commit:**
|
|
3
|
+
**Generated:** 2026-08-30
|
|
4
|
+
**Commit:** 0848858
|
|
5
5
|
**Branch:** main
|
|
6
|
-
**Version:** 0.
|
|
6
|
+
**Version:** 0.19.1.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.
|