@boyingliu01/xp-gate 0.18.5 → 0.19.0
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 +85 -33
- 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 +5 -5
- package/mock-policy/__tests__/gate-m3.test.ts +0 -5
- package/mock-policy/__tests__/scope-scanner.test.ts +8 -2
- package/mutation/AGENTS.md +4 -4
- 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 +13 -12
- 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 +5 -5
- 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 +4 -4
- 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 +13 -12
- 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 +5 -5
- 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 +4 -4
- 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 +15 -17
- 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 +5 -5
- 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 +4 -4
- package/principles/AGENTS.md +4 -4
- 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 +13 -12
- 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 +5 -5
- 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 +4 -4
- package/sprint-gate.sh +291 -0
package/adapter-common.sh
CHANGED
|
@@ -27,6 +27,17 @@ detect_os_env() {
|
|
|
27
27
|
esac
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
# Git exports repository-local variables to hooks. Child test processes must
|
|
31
|
+
# not inherit them, or nested git repositories modify the caller's repository.
|
|
32
|
+
run_without_git_context() (
|
|
33
|
+
unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_CONFIG GIT_CONFIG_PARAMETERS
|
|
34
|
+
unset GIT_CONFIG_COUNT GIT_OBJECT_DIRECTORY GIT_DIR GIT_WORK_TREE
|
|
35
|
+
unset GIT_IMPLICIT_WORK_TREE GIT_GRAFT_FILE GIT_INDEX_FILE
|
|
36
|
+
unset GIT_NO_REPLACE_OBJECTS GIT_REPLACE_REF_BASE GIT_PREFIX
|
|
37
|
+
unset GIT_SHALLOW_FILE GIT_COMMON_DIR
|
|
38
|
+
"$@"
|
|
39
|
+
)
|
|
40
|
+
|
|
30
41
|
detect_project_lang() {
|
|
31
42
|
if [ -f "tsconfig.json" ]; then
|
|
32
43
|
echo "typescript"
|
|
@@ -241,6 +252,22 @@ detect_go_mutation_testable() {
|
|
|
241
252
|
fi
|
|
242
253
|
return 1
|
|
243
254
|
}
|
|
255
|
+
|
|
256
|
+
# Check if any changed file matches any of the given regex patterns.
|
|
257
|
+
# Usage: any_changed_files_match "\.ts$" "\.py$"
|
|
258
|
+
# Returns 0 (true) if at least one changed file matches any pattern, 1 (false) otherwise.
|
|
259
|
+
any_changed_files_match() {
|
|
260
|
+
if [ -z "${CHANGED_FILES:-}" ]; then
|
|
261
|
+
return 1
|
|
262
|
+
fi
|
|
263
|
+
for pattern in "$@"; do
|
|
264
|
+
if echo "$CHANGED_FILES" | grep -qE "$pattern" 2>/dev/null; then
|
|
265
|
+
return 0
|
|
266
|
+
fi
|
|
267
|
+
done
|
|
268
|
+
return 1
|
|
269
|
+
}
|
|
270
|
+
|
|
244
271
|
# Detect if a Java/Kotlin project has PITest (pitest-maven or pitest-gradle) configured
|
|
245
272
|
detect_pitest_testable() {
|
|
246
273
|
# Check for Maven + pitest-maven plugin
|
package/adapters/gate-3.sh
CHANGED
|
File without changes
|
package/adapters/gate-4.sh
CHANGED
|
File without changes
|
package/adapters/gate-7.sh
CHANGED
|
File without changes
|
package/adapters/gate-8.sh
CHANGED
|
File without changes
|
package/adapters/gate-9.sh
CHANGED
|
File without changes
|
package/adapters/powershell.sh
CHANGED
|
@@ -29,14 +29,57 @@ _detect_pwsh() {
|
|
|
29
29
|
fi
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
_find_powershell_files() {
|
|
33
|
+
local name_pattern="$1"
|
|
34
|
+
find . \
|
|
35
|
+
\( -type d \( \
|
|
36
|
+
-name .git -o \
|
|
37
|
+
-name node_modules -o \
|
|
38
|
+
-name dist -o \
|
|
39
|
+
-name coverage -o \
|
|
40
|
+
-path './plugins/claude-code/skills' -o \
|
|
41
|
+
-path './plugins/opencode/skills' -o \
|
|
42
|
+
-path './plugins/qoder/skills' -o \
|
|
43
|
+
-path './src/npm-package/skills' -o \
|
|
44
|
+
-path './src/npm-package/plugins' \
|
|
45
|
+
\) -prune \) -o \
|
|
46
|
+
\( -type f -name "$name_pattern" -print \) 2>/dev/null
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
_powershell_invocation() {
|
|
50
|
+
local executable="$1"
|
|
51
|
+
POWERSHELL_ARGS=(-NoProfile)
|
|
52
|
+
case "${executable##*/}" in
|
|
53
|
+
powershell.exe|powershell)
|
|
54
|
+
POWERSHELL_ARGS[${#POWERSHELL_ARGS[@]}]=-ExecutionPolicy
|
|
55
|
+
POWERSHELL_ARGS[${#POWERSHELL_ARGS[@]}]=Bypass
|
|
56
|
+
;;
|
|
57
|
+
esac
|
|
58
|
+
POWERSHELL_ARGS[${#POWERSHELL_ARGS[@]}]=-Command
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
_powershell_path_array() {
|
|
62
|
+
local path
|
|
63
|
+
local separator=""
|
|
64
|
+
printf '@('
|
|
65
|
+
for path in "$@"; do
|
|
66
|
+
path=${path//\'/\'\'}
|
|
67
|
+
printf "%s'%s'" "$separator" "$path"
|
|
68
|
+
separator=","
|
|
69
|
+
done
|
|
70
|
+
printf ')'
|
|
71
|
+
}
|
|
72
|
+
|
|
32
73
|
run_static_analysis() {
|
|
33
74
|
local PWSH
|
|
34
75
|
PWSH=$(_detect_pwsh)
|
|
35
76
|
if [ -n "$PWSH" ]; then
|
|
77
|
+
local POWERSHELL_ARGS
|
|
78
|
+
_powershell_invocation "$PWSH"
|
|
36
79
|
echo "Running PSScriptAnalyzer static analysis on PowerShell scripts..."
|
|
37
80
|
# Recursively analyze all .ps1 files from repo root
|
|
38
81
|
# Exit with non-zero if Error or Warning severity issues found
|
|
39
|
-
"$PWSH"
|
|
82
|
+
"$PWSH" "${POWERSHELL_ARGS[@]}" "
|
|
40
83
|
\$results = Invoke-ScriptAnalyzer -Path . -Recurse -Severity Error,Warning
|
|
41
84
|
if (\$results) {
|
|
42
85
|
\$results | Format-Table -AutoSize
|
|
@@ -64,30 +107,24 @@ run_tests() {
|
|
|
64
107
|
return 0
|
|
65
108
|
fi
|
|
66
109
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if [ -d "tests" ]; then
|
|
70
|
-
test_paths="tests/"
|
|
71
|
-
elif [ -d "test" ]; then
|
|
72
|
-
test_paths="test/"
|
|
73
|
-
fi
|
|
110
|
+
local POWERSHELL_ARGS
|
|
111
|
+
_powershell_invocation "$PWSH"
|
|
74
112
|
|
|
75
|
-
|
|
113
|
+
local test_files=()
|
|
114
|
+
local discovery_file
|
|
115
|
+
local path
|
|
116
|
+
local test_paths
|
|
117
|
+
discovery_file=$(mktemp)
|
|
118
|
+
_find_powershell_files "*.Tests.ps1" > "$discovery_file"
|
|
119
|
+
while IFS= read -r path; do
|
|
120
|
+
test_files[${#test_files[@]}]="$path"
|
|
121
|
+
done < "$discovery_file"
|
|
122
|
+
rm -f "$discovery_file"
|
|
123
|
+
if [ "${#test_files[@]}" -gt 0 ]; then
|
|
124
|
+
test_paths=$(_powershell_path_array "${test_files[@]}")
|
|
76
125
|
echo "Running Pester tests..."
|
|
77
|
-
"$PWSH"
|
|
78
|
-
\$results = Invoke-Pester -Path
|
|
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 | sed -n '1p; 1q' | grep -q "."; then
|
|
88
|
-
echo "Running Pester tests in current directory..."
|
|
89
|
-
"$PWSH" -NoProfile -Command "
|
|
90
|
-
\$results = Invoke-Pester -CI -PassThru
|
|
126
|
+
"$PWSH" "${POWERSHELL_ARGS[@]}" "
|
|
127
|
+
\$results = Invoke-Pester -Path $test_paths -PassThru
|
|
91
128
|
if (\$results.FailedCount -gt 0) {
|
|
92
129
|
Write-Host \"FAILED: \$(\$results.FailedCount) test(s)\"
|
|
93
130
|
exit 1
|
|
@@ -110,18 +147,32 @@ run_coverage() {
|
|
|
110
147
|
return 0
|
|
111
148
|
fi
|
|
112
149
|
|
|
113
|
-
local
|
|
114
|
-
|
|
115
|
-
test_paths="tests/"
|
|
116
|
-
elif [ -d "test" ]; then
|
|
117
|
-
test_paths="test/"
|
|
118
|
-
fi
|
|
150
|
+
local POWERSHELL_ARGS
|
|
151
|
+
_powershell_invocation "$PWSH"
|
|
119
152
|
|
|
120
|
-
|
|
153
|
+
local test_files=()
|
|
154
|
+
local source_files=()
|
|
155
|
+
local discovery_file
|
|
156
|
+
local path
|
|
157
|
+
local test_paths
|
|
158
|
+
local coverage_paths
|
|
159
|
+
discovery_file=$(mktemp)
|
|
160
|
+
_find_powershell_files "*.Tests.ps1" > "$discovery_file"
|
|
161
|
+
# Discovery is line-delimited; filenames containing newlines are unsupported.
|
|
162
|
+
while IFS= read -r path; do
|
|
163
|
+
test_files[${#test_files[@]}]="$path"
|
|
164
|
+
done < "$discovery_file"
|
|
165
|
+
if [ "${#test_files[@]}" -gt 0 ]; then
|
|
166
|
+
_find_powershell_files "*.ps1" | grep -v '\.Tests\.ps1$' > "$discovery_file"
|
|
167
|
+
while IFS= read -r path; do
|
|
168
|
+
source_files[${#source_files[@]}]="$path"
|
|
169
|
+
done < "$discovery_file"
|
|
170
|
+
rm -f "$discovery_file"
|
|
171
|
+
test_paths=$(_powershell_path_array "${test_files[@]}")
|
|
172
|
+
coverage_paths=$(_powershell_path_array "${source_files[@]}")
|
|
121
173
|
echo "Running Pester with code coverage..."
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
\$results = Invoke-Pester -Path '$path_arg' -CodeCoverage @(Get-ChildItem -Path . -Filter *.ps1 -Recurse -Exclude *.Tests.ps1) -PassThru
|
|
174
|
+
"$PWSH" "${POWERSHELL_ARGS[@]}" "
|
|
175
|
+
\$results = Invoke-Pester -Path $test_paths -CodeCoverage $coverage_paths -PassThru
|
|
125
176
|
\$pct = [math]::Round(\$results.CodeCoverage.CoveragePercent, 1)
|
|
126
177
|
Write-Host \"Coverage: \$pct%\"
|
|
127
178
|
if (\$pct -lt 80) {
|
|
@@ -132,6 +183,7 @@ run_coverage() {
|
|
|
132
183
|
" 2>&1
|
|
133
184
|
return $?
|
|
134
185
|
else
|
|
186
|
+
rm -f "$discovery_file"
|
|
135
187
|
echo "No Pester tests found for coverage measurement"
|
|
136
188
|
return 0
|
|
137
189
|
fi
|
package/adapters/typescript.sh
CHANGED
|
@@ -107,10 +107,10 @@ run_lint() {
|
|
|
107
107
|
run_tests() {
|
|
108
108
|
if command -v npx >/dev/null 2>&1; then
|
|
109
109
|
echo "Running TypeScript tests..."
|
|
110
|
-
if npx vitest --version >/dev/null 2>&1; then
|
|
111
|
-
npx vitest run
|
|
112
|
-
elif npx jest --version >/dev/null 2>&1; then
|
|
113
|
-
npx jest --passWithNoTests
|
|
110
|
+
if run_without_git_context npx vitest --version >/dev/null 2>&1; then
|
|
111
|
+
run_without_git_context npx vitest run
|
|
112
|
+
elif run_without_git_context npx jest --version >/dev/null 2>&1; then
|
|
113
|
+
run_without_git_context npx jest --passWithNoTests
|
|
114
114
|
else
|
|
115
115
|
echo "No test runner available (vitest or jest required)"
|
|
116
116
|
return 1
|
|
@@ -125,10 +125,10 @@ run_tests() {
|
|
|
125
125
|
run_coverage() {
|
|
126
126
|
if command -v npx >/dev/null 2>&1; then
|
|
127
127
|
echo "Running TypeScript coverage..."
|
|
128
|
-
if npx vitest --version >/dev/null 2>&1; then
|
|
129
|
-
npx vitest run --coverage
|
|
130
|
-
elif npx jest --version >/dev/null 2>&1; then
|
|
131
|
-
npx jest --coverage
|
|
128
|
+
if run_without_git_context npx vitest --version >/dev/null 2>&1; then
|
|
129
|
+
run_without_git_context npx vitest run --coverage
|
|
130
|
+
elif run_without_git_context npx jest --version >/dev/null 2>&1; then
|
|
131
|
+
run_without_git_context npx jest --coverage
|
|
132
132
|
else
|
|
133
133
|
echo "No test runner available for coverage"
|
|
134
134
|
return 1
|
|
@@ -321,6 +321,28 @@ describe('runImportCheck', () => {
|
|
|
321
321
|
expect(result.violations[0].reason).toMatch(/not found|does not exist|missing/i);
|
|
322
322
|
});
|
|
323
323
|
|
|
324
|
+
it('skips YAML files containing JavaScript-like require text', async () => {
|
|
325
|
+
const workflowDir = path.join(tmpDir, '.github', 'workflows');
|
|
326
|
+
await fs.mkdir(workflowDir, { recursive: true });
|
|
327
|
+
|
|
328
|
+
const workflowFile = path.join(workflowDir, 'cross-platform-ci.yml');
|
|
329
|
+
await fs.writeFile(workflowFile, `run: node -e "require('../test')"\n`);
|
|
330
|
+
|
|
331
|
+
const result = await runImportCheck([workflowFile], tmpDir, 30000);
|
|
332
|
+
expect(result.status).toBe('pass');
|
|
333
|
+
expect(result.violations).toEqual([]);
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
it('still reports missing relative imports in supported JavaScript modules', async () => {
|
|
337
|
+
const sourceFile = path.join(tmpDir, 'source.mjs');
|
|
338
|
+
await fs.writeFile(sourceFile, `import './missing.js';\n`);
|
|
339
|
+
|
|
340
|
+
const result = await runImportCheck([sourceFile], tmpDir, 30000);
|
|
341
|
+
expect(result.status).toBe('fail');
|
|
342
|
+
expect(result.violations).toHaveLength(1);
|
|
343
|
+
expect(result.violations[0].importPath).toBe('./missing.js');
|
|
344
|
+
});
|
|
345
|
+
|
|
324
346
|
it('returns pass when only bare npm imports are used', async () => {
|
|
325
347
|
const srcDir = path.join(tmpDir, 'src');
|
|
326
348
|
await fs.mkdir(srcDir);
|
|
@@ -12,7 +12,7 @@ import os from 'os';
|
|
|
12
12
|
|
|
13
13
|
import { runGate10, main } from '../gate-10';
|
|
14
14
|
|
|
15
|
-
vi.setConfig({ testTimeout:
|
|
15
|
+
vi.setConfig({ testTimeout: 90000 });
|
|
16
16
|
|
|
17
17
|
describe('runGate10', () => {
|
|
18
18
|
let tmpDir: string;
|
|
@@ -215,7 +215,6 @@ describe('runGate10', () => {
|
|
|
215
215
|
*/
|
|
216
216
|
describe('main', () => {
|
|
217
217
|
let tmpDir: string;
|
|
218
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
219
218
|
let consoleSpy: any;
|
|
220
219
|
|
|
221
220
|
beforeEach(async () => {
|
|
@@ -38,6 +38,11 @@ import type {
|
|
|
38
38
|
*/
|
|
39
39
|
|
|
40
40
|
const execFileAsync = promisify(execFile);
|
|
41
|
+
const SUPPORTED_MODULE_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs']);
|
|
42
|
+
|
|
43
|
+
function isSupportedModuleFile(file: string): boolean {
|
|
44
|
+
return SUPPORTED_MODULE_EXTENSIONS.has(path.extname(file));
|
|
45
|
+
}
|
|
41
46
|
|
|
42
47
|
/**
|
|
43
48
|
* Gate 10: Build Integrity Check — TypeScript compilation verification.
|
|
@@ -303,6 +308,8 @@ export async function runImportCheck(
|
|
|
303
308
|
const fsSync = fsNative;
|
|
304
309
|
|
|
305
310
|
for (const file of changedFiles) {
|
|
311
|
+
if (!isSupportedModuleFile(file)) continue;
|
|
312
|
+
|
|
306
313
|
// Skip test files — they contain intentionally broken imports for unit testing.
|
|
307
314
|
// The published npm package does not include __tests__ directories.
|
|
308
315
|
if (file.includes('__tests__')) continue;
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# ============================================================================
|
|
2
|
+
# GATE 12: File Hygiene Check
|
|
3
|
+
# Detects common file quality issues in staged files:
|
|
4
|
+
# - Trailing whitespace
|
|
5
|
+
# - Missing EOF newline
|
|
6
|
+
# - Merge conflict markers (<<<<<<< , =======, >>>>>>>)
|
|
7
|
+
# - Oversized files (>1MB default, configurable)
|
|
8
|
+
# ============================================================================
|
|
9
|
+
|
|
10
|
+
2>&1 echo ""
|
|
11
|
+
2>&1 echo "→ Gate 12: File hygiene check..."
|
|
12
|
+
GATE_12_START=$(gate_start_ms)
|
|
13
|
+
|
|
14
|
+
# Configuration (can be overridden via environment)
|
|
15
|
+
MAX_FILE_SIZE_BYTES="${XP_GATE_MAX_FILE_SIZE:-1048576}" # 1MB default
|
|
16
|
+
|
|
17
|
+
# Get list of staged files (excluding deleted files)
|
|
18
|
+
STAGED_FILES=$(git diff --cached --name-only --diff-filter=d 2>/dev/null)
|
|
19
|
+
|
|
20
|
+
if [ -z "$STAGED_FILES" ]; then
|
|
21
|
+
echo " ℹ️ No staged files — skipping"
|
|
22
|
+
echo " ✅ PASSED - File Hygiene (no files to check)"
|
|
23
|
+
GATE_12_STATUS="SKIP"
|
|
24
|
+
record_gate_audit "gate-12" "file-hygiene" "$GATE_12_STATUS" "0" "$GATE_12_START"
|
|
25
|
+
return 0 2>/dev/null || true
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
HYGIENE_ISSUES=0
|
|
29
|
+
HYGIENE_FILES=""
|
|
30
|
+
|
|
31
|
+
# --- Check 1: Trailing whitespace ---
|
|
32
|
+
TRAILING_WS_FILES=""
|
|
33
|
+
while IFS= read -r file; do
|
|
34
|
+
[ -z "$file" ] && continue
|
|
35
|
+
# Skip binary files by checking if file contains null bytes
|
|
36
|
+
if git diff --cached --no-color -- "$file" 2>/dev/null | grep -q $'\x00'; then
|
|
37
|
+
continue
|
|
38
|
+
fi
|
|
39
|
+
# Check staged content for trailing whitespace (spaces/tabs at end of lines)
|
|
40
|
+
if git show ":$file" 2>/dev/null | grep -qE '[[:space:]]$'; then
|
|
41
|
+
TRAILING_WS_FILES="$TRAILING_WS_FILES $file"
|
|
42
|
+
fi
|
|
43
|
+
done <<EOF
|
|
44
|
+
$STAGED_FILES
|
|
45
|
+
EOF
|
|
46
|
+
|
|
47
|
+
if [ -n "$TRAILING_WS_FILES" ]; then
|
|
48
|
+
echo " ⚠️ Trailing whitespace detected in:"
|
|
49
|
+
for f in $TRAILING_WS_FILES; do
|
|
50
|
+
echo " - $f"
|
|
51
|
+
done
|
|
52
|
+
HYGIENE_ISSUES=$((HYGIENE_ISSUES + 1))
|
|
53
|
+
HYGIENE_FILES="$HYGIENE_FILES trailing-whitespace"
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# --- Check 2: Missing EOF newline ---
|
|
57
|
+
NO_EOF_NEWLINE_FILES=""
|
|
58
|
+
while IFS= read -r file; do
|
|
59
|
+
[ -z "$file" ] && continue
|
|
60
|
+
# Skip binary files
|
|
61
|
+
if git diff --cached --no-color -- "$file" 2>/dev/null | grep -q $'\x00'; then
|
|
62
|
+
continue
|
|
63
|
+
fi
|
|
64
|
+
# Check if file content ends with newline
|
|
65
|
+
FILE_CONTENT=$(git show ":$file" 2>/dev/null)
|
|
66
|
+
if [ -n "$FILE_CONTENT" ]; then
|
|
67
|
+
LAST_CHAR=$(printf '%s' "$FILE_CONTENT" | tail -c 1)
|
|
68
|
+
if [ "$LAST_CHAR" != "" ]; then
|
|
69
|
+
NO_EOF_NEWLINE_FILES="$NO_EOF_NEWLINE_FILES $file"
|
|
70
|
+
fi
|
|
71
|
+
fi
|
|
72
|
+
done <<EOF
|
|
73
|
+
$STAGED_FILES
|
|
74
|
+
EOF
|
|
75
|
+
|
|
76
|
+
if [ -n "$NO_EOF_NEWLINE_FILES" ]; then
|
|
77
|
+
echo " ⚠️ Missing EOF newline in:"
|
|
78
|
+
for f in $NO_EOF_NEWLINE_FILES; do
|
|
79
|
+
echo " - $f"
|
|
80
|
+
done
|
|
81
|
+
HYGIENE_ISSUES=$((HYGIENE_ISSUES + 1))
|
|
82
|
+
HYGIENE_FILES="$HYGIENE_FILES no-eof-newline"
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# --- Check 3: Merge conflict markers ---
|
|
86
|
+
CONFLICT_MARKER_FILES=""
|
|
87
|
+
while IFS= read -r file; do
|
|
88
|
+
[ -z "$file" ] && continue
|
|
89
|
+
# Skip binary files
|
|
90
|
+
if git diff --cached --no-color -- "$file" 2>/dev/null | grep -q $'\x00'; then
|
|
91
|
+
continue
|
|
92
|
+
fi
|
|
93
|
+
# Check for conflict markers in staged content
|
|
94
|
+
if git show ":$file" 2>/dev/null | grep -qE '^(<<<<<<<|=======|>>>>>>>)'; then
|
|
95
|
+
CONFLICT_MARKER_FILES="$CONFLICT_MARKER_FILES $file"
|
|
96
|
+
fi
|
|
97
|
+
done <<EOF
|
|
98
|
+
$STAGED_FILES
|
|
99
|
+
EOF
|
|
100
|
+
|
|
101
|
+
if [ -n "$CONFLICT_MARKER_FILES" ]; then
|
|
102
|
+
echo " ❌ Merge conflict markers detected in:"
|
|
103
|
+
for f in $CONFLICT_MARKER_FILES; do
|
|
104
|
+
echo " - $f"
|
|
105
|
+
done
|
|
106
|
+
HYGIENE_ISSUES=$((HYGIENE_ISSUES + 1))
|
|
107
|
+
HYGIENE_FILES="$HYGIENE_FILES conflict-markers"
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
# --- Check 4: Oversized files ---
|
|
111
|
+
OVERSIZED_FILES=""
|
|
112
|
+
while IFS= read -r file; do
|
|
113
|
+
[ -z "$file" ] && continue
|
|
114
|
+
[ ! -f "$file" ] && continue
|
|
115
|
+
FILE_SIZE=$(wc -c < "$file" 2>/dev/null | tr -d ' ')
|
|
116
|
+
if [ -n "$FILE_SIZE" ] && [ "$FILE_SIZE" -gt "$MAX_FILE_SIZE_BYTES" ]; then
|
|
117
|
+
SIZE_MB=$((FILE_SIZE / 1048576))
|
|
118
|
+
OVERSIZED_FILES="$OVERSIZED_FILES $file(${SIZE_MB}MB)"
|
|
119
|
+
fi
|
|
120
|
+
done <<EOF
|
|
121
|
+
$STAGED_FILES
|
|
122
|
+
EOF
|
|
123
|
+
|
|
124
|
+
if [ -n "$OVERSIZED_FILES" ]; then
|
|
125
|
+
echo " ⚠️ Oversized files (>${MAX_FILE_SIZE_BYTES} bytes):"
|
|
126
|
+
for f in $OVERSIZED_FILES; do
|
|
127
|
+
echo " - $f"
|
|
128
|
+
done
|
|
129
|
+
HYGIENE_ISSUES=$((HYGIENE_ISSUES + 1))
|
|
130
|
+
HYGIENE_FILES="$HYGIENE_FILES oversized-files"
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
# --- Check 5: YAML/JSON syntax validation (Issue #351) ---
|
|
134
|
+
# Only check staged YAML/JSON files that have changes
|
|
135
|
+
YAML_JSON_ERRORS=""
|
|
136
|
+
YAML_JSON_CHECK_COUNT=0
|
|
137
|
+
|
|
138
|
+
# Detect available validators
|
|
139
|
+
YAML_CMD=""
|
|
140
|
+
if command -v python3 >/dev/null 2>&1; then
|
|
141
|
+
YAML_CMD="python3"
|
|
142
|
+
elif command -v python >/dev/null 2>&1; then
|
|
143
|
+
YAML_CMD="python"
|
|
144
|
+
fi
|
|
145
|
+
|
|
146
|
+
JSON_CMD=""
|
|
147
|
+
if command -v node >/dev/null 2>&1; then
|
|
148
|
+
JSON_CMD="node"
|
|
149
|
+
elif command -v jq >/dev/null 2>&1; then
|
|
150
|
+
JSON_CMD="jq"
|
|
151
|
+
fi
|
|
152
|
+
|
|
153
|
+
while IFS= read -r file; do
|
|
154
|
+
[ -z "$file" ] && continue
|
|
155
|
+
[ ! -f "$file" ] && continue
|
|
156
|
+
|
|
157
|
+
case "$file" in
|
|
158
|
+
*.yml|*.yaml)
|
|
159
|
+
if [ -n "$YAML_CMD" ]; then
|
|
160
|
+
YAML_JSON_CHECK_COUNT=$((YAML_JSON_CHECK_COUNT + 1))
|
|
161
|
+
# Validate YAML syntax using Python's yaml module
|
|
162
|
+
YAML_ERROR=$(git show ":$file" 2>/dev/null | $YAML_CMD -c "
|
|
163
|
+
import sys, yaml
|
|
164
|
+
try:
|
|
165
|
+
yaml.safe_load(sys.stdin.read())
|
|
166
|
+
except yaml.YAMLError as e:
|
|
167
|
+
print(str(e).split(chr(10))[0])
|
|
168
|
+
sys.exit(1)
|
|
169
|
+
except Exception:
|
|
170
|
+
pass
|
|
171
|
+
" 2>&1)
|
|
172
|
+
if [ $? -ne 0 ] && [ -n "$YAML_ERROR" ]; then
|
|
173
|
+
YAML_JSON_ERRORS="$YAML_JSON_ERRORS $file(yaml:$YAML_ERROR)"
|
|
174
|
+
fi
|
|
175
|
+
fi
|
|
176
|
+
;;
|
|
177
|
+
*.json)
|
|
178
|
+
YAML_JSON_CHECK_COUNT=$((YAML_JSON_CHECK_COUNT + 1))
|
|
179
|
+
if [ "$JSON_CMD" = "node" ]; then
|
|
180
|
+
JSON_ERROR=$(git show ":$file" 2>/dev/null | node -e "
|
|
181
|
+
let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{JSON.parse(d)}catch(e){console.log(e.message.split('\\n')[0]);process.exit(1)}})
|
|
182
|
+
" 2>&1)
|
|
183
|
+
if [ $? -ne 0 ] && [ -n "$JSON_ERROR" ]; then
|
|
184
|
+
YAML_JSON_ERRORS="$YAML_JSON_ERRORS $file(json:$JSON_ERROR)"
|
|
185
|
+
fi
|
|
186
|
+
elif [ "$JSON_CMD" = "jq" ]; then
|
|
187
|
+
JSON_ERROR=$(git show ":$file" 2>/dev/null | jq empty 2>&1)
|
|
188
|
+
if [ $? -ne 0 ] && [ -n "$JSON_ERROR" ]; then
|
|
189
|
+
YAML_JSON_ERRORS="$YAML_JSON_ERRORS $file(json:syntax error)"
|
|
190
|
+
fi
|
|
191
|
+
fi
|
|
192
|
+
;;
|
|
193
|
+
esac
|
|
194
|
+
done <<EOF
|
|
195
|
+
$STAGED_FILES
|
|
196
|
+
EOF
|
|
197
|
+
|
|
198
|
+
if [ -n "$YAML_JSON_ERRORS" ]; then
|
|
199
|
+
echo " ❌ YAML/JSON syntax errors:"
|
|
200
|
+
for f in $YAML_JSON_ERRORS; do
|
|
201
|
+
echo " - $f"
|
|
202
|
+
done
|
|
203
|
+
HYGIENE_ISSUES=$((HYGIENE_ISSUES + 1))
|
|
204
|
+
HYGIENE_FILES="$HYGIENE_FILES yaml-json-syntax"
|
|
205
|
+
elif [ "$YAML_JSON_CHECK_COUNT" -gt 0 ]; then
|
|
206
|
+
echo " ✅ YAML/JSON syntax OK ($YAML_JSON_CHECK_COUNT file(s) checked)"
|
|
207
|
+
fi
|
|
208
|
+
|
|
209
|
+
# --- Result ---
|
|
210
|
+
if [ "$HYGIENE_ISSUES" -eq 0 ]; then
|
|
211
|
+
echo " ✅ PASSED - No file hygiene issues detected."
|
|
212
|
+
GATE_12_STATUS="PASS"
|
|
213
|
+
else
|
|
214
|
+
# Hard blocks: conflict markers + YAML/JSON syntax errors
|
|
215
|
+
if [ -n "$CONFLICT_MARKER_FILES" ] || [ -n "$YAML_JSON_ERRORS" ]; then
|
|
216
|
+
echo ""
|
|
217
|
+
echo "❌ BLOCKED - File hygiene violations must be fixed before commit."
|
|
218
|
+
GATE_12_STATUS="BLOCK"
|
|
219
|
+
record_gate_audit "gate-12" "file-hygiene" "$GATE_12_STATUS" "$HYGIENE_ISSUES" "$GATE_12_START"
|
|
220
|
+
exit 1
|
|
221
|
+
else
|
|
222
|
+
echo ""
|
|
223
|
+
echo " ⚠️ WARNINGS - $HYGIENE_ISSUES file hygiene issue(s) found."
|
|
224
|
+
echo " Fix recommended but not blocking (no conflict markers or syntax errors)."
|
|
225
|
+
echo " Issues:$HYGIENE_FILES"
|
|
226
|
+
GATE_12_STATUS="WARN"
|
|
227
|
+
fi
|
|
228
|
+
fi
|
|
229
|
+
|
|
230
|
+
record_gate_audit "gate-12" "file-hygiene" "$GATE_12_STATUS" "$HYGIENE_ISSUES" "$GATE_12_START"
|
package/hooks/adapter-common.sh
CHANGED
|
@@ -27,6 +27,17 @@ detect_os_env() {
|
|
|
27
27
|
esac
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
# Git exports repository-local variables to hooks. Child test processes must
|
|
31
|
+
# not inherit them, or nested git repositories modify the caller's repository.
|
|
32
|
+
run_without_git_context() (
|
|
33
|
+
unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_CONFIG GIT_CONFIG_PARAMETERS
|
|
34
|
+
unset GIT_CONFIG_COUNT GIT_OBJECT_DIRECTORY GIT_DIR GIT_WORK_TREE
|
|
35
|
+
unset GIT_IMPLICIT_WORK_TREE GIT_GRAFT_FILE GIT_INDEX_FILE
|
|
36
|
+
unset GIT_NO_REPLACE_OBJECTS GIT_REPLACE_REF_BASE GIT_PREFIX
|
|
37
|
+
unset GIT_SHALLOW_FILE GIT_COMMON_DIR
|
|
38
|
+
"$@"
|
|
39
|
+
)
|
|
40
|
+
|
|
30
41
|
detect_project_lang() {
|
|
31
42
|
if [ -f "tsconfig.json" ]; then
|
|
32
43
|
echo "typescript"
|
|
@@ -241,6 +252,22 @@ detect_go_mutation_testable() {
|
|
|
241
252
|
fi
|
|
242
253
|
return 1
|
|
243
254
|
}
|
|
255
|
+
|
|
256
|
+
# Check if any changed file matches any of the given regex patterns.
|
|
257
|
+
# Usage: any_changed_files_match "\.ts$" "\.py$"
|
|
258
|
+
# Returns 0 (true) if at least one changed file matches any pattern, 1 (false) otherwise.
|
|
259
|
+
any_changed_files_match() {
|
|
260
|
+
if [ -z "${CHANGED_FILES:-}" ]; then
|
|
261
|
+
return 1
|
|
262
|
+
fi
|
|
263
|
+
for pattern in "$@"; do
|
|
264
|
+
if echo "$CHANGED_FILES" | grep -qE "$pattern" 2>/dev/null; then
|
|
265
|
+
return 0
|
|
266
|
+
fi
|
|
267
|
+
done
|
|
268
|
+
return 1
|
|
269
|
+
}
|
|
270
|
+
|
|
244
271
|
# Detect if a Java/Kotlin project has PITest (pitest-maven or pitest-gradle) configured
|
|
245
272
|
detect_pitest_testable() {
|
|
246
273
|
# Check for Maven + pitest-maven plugin
|