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.
Files changed (90) hide show
  1. package/adapter-common.sh +192 -0
  2. package/adapters/cpp.sh +76 -0
  3. package/adapters/dart.sh +41 -0
  4. package/adapters/flutter.sh +41 -0
  5. package/adapters/go.sh +59 -0
  6. package/adapters/iac.sh +189 -0
  7. package/adapters/java.sh +191 -0
  8. package/adapters/kotlin.sh +77 -0
  9. package/adapters/objectivec.sh +38 -0
  10. package/adapters/powershell.sh +138 -0
  11. package/adapters/python.sh +104 -0
  12. package/adapters/shell.sh +55 -0
  13. package/adapters/swift.sh +44 -0
  14. package/adapters/typescript.sh +61 -0
  15. package/bin/xp-gate.js +157 -0
  16. package/hooks/adapter-common.sh +192 -0
  17. package/hooks/pre-commit +1667 -0
  18. package/hooks/pre-push +395 -0
  19. package/lib/__tests__/detect-deps.test.js +209 -0
  20. package/lib/__tests__/doctor.test.js +448 -0
  21. package/lib/__tests__/download-skill.test.js +281 -0
  22. package/lib/__tests__/init.test.js +327 -0
  23. package/lib/__tests__/install-skill.test.js +326 -0
  24. package/lib/__tests__/migrate.test.js +212 -0
  25. package/lib/__tests__/rollback.test.js +183 -0
  26. package/lib/__tests__/ui-detector.test.ts +200 -0
  27. package/lib/__tests__/uninstall-skill.test.js +189 -0
  28. package/lib/__tests__/uninstall.test.js +589 -0
  29. package/lib/__tests__/update-skill.test.js +276 -0
  30. package/lib/detect-deps.js +157 -0
  31. package/lib/doctor.js +370 -0
  32. package/lib/download-skill.js +96 -0
  33. package/lib/init.js +367 -0
  34. package/lib/install-skill.js +184 -0
  35. package/lib/migrate.js +120 -0
  36. package/lib/rollback.js +78 -0
  37. package/lib/ui-detector.ts +99 -0
  38. package/lib/uninstall-skill.js +69 -0
  39. package/lib/uninstall.js +401 -0
  40. package/lib/update-skill.js +90 -0
  41. package/package.json +39 -0
  42. package/plugins/claude-code/.claude-plugin/plugin.json +21 -0
  43. package/plugins/claude-code/bin/delphi-review-guard.sh +68 -0
  44. package/plugins/claude-code/bin/xp-gate-check +47 -0
  45. package/plugins/claude-code/hooks/hooks.json +37 -0
  46. package/skills/delphi-review/.delphi-config.json.example +45 -0
  47. package/skills/delphi-review/AGENTS.md +54 -0
  48. package/skills/delphi-review/INSTALL.md +152 -0
  49. package/skills/delphi-review/SKILL.md +371 -0
  50. package/skills/delphi-review/evals/evals.json +82 -0
  51. package/skills/delphi-review/opencode.json.delphi.example +56 -0
  52. package/skills/delphi-review/references/code-walkthrough.md +486 -0
  53. package/skills/ralph-loop/SKILL.md +330 -0
  54. package/skills/ralph-loop/evals/evals.json +311 -0
  55. package/skills/ralph-loop/evolution-history.json +59 -0
  56. package/skills/ralph-loop/evolution-log.md +16 -0
  57. package/skills/ralph-loop/references/components/memory.md +55 -0
  58. package/skills/ralph-loop/references/components/middleware.md +54 -0
  59. package/skills/ralph-loop/references/components/skill-invocations.md +39 -0
  60. package/skills/ralph-loop/references/components/system-prompt.md +24 -0
  61. package/skills/ralph-loop/references/components/tool-descriptions.md +32 -0
  62. package/skills/ralph-loop/references/phase-2-build-ralph.md +89 -0
  63. package/skills/ralph-loop/templates/progress-log.md +36 -0
  64. package/skills/sprint-flow/SKILL.md +600 -0
  65. package/skills/sprint-flow/evals/evals.json +78 -0
  66. package/skills/sprint-flow/evolution-history.json +39 -0
  67. package/skills/sprint-flow/evolution-log.md +23 -0
  68. package/skills/sprint-flow/references/components/memory.md +87 -0
  69. package/skills/sprint-flow/references/components/middleware.md +72 -0
  70. package/skills/sprint-flow/references/components/skill-invocations.md +104 -0
  71. package/skills/sprint-flow/references/components/system-prompt.md +27 -0
  72. package/skills/sprint-flow/references/components/tool-descriptions.md +96 -0
  73. package/skills/sprint-flow/references/phase-0-think.md +115 -0
  74. package/skills/sprint-flow/references/phase-1-plan.md +178 -0
  75. package/skills/sprint-flow/references/phase-2-build.md +198 -0
  76. package/skills/sprint-flow/references/phase-3-review.md +213 -0
  77. package/skills/sprint-flow/references/phase-4-uat.md +125 -0
  78. package/skills/sprint-flow/references/phase-5-feedback.md +100 -0
  79. package/skills/sprint-flow/references/phase-6-ship.md +193 -0
  80. package/skills/sprint-flow/references/phase-7-land.md +140 -0
  81. package/skills/sprint-flow/references/phase-8-cleanup.md +192 -0
  82. package/skills/sprint-flow/templates/emergent-issues-template.md +120 -0
  83. package/skills/sprint-flow/templates/pain-document-template.md +115 -0
  84. package/skills/sprint-flow/templates/sprint-summary-template.md +120 -0
  85. package/skills/test-specification-alignment/AGENTS.md +59 -0
  86. package/skills/test-specification-alignment/SKILL.md +605 -0
  87. package/skills/test-specification-alignment/evals/evals.json +75 -0
  88. package/skills/test-specification-alignment/references/alignment-verification-algorithm.md +493 -0
  89. package/skills/test-specification-alignment/references/phase2-constraint-enforcement.md +431 -0
  90. package/skills/test-specification-alignment/references/specification-format.md +348 -0
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env bash
2
+
3
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
4
+ # Plugin directory
5
+ PLUGIN_DIR="$SCRIPT_DIR/plugins/p3c-java"
6
+ WHALECLOUD_PLUGIN_DIR="$SCRIPT_DIR/plugins/whalecloud-java"
7
+
8
+ _is_whalecloud_enabled() {
9
+ # Check if whalecloud-java plugin is enabled
10
+ [ -d "$WHALECLOUD_PLUGIN_DIR" ] && \
11
+ ([ -f "config/pmd/whalecloud-ruleset.xml" ] || \
12
+ grep -q 'xp-gate-whalecloud-java\|xp-gateWhalecloudCheck' pom.xml build.gradle build.gradle.kts 2>/dev/null)
13
+ }
14
+
15
+ _detect_java_build() {
16
+ if [ -f "pom.xml" ]; then
17
+ echo "maven"
18
+ elif [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then
19
+ echo "gradle"
20
+ else
21
+ echo "none"
22
+ fi
23
+ }
24
+
25
+ run_static_analysis() {
26
+ local build_system
27
+ build_system=$(_detect_java_build)
28
+
29
+ if [ "$build_system" = "maven" ]; then
30
+ mvn compile -q 2>&1 | grep -i "error\|fail" | head -5
31
+ if [ "${PIPESTATUS[0]}" -ne 0 ]; then
32
+ echo "❌ Maven compilation failed"
33
+ return 1
34
+ fi
35
+ elif [ "$build_system" = "gradle" ]; then
36
+ gradle compileJava --quiet 2>&1 | grep -i "error\|fail" | head -5
37
+ if [ "${PIPESTATUS[0]}" -ne 0 ]; then
38
+ echo "❌ Gradle compilation failed"
39
+ return 1
40
+ fi
41
+ fi
42
+
43
+ # CheckStyle with Google style (legacy fallback)
44
+ if command -v checkstyle &>/dev/null; then
45
+ checkstyle -c /google_checks.xml . 2>&1 | head -20
46
+ fi
47
+
48
+ # PMD error detection (legacy fallback)
49
+ if command -v pmd &>/dev/null; then
50
+ pmd check -d . -R category/java/errorprone.xml 2>&1 | head -20
51
+ fi
52
+
53
+ # p3c-pmd check (Alibaba coding guidelines) — primary Java quality gate
54
+ _run_p3c_check "$build_system"
55
+
56
+ # WhaleCloud Java Coding Standards — overlay on top of p3c-pmd
57
+ _run_whalecloud_check "$build_system"
58
+
59
+ return 0
60
+ }
61
+
62
+ run_lint() {
63
+ run_static_analysis
64
+ }
65
+
66
+ run_tests() {
67
+ local build_system
68
+ build_system=$(_detect_java_build)
69
+
70
+ if [ "$build_system" = "maven" ]; then
71
+ mvn test -q 2>&1 | tail -15
72
+ return "${PIPESTATUS[0]}"
73
+ elif [ "$build_system" = "gradle" ]; then
74
+ gradle test --quiet 2>&1 | tail -15
75
+ return "${PIPESTATUS[0]}"
76
+ else
77
+ echo "No Maven/Gradle project detected"
78
+ return 1
79
+ fi
80
+ }
81
+
82
+ run_coverage() {
83
+ local build_system
84
+ build_system=$(_detect_java_build)
85
+
86
+ if [ "$build_system" = "maven" ]; then
87
+ mvn test jacoco:report -q 2>&1 | tail -10
88
+ return "${PIPESTATUS[0]}"
89
+ elif [ "$build_system" = "gradle" ]; then
90
+ gradle jacocoTestReport --quiet 2>&1 | tail -10
91
+ return "${PIPESTATUS[0]}"
92
+ else
93
+ echo "No Maven/Gradle project detected"
94
+ return 1
95
+ fi
96
+ }
97
+
98
+ run_p3c_check() {
99
+ _run_p3c_check "$(_detect_java_build)"
100
+ }
101
+
102
+ _run_p3c_check() {
103
+ local build_system="$1"
104
+
105
+ echo " Running p3c-pmd Alibaba Coding Guidelines check..."
106
+
107
+ if [ "$build_system" = "maven" ]; then
108
+ if grep -q '<id>xp-gate-p3c</id>' pom.xml 2>/dev/null; then
109
+ # Profile already installed — use it
110
+ mvn pmd:check -P xp-gate-p3c -Dpmd.failOnViolation=true 2>&1 | tail -30
111
+ return "${PIPESTATUS[0]}"
112
+ else
113
+ # Profile not installed — run inline with p3c-pmd dependency
114
+ if command -v mvn &>/dev/null; then
115
+ mvn pmd:check \
116
+ -Dpmd.rulesets="/rulesets/java/ali-comment.xml,/rulesets/java/ali-concurrent.xml,/rulesets/java/ali-constant.xml,/rulesets/java/ali-exception.xml,/rulesets/java/ali-flowcontrol.xml,/rulesets/java/ali-naming.xml,/rulesets/java/ali-oop.xml,/rulesets/java/ali-orm.xml,/rulesets/java/ali-other.xml,/rulesets/java/ali-set.xml" \
117
+ -Dpmd.failOnViolation=true \
118
+ -DprintFailingErrors=true \
119
+ 2>&1 | tail -30
120
+ local result="${PIPESTATUS[0]}"
121
+
122
+ if [ "$result" -ne 0 ]; then
123
+ echo ""
124
+ echo " ⚠️ p3c-pmd check FAILED — Alibaba Coding Guidelines violations found"
125
+ echo " To permanently enable: bash $PLUGIN_DIR/scripts/install-maven-p3c.sh"
126
+ return 1
127
+ fi
128
+
129
+ echo " ✅ p3c-pmd check passed"
130
+ return 0
131
+ else
132
+ echo " ℹ️ Maven not available — Skipping p3c-pmd"
133
+ return 0
134
+ fi
135
+ fi
136
+
137
+ elif [ "$build_system" = "gradle" ]; then
138
+ if grep -q 'xp-gateP3cCheck\|p3c-pmd' build.gradle 2>/dev/null || \
139
+ grep -q 'xp-gateP3cCheck\|p3c-pmd' build.gradle.kts 2>/dev/null; then
140
+ gradle xp-gateP3cCheck --quiet 2>&1 | tail -20
141
+ return "${PIPESTATUS[0]}"
142
+ else
143
+ echo " ℹ️ p3c-pmd not configured in Gradle build"
144
+ echo " To enable: bash $PLUGIN_DIR/scripts/install-gradle-p3c.sh"
145
+ return 0
146
+ fi
147
+ fi
148
+
149
+ echo " ℹ️ No Maven/Gradle project — Skipping p3c-pmd"
150
+ return 0
151
+ }
152
+
153
+ _run_whalecloud_check() {
154
+ local build_system="$1"
155
+
156
+ if ! _is_whalecloud_enabled; then
157
+ return 0
158
+ fi
159
+
160
+ echo " Running WhaleCloud Java Coding Standards check..."
161
+
162
+ if [ "$build_system" = "maven" ]; then
163
+ if grep -q '<id>xp-gate-whalecloud-java</id>' pom.xml 2>/dev/null; then
164
+ mvn pmd:check checkstyle:check spotbugs:check \
165
+ -P xp-gate-whalecloud-java -Dpmd.failOnViolation=true \
166
+ 2>&1 | tail -30
167
+ return "${PIPESTATUS[0]}"
168
+ else
169
+ echo " ⚠️ whalecloud-java profile not installed in pom.xml"
170
+ echo " To enable: bash $WHALECLOUD_PLUGIN_DIR/scripts/install-maven-whalecloud.sh"
171
+ return 0
172
+ fi
173
+
174
+ elif [ "$build_system" = "gradle" ]; then
175
+ if grep -q 'xp-gateWhalecloudCheck' build.gradle 2>/dev/null || \
176
+ grep -q 'xp-gateWhalecloudCheck' build.gradle.kts 2>/dev/null; then
177
+ gradle xp-gateWhalecloudCheck --quiet 2>&1 | tail -20
178
+ return "${PIPESTATUS[0]}"
179
+ else
180
+ echo " ⚠️ whalecloud-java not configured in Gradle build"
181
+ echo " To enable: bash $WHALECLOUD_PLUGIN_DIR/scripts/install-gradle-whalecloud.sh"
182
+ return 0
183
+ fi
184
+ fi
185
+
186
+ return 0
187
+ }
188
+
189
+ run_whalecloud_check() {
190
+ _run_whalecloud_check "$(_detect_java_build)"
191
+ }
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env bash
2
+
3
+ _detect_kotlin_build() {
4
+ if [ -f "pom.xml" ]; then
5
+ echo "maven"
6
+ elif [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then
7
+ echo "gradle"
8
+ else
9
+ echo "none"
10
+ fi
11
+ }
12
+
13
+ run_static_analysis() {
14
+ local build_system
15
+ build_system=$(_detect_kotlin_build)
16
+
17
+ if [ "$build_system" = "maven" ]; then
18
+ mvn compile -q 2>&1 | grep -i "error\|fail" | head -5
19
+ if [ ${PIPESTATUS[0]} -ne 0 ]; then
20
+ echo "❌ Maven compilation failed"
21
+ return 1
22
+ fi
23
+ elif [ "$build_system" = "gradle" ]; then
24
+ gradle compileKotlin --quiet 2>&1 | grep -i "error\|fail" | head -5
25
+ if [ ${PIPESTATUS[0]} -ne 0 ]; then
26
+ echo "❌ Gradle compilation failed"
27
+ return 1
28
+ fi
29
+ fi
30
+
31
+ if command -v ktlint &>/dev/null; then
32
+ ktlint "**/*.kt" 2>&1 | head -20
33
+ return $?
34
+ elif command -v detekt &>/dev/null; then
35
+ detekt --input . 2>&1 | head -20
36
+ return $?
37
+ else
38
+ echo "No Kotlin lint tools (ktlint/detekt)"
39
+ return 0
40
+ fi
41
+ }
42
+
43
+ run_lint() {
44
+ run_static_analysis
45
+ }
46
+
47
+ run_tests() {
48
+ local build_system
49
+ build_system=$(_detect_kotlin_build)
50
+
51
+ if [ "$build_system" = "maven" ]; then
52
+ mvn test -q 2>&1 | tail -15
53
+ return ${PIPESTATUS[0]}
54
+ elif [ "$build_system" = "gradle" ]; then
55
+ gradle test --quiet 2>&1 | tail -15
56
+ return ${PIPESTATUS[0]}
57
+ else
58
+ echo "No build system detected"
59
+ return 1
60
+ fi
61
+ }
62
+
63
+ run_coverage() {
64
+ local build_system
65
+ build_system=$(_detect_kotlin_build)
66
+
67
+ if [ "$build_system" = "maven" ]; then
68
+ mvn test jacoco:report -q 2>&1 | tail -10
69
+ return ${PIPESTATUS[0]}
70
+ elif [ "$build_system" = "gradle" ]; then
71
+ gradle jacocoTestReport --quiet 2>&1 | tail -10
72
+ return ${PIPESTATUS[0]}
73
+ else
74
+ echo "No build system detected"
75
+ return 1
76
+ fi
77
+ }
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env bash
2
+
3
+ run_static_analysis() {
4
+ if command -v oclint &>/dev/null; then
5
+ oclint-json-compilation-database 2>&1 | head -30
6
+ return $?
7
+ elif command -v clang-tidy &>/dev/null; then
8
+ find . -name "*.m" -o -name "*.mm" -o -name "*.h" | head -20 | xargs clang-tidy 2>&1 | head -30
9
+ return $?
10
+ else
11
+ echo "No Objective-C analysis tools available (oclint/clang-tidy)"
12
+ return 1
13
+ fi
14
+ }
15
+
16
+ run_lint() {
17
+ run_static_analysis
18
+ }
19
+
20
+ run_tests() {
21
+ if [ -f "*.xcodeproj" ] || [ -f "*.xcworkspace" ]; then
22
+ echo "Xcode project detected — use xcodebuild for tests"
23
+ return 1
24
+ else
25
+ echo "No Objective-C test framework detected"
26
+ return 1
27
+ fi
28
+ }
29
+
30
+ run_coverage() {
31
+ if command -v xccov &>/dev/null; then
32
+ xccov view --report 2>&1 | tail -10
33
+ return $?
34
+ else
35
+ echo "No Objective-C coverage tools available"
36
+ return 1
37
+ fi
38
+ }
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # PowerShell adapter for quality gates
4
+ #
5
+ # Tool requirements:
6
+ # - PSScriptAnalyzer: Install-Module PSScriptAnalyzer -Scope CurrentUser
7
+ # - Pester: Install-Module Pester -Scope CurrentUser
8
+ #
9
+ # Notes:
10
+ # - Gate 2 (Duplicate Code): No PowerShell-native duplicate detector exists.
11
+ # jscpd and lizard do not support .ps1. SKIP for now.
12
+ # - Gate 3 (Cyclomatic Complexity): lizard does not analyze .ps1.
13
+ # SKIP for now.
14
+ # - Gate 4 (Principles Checker): No PowerShell principles checker.
15
+ # SKIP for now.
16
+ # - Gate 6 (Architecture): No PowerShell architecture tooling.
17
+ # SKIP for now.
18
+
19
+ # Detect PowerShell executable (prefer pwsh 7+, fallback to powershell.exe 5.1)
20
+ _detect_pwsh() {
21
+ if command -v pwsh &>/dev/null 2>&1; then
22
+ echo "pwsh"
23
+ elif command -v powershell.exe &>/dev/null 2>&1; then
24
+ echo "powershell.exe"
25
+ elif command -v powershell &>/dev/null 2>&1; then
26
+ echo "powershell"
27
+ else
28
+ echo ""
29
+ fi
30
+ }
31
+
32
+ run_static_analysis() {
33
+ local PWSH
34
+ PWSH=$(_detect_pwsh)
35
+ if [ -n "$PWSH" ]; then
36
+ echo "Running PSScriptAnalyzer static analysis on PowerShell scripts..."
37
+ # Recursively analyze all .ps1 files from repo root
38
+ # Exit with non-zero if Error or Warning severity issues found
39
+ "$PWSH" -NoProfile -Command "
40
+ \$results = Invoke-ScriptAnalyzer -Path . -Recurse -Severity Error,Warning
41
+ if (\$results) {
42
+ \$results | Format-Table -AutoSize
43
+ exit 1
44
+ }
45
+ exit 0
46
+ "
47
+ return $?
48
+ else
49
+ echo "PowerShell not available, skipping PowerShell static analysis"
50
+ return 0
51
+ fi
52
+ }
53
+
54
+ run_lint() {
55
+ # PSScriptAnalyzer covers both static analysis and linting
56
+ run_static_analysis
57
+ }
58
+
59
+ run_tests() {
60
+ local PWSH
61
+ PWSH=$(_detect_pwsh)
62
+ if [ -z "$PWSH" ]; then
63
+ echo "PowerShell not available, skipping PowerShell tests"
64
+ return 0
65
+ fi
66
+
67
+ # Check if Pester tests exist in common locations
68
+ local test_paths=""
69
+ if [ -d "tests" ]; then
70
+ test_paths="tests/"
71
+ elif [ -d "test" ]; then
72
+ test_paths="test/"
73
+ fi
74
+
75
+ if [ -n "$test_paths" ] && find "$test_paths" -name "*.Tests.ps1" -type f 2>/dev/null | head -1 | grep -q "."; then
76
+ echo "Running Pester tests..."
77
+ "$PWSH" -NoProfile -Command "
78
+ \$results = Invoke-Pester -Path '$test_paths' -PassThru
79
+ if (\$results.FailedCount -gt 0) {
80
+ Write-Host \"FAILED: \$(\$results.FailedCount) test(s)\"
81
+ exit 1
82
+ }
83
+ Write-Host \"PASSED: \$(\$results.PassedCount) test(s)\"
84
+ exit 0
85
+ "
86
+ return $?
87
+ elif find . -maxdepth 2 -name "*.Tests.ps1" -type f 2>/dev/null | head -1 | grep -q "."; then
88
+ echo "Running Pester tests in current directory..."
89
+ "$PWSH" -NoProfile -Command "
90
+ \$results = Invoke-Pester -CI -PassThru
91
+ if (\$results.FailedCount -gt 0) {
92
+ Write-Host \"FAILED: \$(\$results.FailedCount) test(s)\"
93
+ exit 1
94
+ }
95
+ Write-Host \"PASSED: \$(\$results.PassedCount) test(s)\"
96
+ exit 0
97
+ "
98
+ return $?
99
+ else
100
+ echo "No Pester tests found"
101
+ return 0
102
+ fi
103
+ }
104
+
105
+ run_coverage() {
106
+ local PWSH
107
+ PWSH=$(_detect_pwsh)
108
+ if [ -z "$PWSH" ]; then
109
+ echo "PowerShell not available, skipping PowerShell coverage"
110
+ return 0
111
+ fi
112
+
113
+ local test_paths=""
114
+ if [ -d "tests" ]; then
115
+ test_paths="tests/"
116
+ elif [ -d "test" ]; then
117
+ test_paths="test/"
118
+ fi
119
+
120
+ if [ -n "$test_paths" ] || find . -maxdepth 2 -name "*.Tests.ps1" -type f 2>/dev/null | head -1 | grep -q "."; then
121
+ echo "Running Pester with code coverage..."
122
+ local path_arg="${test_paths:-.}"
123
+ "$PWSH" -NoProfile -Command "
124
+ \$results = Invoke-Pester -Path '$path_arg' -CodeCoverage @(Get-ChildItem -Path . -Filter *.ps1 -Recurse -Exclude *.Tests.ps1) -PassThru
125
+ \$pct = [math]::Round(\$results.CodeCoverage.CoveragePercent, 1)
126
+ Write-Host \"Coverage: \$pct%\"
127
+ if (\$pct -lt 80) {
128
+ Write-Host \"WARNING: Coverage \$pct% is below 80% threshold\"
129
+ exit 0
130
+ }
131
+ exit 0
132
+ " 2>&1
133
+ return $?
134
+ else
135
+ echo "No Pester tests found for coverage measurement"
136
+ return 0
137
+ fi
138
+ }
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Python adapter for quality gates
4
+ # Tools: mypy, ruff/flake8, pytest, import-linter (architecture)
5
+
6
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
+ source "$SCRIPT_DIR/../adapter-common.sh" 2>/dev/null || true
8
+
9
+ run_static_analysis() {
10
+ require_tool mypy "mypy" || return 1
11
+
12
+ echo "Running Python static analysis (mypy)..."
13
+ mypy .
14
+ return $?
15
+ }
16
+
17
+ run_lint() {
18
+ if command -v ruff >/dev/null 2>&1; then
19
+ echo "Running Python linting (ruff)..."
20
+ ruff check .
21
+ return $?
22
+ elif command -v flake8 >/dev/null 2>&1; then
23
+ echo "Running Python linting (flake8)..."
24
+ flake8 .
25
+ return $?
26
+ else
27
+ echo "⚠ No Python linter available (ruff or flake8 required)"
28
+ return 0
29
+ fi
30
+ }
31
+
32
+ run_architecture() {
33
+ if [ ! -f ".import-linter.yml" ] && [ ! -f "import_linter_config.yml" ]; then
34
+ return 0
35
+ fi
36
+
37
+ require_tool lint-imports "import-linter" || return 0
38
+
39
+ echo "Running Python architecture checks (import-linter)..."
40
+ lint-imports
41
+ return $?
42
+ }
43
+
44
+ run_tests() {
45
+ require_tool pytest "pytest" || return 1
46
+
47
+ echo "Running Python tests..."
48
+ PYTEST_OUTPUT=$(pytest --exitfirst --tb=short 2>&1)
49
+ PYTEST_EXIT=$?
50
+ echo "$PYTEST_OUTPUT" | tail -30
51
+
52
+ # Check for collection errors (ModuleNotFoundError / ImportError)
53
+ if echo "$PYTEST_OUTPUT" | grep -qi "ModuleNotFoundError\|ImportError"; then
54
+ echo "❌ Python test collection errors detected — modules not importable"
55
+ echo " Fix: Run 'pip install -e .' or set PYTHONPATH=."
56
+ return 1
57
+ fi
58
+
59
+ # Check if no tests were actually collected
60
+ if echo "$PYTEST_OUTPUT" | grep -q "collected 0 items\|no tests ran"; then
61
+ echo "❌ No tests were collected — nothing actually ran"
62
+ return 1
63
+ fi
64
+
65
+ # Check for errors in summary line (e.g. "3 errors")
66
+ ERROR_COUNT=$(echo "$PYTEST_OUTPUT" | grep -oP '\d+ error' | grep -oP '\d+' | head -1)
67
+ if [ -n "$ERROR_COUNT" ] && [ "$ERROR_COUNT" -gt 0 ]; then
68
+ echo "❌ $ERROR_COUNT test collection/execution errors detected"
69
+ return 1
70
+ fi
71
+
72
+ return $PYTEST_EXIT
73
+ }
74
+
75
+ run_coverage() {
76
+ require_tool pytest "pytest" || return 1
77
+
78
+ echo "Running Python coverage..."
79
+ PYTEST_OUTPUT=$(pytest --exitfirst --tb=short --cov=. --cov-fail-under=80 2>&1)
80
+ PYTEST_EXIT=$?
81
+ echo "$PYTEST_OUTPUT" | tail -30
82
+
83
+ # Check for collection errors (ModuleNotFoundError / ImportError)
84
+ if echo "$PYTEST_OUTPUT" | grep -qi "ModuleNotFoundError\|ImportError"; then
85
+ echo "❌ Python test collection errors detected — modules not importable"
86
+ echo " Fix: Run 'pip install -e .' or set PYTHONPATH=."
87
+ return 1
88
+ fi
89
+
90
+ # Check if no tests were actually collected
91
+ if echo "$PYTEST_OUTPUT" | grep -q "collected 0 items\|no tests ran"; then
92
+ echo "❌ No tests were collected — nothing actually ran"
93
+ return 1
94
+ fi
95
+
96
+ # Check for errors in summary line (e.g. "3 errors")
97
+ ERROR_COUNT=$(echo "$PYTEST_OUTPUT" | grep -oP '\d+ error' | grep -oP '\d+' | head -1)
98
+ if [ -n "$ERROR_COUNT" ] && [ "$ERROR_COUNT" -gt 0 ]; then
99
+ echo "❌ $ERROR_COUNT test collection/execution errors detected"
100
+ return 1
101
+ fi
102
+
103
+ return $PYTEST_EXIT
104
+ }
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Shell adapter for quality gates
4
+
5
+ run_static_analysis() {
6
+ if command -v shellcheck >/dev/null 2>&1; then
7
+ echo "Running Shell static analysis..."
8
+ shellcheck ./*.sh
9
+ return $?
10
+ else
11
+ echo "shellcheck not available, skipping Shell linting"
12
+ return 0
13
+ fi
14
+ }
15
+
16
+ run_lint() {
17
+ if command -v shellcheck >/dev/null 2>&1; then
18
+ echo "Running Shell linting..."
19
+ shellcheck ./*.sh ./**/**/*.sh
20
+ return $?
21
+ else
22
+ echo "shellcheck not available, skipping Shell linting"
23
+ return 0
24
+ fi
25
+ }
26
+
27
+ run_tests() {
28
+ # Look for and run shell test files
29
+ if [[ -d "tests" ]] && [[ -n "$(find tests -name "*.sh" -type f | head -n 1)" ]]; then
30
+ echo "Running Shell tests..."
31
+ for test_file in tests/*.sh; do
32
+ if [[ -x "$test_file" ]]; then
33
+ "$test_file"
34
+ local exit_code=$?
35
+ if [[ $exit_code -ne 0 ]]; then
36
+ return $exit_code
37
+ fi
38
+ fi
39
+ done
40
+ return 0
41
+ elif command -v shunit2 >/dev/null 2>&1; then
42
+ echo "Checking for shunit2 tests..."
43
+ # Skip - shunit2 requires properly formatted tests, just run any script if available
44
+ return 0
45
+ else
46
+ echo "No shell tests detected or shunit2 available"
47
+ return 0
48
+ fi
49
+ }
50
+
51
+ run_coverage() {
52
+ # Shell does not typically have standardized coverage tools
53
+ echo "Shell coverage not available"
54
+ return 0
55
+ }
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env bash
2
+
3
+ run_static_analysis() {
4
+ if command -v swiftlint &>/dev/null; then
5
+ swiftlint lint 2>&1 | head -30
6
+ return $?
7
+ else
8
+ echo "SwiftLint not available"
9
+ return 1
10
+ fi
11
+ }
12
+
13
+ run_lint() {
14
+ if command -v swiftlint &>/dev/null; then
15
+ swiftlint lint --strict 2>&1 | head -30
16
+ return $?
17
+ else
18
+ echo "SwiftLint not available"
19
+ return 1
20
+ fi
21
+ }
22
+
23
+ run_tests() {
24
+ if command -v swift &>/dev/null && [ -f "Package.swift" ]; then
25
+ swift test 2>&1 | tail -20
26
+ return $?
27
+ elif [ -f "*.xcodeproj" ] || [ -f "*.xcworkspace" ]; then
28
+ echo "Xcode project detected — use xcodebuild for tests"
29
+ return 1
30
+ else
31
+ echo "No Swift test framework detected"
32
+ return 1
33
+ fi
34
+ }
35
+
36
+ run_coverage() {
37
+ if command -v swift &>/dev/null && [ -f "Package.swift" ]; then
38
+ swift test --enable-code-coverage 2>&1 | tail -10
39
+ return $?
40
+ else
41
+ echo "No Swift test framework detected"
42
+ return 1
43
+ fi
44
+ }