xp-gate 0.5.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 +192 -0
- package/adapters/cpp.sh +76 -0
- package/adapters/dart.sh +41 -0
- package/adapters/flutter.sh +41 -0
- package/adapters/go.sh +59 -0
- package/adapters/iac.sh +189 -0
- package/adapters/java.sh +191 -0
- package/adapters/kotlin.sh +77 -0
- package/adapters/objectivec.sh +38 -0
- package/adapters/powershell.sh +138 -0
- package/adapters/python.sh +104 -0
- package/adapters/shell.sh +55 -0
- package/adapters/swift.sh +44 -0
- package/adapters/typescript.sh +61 -0
- package/bin/xp-gate.js +157 -0
- package/hooks/adapter-common.sh +192 -0
- package/hooks/pre-commit +1667 -0
- package/hooks/pre-push +395 -0
- package/lib/__tests__/detect-deps.test.js +209 -0
- package/lib/__tests__/doctor.test.js +448 -0
- package/lib/__tests__/download-skill.test.js +281 -0
- package/lib/__tests__/init.test.js +327 -0
- package/lib/__tests__/install-skill.test.js +326 -0
- package/lib/__tests__/migrate.test.js +212 -0
- package/lib/__tests__/rollback.test.js +183 -0
- package/lib/__tests__/ui-detector.test.ts +200 -0
- package/lib/__tests__/uninstall-skill.test.js +189 -0
- package/lib/__tests__/uninstall.test.js +589 -0
- package/lib/__tests__/update-skill.test.js +276 -0
- package/lib/detect-deps.js +157 -0
- package/lib/doctor.js +370 -0
- package/lib/download-skill.js +96 -0
- package/lib/init.js +367 -0
- package/lib/install-skill.js +184 -0
- package/lib/migrate.js +120 -0
- package/lib/rollback.js +78 -0
- package/lib/ui-detector.ts +99 -0
- package/lib/uninstall-skill.js +69 -0
- package/lib/uninstall.js +401 -0
- package/lib/update-skill.js +90 -0
- package/package.json +39 -0
- package/plugins/claude-code/.claude-plugin/plugin.json +21 -0
- package/plugins/claude-code/bin/delphi-review-guard.sh +68 -0
- package/plugins/claude-code/bin/xp-gate-check +47 -0
- package/plugins/claude-code/hooks/hooks.json +37 -0
- package/skills/delphi-review/.delphi-config.json.example +45 -0
- package/skills/delphi-review/AGENTS.md +54 -0
- package/skills/delphi-review/INSTALL.md +152 -0
- package/skills/delphi-review/SKILL.md +371 -0
- package/skills/delphi-review/evals/evals.json +82 -0
- package/skills/delphi-review/opencode.json.delphi.example +56 -0
- package/skills/delphi-review/references/code-walkthrough.md +486 -0
- package/skills/ralph-loop/SKILL.md +330 -0
- package/skills/ralph-loop/evals/evals.json +311 -0
- package/skills/ralph-loop/evolution-history.json +59 -0
- package/skills/ralph-loop/evolution-log.md +16 -0
- package/skills/ralph-loop/references/components/memory.md +55 -0
- package/skills/ralph-loop/references/components/middleware.md +54 -0
- package/skills/ralph-loop/references/components/skill-invocations.md +39 -0
- package/skills/ralph-loop/references/components/system-prompt.md +24 -0
- package/skills/ralph-loop/references/components/tool-descriptions.md +32 -0
- package/skills/ralph-loop/references/phase-2-build-ralph.md +89 -0
- package/skills/ralph-loop/templates/progress-log.md +36 -0
- package/skills/sprint-flow/SKILL.md +600 -0
- package/skills/sprint-flow/evals/evals.json +78 -0
- package/skills/sprint-flow/evolution-history.json +39 -0
- package/skills/sprint-flow/evolution-log.md +23 -0
- package/skills/sprint-flow/references/components/memory.md +87 -0
- package/skills/sprint-flow/references/components/middleware.md +72 -0
- package/skills/sprint-flow/references/components/skill-invocations.md +104 -0
- package/skills/sprint-flow/references/components/system-prompt.md +27 -0
- package/skills/sprint-flow/references/components/tool-descriptions.md +96 -0
- package/skills/sprint-flow/references/phase-0-think.md +115 -0
- package/skills/sprint-flow/references/phase-1-plan.md +178 -0
- package/skills/sprint-flow/references/phase-2-build.md +198 -0
- package/skills/sprint-flow/references/phase-3-review.md +213 -0
- package/skills/sprint-flow/references/phase-4-uat.md +125 -0
- package/skills/sprint-flow/references/phase-5-feedback.md +100 -0
- package/skills/sprint-flow/references/phase-6-ship.md +193 -0
- package/skills/sprint-flow/references/phase-7-land.md +140 -0
- package/skills/sprint-flow/references/phase-8-cleanup.md +192 -0
- package/skills/sprint-flow/templates/emergent-issues-template.md +120 -0
- package/skills/sprint-flow/templates/pain-document-template.md +115 -0
- package/skills/sprint-flow/templates/sprint-summary-template.md +120 -0
- package/skills/test-specification-alignment/AGENTS.md +59 -0
- package/skills/test-specification-alignment/SKILL.md +605 -0
- package/skills/test-specification-alignment/evals/evals.json +75 -0
- package/skills/test-specification-alignment/references/alignment-verification-algorithm.md +493 -0
- package/skills/test-specification-alignment/references/phase2-constraint-enforcement.md +431 -0
- package/skills/test-specification-alignment/references/specification-format.md +348 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# TypeScript adapter for quality gates
|
|
4
|
+
|
|
5
|
+
run_static_analysis() {
|
|
6
|
+
if command -v npx >/dev/null 2>&1; then
|
|
7
|
+
echo "Running TypeScript static analysis..."
|
|
8
|
+
npx tsc --noEmit
|
|
9
|
+
return $?
|
|
10
|
+
else
|
|
11
|
+
echo "npx not available, skipping TypeScript static analysis"
|
|
12
|
+
return 0
|
|
13
|
+
fi
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
run_lint() {
|
|
17
|
+
if command -v npx >/dev/null 2>&1; then
|
|
18
|
+
echo "Running TypeScript linting..."
|
|
19
|
+
npx eslint . --ext .ts,.tsx
|
|
20
|
+
return $?
|
|
21
|
+
else
|
|
22
|
+
echo "npx not available, skipping TypeScript linting"
|
|
23
|
+
return 0
|
|
24
|
+
fi
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
run_tests() {
|
|
28
|
+
if command -v npx >/dev/null 2>&1; then
|
|
29
|
+
echo "Running TypeScript tests..."
|
|
30
|
+
if npx vitest --version >/dev/null 2>&1; then
|
|
31
|
+
npx vitest run
|
|
32
|
+
elif npx jest --version >/dev/null 2>&1; then
|
|
33
|
+
npx jest --passWithNoTests
|
|
34
|
+
else
|
|
35
|
+
echo "No test runner available (vitest or jest required)"
|
|
36
|
+
return 1
|
|
37
|
+
fi
|
|
38
|
+
return $?
|
|
39
|
+
else
|
|
40
|
+
echo "npx not available, skipping TypeScript tests"
|
|
41
|
+
return 0
|
|
42
|
+
fi
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
run_coverage() {
|
|
46
|
+
if command -v npx >/dev/null 2>&1; then
|
|
47
|
+
echo "Running TypeScript coverage..."
|
|
48
|
+
if npx vitest --version >/dev/null 2>&1; then
|
|
49
|
+
npx vitest run --coverage
|
|
50
|
+
elif npx jest --version >/dev/null 2>&1; then
|
|
51
|
+
npx jest --coverage
|
|
52
|
+
else
|
|
53
|
+
echo "No test runner available for coverage"
|
|
54
|
+
return 1
|
|
55
|
+
fi
|
|
56
|
+
return $?
|
|
57
|
+
else
|
|
58
|
+
echo "npx not available, skipping TypeScript coverage"
|
|
59
|
+
return 0
|
|
60
|
+
fi
|
|
61
|
+
}
|
package/bin/xp-gate.js
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { init } = require('../lib/init.js');
|
|
3
|
+
const { installSkill } = require('../lib/install-skill.js');
|
|
4
|
+
const { updateSkill } = require('../lib/update-skill.js');
|
|
5
|
+
const { uninstallSkill } = require('../lib/uninstall-skill.js');
|
|
6
|
+
const { uninstall } = require('../lib/uninstall.js');
|
|
7
|
+
const { doctor } = require('../lib/doctor.js');
|
|
8
|
+
const { checkDeps } = require('../lib/detect-deps.js');
|
|
9
|
+
const { migrate } = require('../lib/migrate.js');
|
|
10
|
+
|
|
11
|
+
const COMMANDS = {
|
|
12
|
+
'init': {
|
|
13
|
+
description: 'Initialize xp-gate (use --global for all projects)',
|
|
14
|
+
fn: init,
|
|
15
|
+
usage: 'xp-gate init [--global]'
|
|
16
|
+
},
|
|
17
|
+
'setup-global': {
|
|
18
|
+
description: 'Set up xp-gate globally for all git projects',
|
|
19
|
+
fn: init,
|
|
20
|
+
usage: 'xp-gate setup-global'
|
|
21
|
+
},
|
|
22
|
+
'install-skill': {
|
|
23
|
+
description: 'Install a xp-gate skill from GitHub',
|
|
24
|
+
fn: installSkill,
|
|
25
|
+
usage: 'xp-gate install-skill <name>[@<version>] [--offline] [--verbose] [--force]'
|
|
26
|
+
},
|
|
27
|
+
'update-skill': {
|
|
28
|
+
description: 'Update installed skill(s)',
|
|
29
|
+
fn: updateSkill,
|
|
30
|
+
usage: 'xp-gate update-skill [<name>] [--all] [--check]'
|
|
31
|
+
},
|
|
32
|
+
'uninstall-skill': {
|
|
33
|
+
description: 'Uninstall a xp-gate skill',
|
|
34
|
+
fn: uninstallSkill,
|
|
35
|
+
usage: 'xp-gate uninstall-skill <name> [--force]'
|
|
36
|
+
},
|
|
37
|
+
'uninstall': {
|
|
38
|
+
description: 'Uninstall xp-gate (reverse of init)',
|
|
39
|
+
fn: uninstall,
|
|
40
|
+
usage: 'xp-gate uninstall [--dry-run] [--force] [--local|--global]'
|
|
41
|
+
},
|
|
42
|
+
'migrate': {
|
|
43
|
+
description: 'Migrate from v0.4.x (GitHub Packages) to v0.5.x (public npm)',
|
|
44
|
+
fn: migrate,
|
|
45
|
+
usage: 'xp-gate migrate [--dry-run]'
|
|
46
|
+
},
|
|
47
|
+
'doctor': {
|
|
48
|
+
description: 'Diagnose xp-gate installation health',
|
|
49
|
+
fn: doctor,
|
|
50
|
+
usage: 'xp-gate doctor [--fix]'
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
function printHelp() {
|
|
55
|
+
console.log('xp-gate - AI development workflow tool');
|
|
56
|
+
console.log('');
|
|
57
|
+
console.log('Usage: xp-gate <command> [options]');
|
|
58
|
+
console.log('');
|
|
59
|
+
console.log('Commands:');
|
|
60
|
+
for (const [name, cmd] of Object.entries(COMMANDS)) {
|
|
61
|
+
console.log(` ${name.padEnd(16)} ${cmd.description}`);
|
|
62
|
+
}
|
|
63
|
+
console.log('');
|
|
64
|
+
console.log('Options:');
|
|
65
|
+
console.log(' --version Show version');
|
|
66
|
+
console.log(' --help Show this help');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function main() {
|
|
70
|
+
const args = process.argv.slice(2);
|
|
71
|
+
|
|
72
|
+
if (args.includes('--version')) {
|
|
73
|
+
const pkg = require('../package.json');
|
|
74
|
+
console.log(`xp-gate v${pkg.version}`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (args.includes('--help') || args.length === 0) {
|
|
79
|
+
printHelp();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const command = args[0];
|
|
84
|
+
const subargs = args.slice(1);
|
|
85
|
+
|
|
86
|
+
if (command === 'init' || command === 'setup-global') {
|
|
87
|
+
const initArgs = command === 'setup-global' ? ['--global'] : subargs;
|
|
88
|
+
init(initArgs).then(code => process.exit(code));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (command === 'install-skill') {
|
|
93
|
+
const name = subargs[0];
|
|
94
|
+
if (!name) {
|
|
95
|
+
console.error('Error: Skill name required');
|
|
96
|
+
console.error('Usage: xp-gate install-skill <name>[@<version>]');
|
|
97
|
+
process.exit(1);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const options = parseOptions(subargs.slice(1));
|
|
101
|
+
installSkill(name, options).then(code => process.exit(code));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (command === 'update-skill') {
|
|
106
|
+
const name = subargs[0];
|
|
107
|
+
const options = parseOptions(subargs.slice(1));
|
|
108
|
+
updateSkill(name, options).then(code => process.exit(code));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (command === 'uninstall-skill') {
|
|
113
|
+
const name = subargs[0];
|
|
114
|
+
if (!name) {
|
|
115
|
+
console.error('Error: Skill name required');
|
|
116
|
+
console.error('Usage: xp-gate uninstall-skill <name>');
|
|
117
|
+
process.exit(1);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const options = parseOptions(subargs.slice(1));
|
|
121
|
+
uninstallSkill(name, options).then(code => process.exit(code));
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (command === 'uninstall') {
|
|
126
|
+
uninstall(subargs).then(code => process.exit(code));
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (command === 'migrate') {
|
|
131
|
+
migrate(subargs).then(code => process.exit(code));
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (command === 'doctor') {
|
|
136
|
+
doctor(subargs).then(code => process.exit(code));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
console.error(`Unknown command: ${command}`);
|
|
141
|
+
printHelp();
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function parseOptions(args) {
|
|
146
|
+
const options = { offline: false, verbose: false, force: false, all: false, check: false };
|
|
147
|
+
for (const arg of args) {
|
|
148
|
+
if (arg === '--offline') options.offline = true;
|
|
149
|
+
if (arg === '--verbose') options.verbose = true;
|
|
150
|
+
if (arg === '--force') options.force = true;
|
|
151
|
+
if (arg === '--all') options.all = true;
|
|
152
|
+
if (arg === '--check') options.check = true;
|
|
153
|
+
}
|
|
154
|
+
return options;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
main();
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Common adapter functions for language detection and routing
|
|
4
|
+
|
|
5
|
+
detect_project_lang() {
|
|
6
|
+
if [[ -f "tsconfig.json" ]]; then
|
|
7
|
+
echo "typescript"
|
|
8
|
+
elif [[ -f "pyproject.toml" ]] || [[ -f "requirements.txt" ]] || [[ -f "setup.py" ]]; then
|
|
9
|
+
echo "python"
|
|
10
|
+
elif [[ -f "go.mod" ]]; then
|
|
11
|
+
echo "go"
|
|
12
|
+
elif [[ -f "build.gradle" ]] || [[ -f "build.gradle.kts" ]]; then
|
|
13
|
+
if [[ -n "$(find . -name "*.kt" -type f | head -n 1)" ]]; then
|
|
14
|
+
echo "kotlin"
|
|
15
|
+
else
|
|
16
|
+
echo "java"
|
|
17
|
+
fi
|
|
18
|
+
elif [[ -f "pom.xml" ]]; then
|
|
19
|
+
echo "java"
|
|
20
|
+
elif [[ -f "pubspec.yaml" ]]; then
|
|
21
|
+
if grep -q "flutter:" "pubspec.yaml" 2>/dev/null || [[ -f ".metadata" ]]; then
|
|
22
|
+
echo "flutter"
|
|
23
|
+
else
|
|
24
|
+
echo "dart"
|
|
25
|
+
fi
|
|
26
|
+
elif [[ -n "$(find . -name "*.ps1" -type f | head -n 1)" ]]; then
|
|
27
|
+
echo "powershell"
|
|
28
|
+
elif [[ -f "Package.swift" ]]; then
|
|
29
|
+
echo "swift"
|
|
30
|
+
elif [[ -f "CMakeLists.txt" ]] || [[ -n "$(find . -name "*.cpp" -o -name "*.cc" -type f | head -n 1)" ]]; then
|
|
31
|
+
echo "cpp"
|
|
32
|
+
elif [[ -n "$(find . -name "*.m" -o -name "*.mm" -type f | head -n 1)" ]]; then
|
|
33
|
+
echo "objectivec"
|
|
34
|
+
elif [[ -n "$(find . -name "*.sh" -type f | head -n 1)" ]] || [[ -n "$(find . -name "Dockerfile" -o -name "*.dockerfile" -type f | head -n 1)" ]]; then
|
|
35
|
+
echo "shell"
|
|
36
|
+
elif [[ -n "$(find . -name "*.ps1" -type f -not -path "./.git/*" | head -n 1)" ]]; then
|
|
37
|
+
echo "powershell"
|
|
38
|
+
else
|
|
39
|
+
if [[ -n "$(find . -name "*.ts" -o -name "*.tsx" -type f | head -n 1)" ]]; then
|
|
40
|
+
echo "typescript"
|
|
41
|
+
elif [[ -n "$(find . -name "*.py" -type f | head -n 1)" ]]; then
|
|
42
|
+
echo "python"
|
|
43
|
+
elif [[ -n "$(find . -name "*.go" -type f | head -n 1)" ]]; then
|
|
44
|
+
echo "go"
|
|
45
|
+
elif [[ -n "$(find . -name "*.kt" -type f | head -n 1)" ]]; then
|
|
46
|
+
echo "kotlin"
|
|
47
|
+
elif [[ -n "$(find . -name "*.java" -type f | head -n 1)" ]]; then
|
|
48
|
+
echo "java"
|
|
49
|
+
elif [[ -n "$(find . -name "*.dart" -type f | head -n 1)" ]]; then
|
|
50
|
+
if grep -q "flutter:" "pubspec.yaml" 2>/dev/null || [[ -f ".flutter" ]]; then
|
|
51
|
+
echo "flutter"
|
|
52
|
+
else
|
|
53
|
+
echo "dart"
|
|
54
|
+
fi
|
|
55
|
+
elif [[ -n "$(find . -name "*.swift" -type f | head -n 1)" ]]; then
|
|
56
|
+
echo "swift"
|
|
57
|
+
elif [[ -n "$(find . -name "*.cpp" -o -name "*.cc" -o -name "*.c" -o -name "*.h" -type f | head -n 1)" ]]; then
|
|
58
|
+
echo "cpp"
|
|
59
|
+
elif [[ -n "$(find . -name "*.m" -o -name "*.mm" -type f | head -n 1)" ]]; then
|
|
60
|
+
echo "objectivec"
|
|
61
|
+
elif [[ -n "$(find . -name "*.sh" -type f | head -n 1)" ]]; then
|
|
62
|
+
echo "shell"
|
|
63
|
+
elif [[ -n "$(find . -name "*.ps1" -type f -not -path "./.git/*" | head -n 1)" ]]; then
|
|
64
|
+
echo "powershell"
|
|
65
|
+
else
|
|
66
|
+
echo "unknown"
|
|
67
|
+
fi
|
|
68
|
+
fi
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
route_to_adapter() {
|
|
72
|
+
local action="$1"
|
|
73
|
+
local lang
|
|
74
|
+
lang=$(detect_project_lang)
|
|
75
|
+
|
|
76
|
+
# Source the appropriate adapter
|
|
77
|
+
if [[ -f "githooks/adapters/${lang}.sh" ]]; then
|
|
78
|
+
# shellcheck source=githooks/adapters/"${lang}".sh
|
|
79
|
+
source "githooks/adapters/${lang}.sh"
|
|
80
|
+
|
|
81
|
+
# Execute the requested action
|
|
82
|
+
case "$action" in
|
|
83
|
+
"static_analysis") run_static_analysis ;;
|
|
84
|
+
"lint") run_lint ;;
|
|
85
|
+
"tests") run_tests ;;
|
|
86
|
+
"coverage") run_coverage ;;
|
|
87
|
+
*) return 1 ;;
|
|
88
|
+
esac
|
|
89
|
+
elif [[ -f "./githooks/adapters/${lang}.sh" ]]; then
|
|
90
|
+
# Alternative: source with ./ prefix
|
|
91
|
+
# shellcheck source=./githooks/adapters/"${lang}".sh
|
|
92
|
+
source "./githooks/adapters/${lang}.sh"
|
|
93
|
+
|
|
94
|
+
# Execute the requested action
|
|
95
|
+
case "$action" in
|
|
96
|
+
"static_analysis") run_static_analysis ;;
|
|
97
|
+
"lint") run_lint ;;
|
|
98
|
+
"tests") run_tests ;;
|
|
99
|
+
"coverage") run_coverage ;;
|
|
100
|
+
*) return 1 ;;
|
|
101
|
+
esac
|
|
102
|
+
else
|
|
103
|
+
echo "No adapter found for language: $lang"
|
|
104
|
+
return 1
|
|
105
|
+
fi
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
check_if_tool_available() {
|
|
109
|
+
local tool_name="$1"
|
|
110
|
+
|
|
111
|
+
# Check if command exists
|
|
112
|
+
if command -v "$tool_name" >/dev/null 2>&1; then
|
|
113
|
+
return 0
|
|
114
|
+
else
|
|
115
|
+
return 1
|
|
116
|
+
fi
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
require_tool() {
|
|
120
|
+
local tool_name="$1"
|
|
121
|
+
local gate_name="${2:-Gate}"
|
|
122
|
+
local install_hint="${3:-}"
|
|
123
|
+
|
|
124
|
+
if command -v "$tool_name" >/dev/null 2>&1; then
|
|
125
|
+
return 0
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
if command -v npx >/dev/null 2>&1 && npx --no-install "$tool_name" --version >/dev/null 2>&1; then
|
|
129
|
+
return 0
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
echo "❌ BLOCKED - Required tool '$tool_name' not available for $gate_name"
|
|
133
|
+
if [[ -n "$install_hint" ]]; then
|
|
134
|
+
echo " Install: $install_hint"
|
|
135
|
+
fi
|
|
136
|
+
echo " Per QUALITY-GATES-CODE-OF-CONDUCT.md: tool unavailable = BLOCK, not SKIP"
|
|
137
|
+
return 1
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
# Detect if project has IaC files (Terraform, Kubernetes, Docker)
|
|
141
|
+
detect_iac_project() {
|
|
142
|
+
local has_iac=false
|
|
143
|
+
|
|
144
|
+
# Check for Terraform files
|
|
145
|
+
if [[ -n "$(find . -maxdepth 2 -name "*.tf" -not -path "./.git/*" 2>/dev/null | head -1)" ]]; then
|
|
146
|
+
has_iac=true
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
# Check for Kubernetes manifests (YAML with apiVersion/kind)
|
|
150
|
+
if [[ -n "$(find . -maxdepth 2 \( -name "*.yaml" -o -name "*.yml" \) -not -path "./.git/*" 2>/dev/null | head -1)" ]]; then
|
|
151
|
+
local yaml_file=$(find . -maxdepth 2 \( -name "*.yaml" -o -name "*.yml" \) -not -path "./.git/*" 2>/dev/null | head -1)
|
|
152
|
+
if grep -qE "^(apiVersion|kind):" "$yaml_file" 2>/dev/null; then
|
|
153
|
+
has_iac=true
|
|
154
|
+
fi
|
|
155
|
+
fi
|
|
156
|
+
|
|
157
|
+
# Check for Dockerfiles
|
|
158
|
+
if [[ -n "$(find . -maxdepth 2 -name "Dockerfile" -o -name "*.dockerfile" -not -path "./.git/*" 2>/dev/null | head -1)" ]]; then
|
|
159
|
+
has_iac=true
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
if [ "$has_iac" = true ]; then
|
|
163
|
+
echo "iac"
|
|
164
|
+
else
|
|
165
|
+
echo ""
|
|
166
|
+
fi
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
# Stryker 9.x config files (new format, takes priority)
|
|
170
|
+
detect_mutation_testable() {
|
|
171
|
+
if [[ -f "stryker.config.mjs" ]] || [[ -f "stryker.config.js" ]] || \
|
|
172
|
+
[[ -f "stryker.config.cjs" ]] || [[ -f "stryker.config.json" ]]; then
|
|
173
|
+
if [[ -f "package.json" ]] && grep -qE '"@stryker-mutator[^"]*"' package.json 2>/dev/null; then
|
|
174
|
+
return 0
|
|
175
|
+
fi
|
|
176
|
+
if command -v npx >/dev/null 2>&1 && npx --no-install stryker --version >/dev/null 2>&1; then
|
|
177
|
+
return 0
|
|
178
|
+
fi
|
|
179
|
+
fi
|
|
180
|
+
|
|
181
|
+
# Legacy Stryker config files (backwards compatibility)
|
|
182
|
+
if [[ -f "stryker.conf.json" ]] || [[ -f "stryker.prepush.conf.json" ]]; then
|
|
183
|
+
if [[ -f "package.json" ]] && grep -qE '"@stryker-mutator[^"]*"' package.json 2>/dev/null; then
|
|
184
|
+
return 0
|
|
185
|
+
fi
|
|
186
|
+
if command -v npx >/dev/null 2>&1 && npx --no-install stryker --version >/dev/null 2>&1; then
|
|
187
|
+
return 0
|
|
188
|
+
fi
|
|
189
|
+
fi
|
|
190
|
+
|
|
191
|
+
return 1
|
|
192
|
+
}
|