claude-flow-novice 2.15.6 → 2.15.7

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 (113) hide show
  1. package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +39 -577
  2. package/.claude/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +49 -270
  3. package/.claude/skills/cfn-loop-orchestration/src/helpers/consensus.ts +87 -0
  4. package/.claude/skills/cfn-loop-orchestration/src/helpers/gate-check.ts +115 -0
  5. package/.claude/skills/cfn-loop-orchestration/src/helpers/parse-test-results.ts +372 -0
  6. package/.claude/skills/cfn-loop-orchestration/tests/consensus.test.ts +142 -0
  7. package/.claude/skills/cfn-loop-orchestration/tests/deliverable-verifier.test.ts +199 -0
  8. package/.claude/skills/cfn-loop-orchestration/tests/gate-check.test.ts +325 -0
  9. package/.claude/skills/cfn-loop-orchestration/tests/iteration-manager.test.ts +132 -0
  10. package/.claude/skills/cfn-loop-orchestration/tests/parse-test-results.test.ts +382 -0
  11. package/.claude/skills/cfn-loop-orchestration/tests/timeout-calculator.test.ts +118 -0
  12. package/.claude/skills/cfn-redis-coordination/coverage/clover.xml +1447 -0
  13. package/.claude/skills/cfn-redis-coordination/coverage/coverage-final.json +13 -0
  14. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/agent-logger.ts.html +1423 -0
  15. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/agent-recovery.ts.html +1447 -0
  16. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/base.css +224 -0
  17. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/block-navigation.js +87 -0
  18. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/completion-reporter.ts.html +1273 -0
  19. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/context-manager.ts.html +1066 -0
  20. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/favicon.png +0 -0
  21. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/index.html +281 -0
  22. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/mode-detector.ts.html +550 -0
  23. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/prettify.css +1 -0
  24. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/prettify.js +2 -0
  25. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/redis-client.ts.html +2047 -0
  26. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/result-collector.ts.html +1396 -0
  27. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  28. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/sorter.js +210 -0
  29. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/swarm-manager.ts.html +1567 -0
  30. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/task-analyzer.ts.html +1297 -0
  31. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/task-executor.ts.html +1354 -0
  32. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/types.ts.html +790 -0
  33. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/waiting-coordinator.ts.html +1846 -0
  34. package/.claude/skills/cfn-redis-coordination/coverage/lcov.info +2650 -0
  35. package/.claude/skills/cfn-redis-coordination/dist/task-analyzer.js +1 -1
  36. package/.claude/skills/cfn-redis-coordination/src/task-analyzer.ts +1 -1
  37. package/.claude/skills/cfn-redis-coordination/tests/coordination.test.ts +18 -9
  38. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +13 -72
  39. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +5 -65
  40. package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +465 -508
  41. package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +733 -743
  42. package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +13 -79
  43. package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +13 -18
  44. package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +13 -18
  45. package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +13 -18
  46. package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +15 -17
  47. package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +15 -17
  48. package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +15 -14
  49. package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +15 -17
  50. package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +15 -17
  51. package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +15 -17
  52. package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +23 -30
  53. package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +13 -18
  54. package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +13 -18
  55. package/claude-assets/agents/cfn-dev-team/reviewers/code-reviewer.md +312 -317
  56. package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +23 -20
  57. package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +23 -20
  58. package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +23 -20
  59. package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +23 -20
  60. package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +15 -20
  61. package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +15 -20
  62. package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +718 -737
  63. package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +817 -828
  64. package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +15 -20
  65. package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +8 -9
  66. package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +668 -684
  67. package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +15 -20
  68. package/claude-assets/agents/cfn-dev-team/testers/tester.md +248 -253
  69. package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +13 -18
  70. package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +13 -18
  71. package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +13 -18
  72. package/claude-assets/skills/cfn-loop-orchestration/helpers/gate-check.sh +39 -577
  73. package/claude-assets/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +49 -270
  74. package/claude-assets/skills/cfn-loop-orchestration/src/helpers/gate-check.ts +115 -0
  75. package/claude-assets/skills/cfn-loop-orchestration/src/helpers/parse-test-results.ts +372 -0
  76. package/claude-assets/skills/cfn-loop-orchestration/tests/consensus.test.ts +142 -0
  77. package/claude-assets/skills/cfn-loop-orchestration/tests/deliverable-verifier.test.ts +199 -0
  78. package/claude-assets/skills/cfn-loop-orchestration/tests/gate-check.test.ts +325 -0
  79. package/claude-assets/skills/cfn-loop-orchestration/tests/iteration-manager.test.ts +132 -0
  80. package/claude-assets/skills/cfn-loop-orchestration/tests/parse-test-results.test.ts +382 -0
  81. package/claude-assets/skills/cfn-loop-orchestration/tests/timeout-calculator.test.ts +118 -0
  82. package/claude-assets/skills/cfn-redis-coordination/coverage/clover.xml +1447 -0
  83. package/claude-assets/skills/cfn-redis-coordination/coverage/coverage-final.json +13 -0
  84. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/agent-logger.ts.html +1423 -0
  85. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/agent-recovery.ts.html +1447 -0
  86. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/base.css +224 -0
  87. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/block-navigation.js +87 -0
  88. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/completion-reporter.ts.html +1273 -0
  89. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/context-manager.ts.html +1066 -0
  90. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/favicon.png +0 -0
  91. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/index.html +281 -0
  92. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/mode-detector.ts.html +550 -0
  93. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/prettify.css +1 -0
  94. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/prettify.js +2 -0
  95. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/redis-client.ts.html +2047 -0
  96. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/result-collector.ts.html +1396 -0
  97. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  98. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/sorter.js +210 -0
  99. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/swarm-manager.ts.html +1567 -0
  100. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/task-analyzer.ts.html +1297 -0
  101. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/task-executor.ts.html +1354 -0
  102. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/types.ts.html +790 -0
  103. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/waiting-coordinator.ts.html +1846 -0
  104. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov.info +2650 -0
  105. package/claude-assets/skills/cfn-redis-coordination/dist/task-analyzer.js +1 -1
  106. package/claude-assets/skills/cfn-redis-coordination/src/task-analyzer.ts +1 -1
  107. package/claude-assets/skills/cfn-redis-coordination/tests/coordination.test.ts +18 -9
  108. package/dist/agents/agent-loader.js +165 -146
  109. package/dist/agents/agent-loader.js.map +1 -1
  110. package/dist/cli/config-manager.js +91 -109
  111. package/dist/cli/config-manager.js.map +1 -1
  112. package/package.json +1 -1
  113. package/scripts/clean-agent-profiles.sh +112 -0
@@ -1,277 +1,56 @@
1
1
  #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- parse_jest_output() {
5
- local output="$1"
6
- local total=0 passed=0 failed=0 skipped=0 duration=0
7
- local failed_names=()
8
-
9
- local tests_line=$(echo "$output" | grep "^Tests:" || echo "")
10
-
11
- if [ -n "$tests_line" ]; then
12
- [[ "$tests_line" =~ ([0-9]+)[[:space:]]*passed ]] && passed="${BASH_REMATCH[1]}"
13
- [[ "$tests_line" =~ ([0-9]+)[[:space:]]*failed ]] && failed="${BASH_REMATCH[1]}"
14
- [[ "$tests_line" =~ ([0-9]+)[[:space:]]*skipped ]] && skipped="${BASH_REMATCH[1]}"
15
- [[ "$tests_line" =~ ([0-9]+)[[:space:]]*total ]] && total="${BASH_REMATCH[1]}"
16
- fi
17
-
18
- # OPTIMIZATION: Replace bc with BASH arithmetic (75-150ms savings)
19
- if [[ "$output" =~ Time:[[:space:]]*([0-9.]+)[[:space:]]*s ]]; then
20
- duration=$(awk "BEGIN {printf \"%.0f\", ${BASH_REMATCH[1]} * 1000}")
21
- fi
22
-
23
- while IFS= read -r line; do
24
- [[ "$line" =~ ●[[:space:]]*(.*) ]] && failed_names+=("${BASH_REMATCH[1]}")
25
- done <<< "$output"
26
-
27
- # OPTIMIZATION: Replace bc with awk
28
- local pass_rate="0.0000"
29
- if [ "$total" -gt 0 ]; then
30
- pass_rate=$(awk "BEGIN {printf \"%.4f\", $passed / $total}")
31
- fi
32
-
33
- # OPTIMIZATION: Single jq call
34
- local failed_names_json="[]"
35
- [ ${#failed_names[@]} -gt 0 ] && failed_names_json=$(printf '%s\n' "${failed_names[@]}" | jq -Rs 'split("\n") | map(select(length > 0))')
36
-
37
- cat <<EOF
38
- {"framework":"jest","total_tests":$total,"passed_tests":$passed,"failed_tests":$failed,"skipped_tests":$skipped,"pass_rate":$pass_rate,"duration_ms":$duration,"failed_test_names":$failed_names_json}
39
- EOF
40
- }
41
-
42
- parse_mocha_output() {
43
- local output="$1"
44
- local total=0 passed=0 failed=0 skipped=0 duration=0
45
- local failed_names=()
46
-
47
- [[ "$output" =~ ([0-9]+)[[:space:]]*passing ]] && passed="${BASH_REMATCH[1]}"
48
- [[ "$output" =~ ([0-9]+)[[:space:]]*failing ]] && failed="${BASH_REMATCH[1]}"
49
- [[ "$output" =~ ([0-9]+)[[:space:]]*pending ]] && skipped="${BASH_REMATCH[1]}"
50
- total=$((passed + failed + skipped))
51
-
52
- # OPTIMIZATION: Replace bc with awk
53
- if [[ "$output" =~ passing[[:space:]]*\(([0-9]+)ms\) ]]; then
54
- duration="${BASH_REMATCH[1]}"
55
- elif [[ "$output" =~ passing[[:space:]]*\(([0-9.]+)s\) ]]; then
56
- duration=$(awk "BEGIN {printf \"%.0f\", ${BASH_REMATCH[1]} * 1000}")
57
- fi
58
-
59
- while IFS= read -r line; do
60
- [[ "$line" =~ ^[[:space:]]*[0-9]+\)[[:space:]]*(.*): ]] && failed_names+=("${BASH_REMATCH[1]}")
61
- done <<< "$output"
62
-
63
- # OPTIMIZATION: Replace bc with awk
64
- local pass_rate="0.0000"
65
- if [ "$total" -gt 0 ]; then
66
- pass_rate=$(awk "BEGIN {printf \"%.4f\", $passed / $total}")
67
- fi
68
-
69
- # OPTIMIZATION: Single jq call
70
- local failed_names_json="[]"
71
- [ ${#failed_names[@]} -gt 0 ] && failed_names_json=$(printf '%s\n' "${failed_names[@]}" | jq -Rs 'split("\n") | map(select(length > 0))')
72
-
73
- cat <<EOF
74
- {"framework":"mocha","total_tests":$total,"passed_tests":$passed,"failed_tests":$failed,"skipped_tests":$skipped,"pass_rate":$pass_rate,"duration_ms":$duration,"failed_test_names":$failed_names_json}
75
- EOF
76
- }
77
-
78
- parse_pytest_output() {
79
- local output="$1"
80
- local total=0 passed=0 failed=0 skipped=0 duration=0
81
- local failed_names=()
82
-
83
- [[ "$output" =~ ([0-9]+)[[:space:]]*passed ]] && passed="${BASH_REMATCH[1]}"
84
- [[ "$output" =~ ([0-9]+)[[:space:]]*failed ]] && failed="${BASH_REMATCH[1]}"
85
- [[ "$output" =~ ([0-9]+)[[:space:]]*skipped ]] && skipped="${BASH_REMATCH[1]}"
86
- total=$((passed + failed + skipped))
87
-
88
- # OPTIMIZATION: Replace bc with awk
89
- [[ "$output" =~ in[[:space:]]+([0-9.]+)s ]] && duration=$(awk "BEGIN {printf \"%.0f\", ${BASH_REMATCH[1]} * 1000}")
90
-
91
- while IFS= read -r line; do
92
- [[ "$line" =~ FAILED[[:space:]]+([^[:space:]]+) ]] && failed_names+=("${BASH_REMATCH[1]}")
93
- done <<< "$output"
94
-
95
- # OPTIMIZATION: Replace bc with awk
96
- local pass_rate="0.0000"
97
- if [ "$total" -gt 0 ]; then
98
- pass_rate=$(awk "BEGIN {printf \"%.4f\", $passed / $total}")
99
- fi
100
-
101
- # OPTIMIZATION: Single jq call
102
- local failed_names_json="[]"
103
- [ ${#failed_names[@]} -gt 0 ] && failed_names_json=$(printf '%s\n' "${failed_names[@]}" | jq -Rs 'split("\n") | map(select(length > 0))')
104
-
105
- cat <<EOF
106
- {"framework":"pytest","total_tests":$total,"passed_tests":$passed,"failed_tests":$failed,"skipped_tests":$skipped,"pass_rate":$pass_rate,"duration_ms":$duration,"failed_test_names":$failed_names_json}
107
- EOF
108
- }
109
-
110
- parse_tap_output() {
111
- local output="$1"
112
- local total=0 passed=0 failed=0 skipped=0
113
- local failed_names=()
114
-
115
- [[ "$output" =~ 1\.\.([0-9]+) ]] && total="${BASH_REMATCH[1]}"
116
- passed=$(echo "$output" | grep -c "^ok " || true)
117
- failed=$(echo "$output" | grep -c "^not ok " || true)
118
- skipped=$(echo "$output" | grep -c "^ok .* # SKIP" || true)
119
- passed=$((passed - skipped))
120
-
121
- while IFS= read -r line; do
122
- [[ "$line" =~ ^not\ ok\ [0-9]+\ (.*) ]] && failed_names+=("${BASH_REMATCH[1]}")
123
- done <<< "$output"
124
-
125
- # OPTIMIZATION: Replace bc with awk
126
- local pass_rate="0.0000"
127
- if [ "$total" -gt 0 ]; then
128
- pass_rate=$(awk "BEGIN {printf \"%.4f\", $passed / $total}")
129
- fi
130
-
131
- # OPTIMIZATION: Single jq call
132
- local failed_names_json="[]"
133
- [ ${#failed_names[@]} -gt 0 ] && failed_names_json=$(printf '%s\n' "${failed_names[@]}" | jq -Rs 'split("\n") | map(select(length > 0))')
2
+ ##############################################################################
3
+ # Parse Test Results - TypeScript Wrapper
4
+ # Parses test output from multiple testing frameworks
5
+ #
6
+ # This is a wrapper script that delegates to the TypeScript implementation
7
+ # for better type safety and maintainability.
8
+ #
9
+ # Usage:
10
+ # parse-test-results.sh <framework|auto> <output_file_or_string>
11
+ #
12
+ # Frameworks:
13
+ # - jest: Jest testing framework
14
+ # - mocha: Mocha testing framework
15
+ # - pytest: Python pytest
16
+ # - tap: TAP (Test Anything Protocol)
17
+ # - go: Go test output
18
+ # - auto: Auto-detect framework
19
+ #
20
+ # Returns JSON:
21
+ # {
22
+ # "framework": "jest",
23
+ # "total": 10,
24
+ # "passed": 8,
25
+ # "failed": 2,
26
+ # "skipped": 0,
27
+ # "passRate": 0.8,
28
+ # "durationMs": 1234,
29
+ # "failedTestNames": ["test1", "test2"],
30
+ # "raw": "..."
31
+ # }
32
+ ##############################################################################
134
33
 
135
- cat <<EOF
136
- {"framework":"tap","total_tests":$total,"passed_tests":$passed,"failed_tests":$failed,"skipped_tests":$skipped,"pass_rate":$pass_rate,"duration_ms":0,"failed_test_names":$failed_names_json}
137
- EOF
138
- }
139
-
140
- parse_junit_xml() {
141
- local xml_file="$1"
142
- [ ! -f "$xml_file" ] && echo '{"error":"File not found"}' && return 1
143
-
144
- local total=0 failures=0 errors=0 skipped=0 duration=0
145
-
146
- if command -v xmllint &>/dev/null; then
147
- total=$(xmllint --xpath "sum(//testsuite/@tests)" "$xml_file" 2>/dev/null || echo "0")
148
- failures=$(xmllint --xpath "sum(//testsuite/@failures)" "$xml_file" 2>/dev/null || echo "0")
149
- errors=$(xmllint --xpath "sum(//testsuite/@errors)" "$xml_file" 2>/dev/null || echo "0")
150
- skipped=$(xmllint --xpath "sum(//testsuite/@skipped)" "$xml_file" 2>/dev/null || echo "0")
151
- duration=$(xmllint --xpath "sum(//testsuite/@time)" "$xml_file" 2>/dev/null || echo "0")
152
- else
153
- total=$(grep -oP 'tests="\K[0-9]+' "$xml_file" | awk '{s+=$1} END {print s}')
154
- failures=$(grep -oP 'failures="\K[0-9]+' "$xml_file" | awk '{s+=$1} END {print s}')
155
- errors=$(grep -oP 'errors="\K[0-9]+' "$xml_file" | awk '{s+=$1} END {print s}')
156
- skipped=$(grep -oP 'skipped="\K[0-9]+' "$xml_file" | awk '{s+=$1} END {print s}')
157
- duration=$(grep -oP 'time="\K[0-9.]+' "$xml_file" | awk '{s+=$1} END {print s}')
158
- fi
159
-
160
- total=${total:-0} failures=${failures:-0} errors=${errors:-0} skipped=${skipped:-0} duration=${duration:-0}
161
- local failed=$((failures + errors))
162
- local passed=$((total - failed - skipped))
163
-
164
- # OPTIMIZATION: Replace bc with awk
165
- local duration_ms=$(awk "BEGIN {printf \"%.0f\", $duration * 1000}")
166
-
167
- local pass_rate="0.0000"
168
- if [ "$total" -gt 0 ]; then
169
- pass_rate=$(awk "BEGIN {printf \"%.4f\", $passed / $total}")
170
- fi
171
-
172
- cat <<EOF
173
- {"framework":"junit","total_tests":$total,"passed_tests":$passed,"failed_tests":$failed,"skipped_tests":$skipped,"pass_rate":$pass_rate,"duration_ms":$duration_ms,"failed_test_names":[]}
174
- EOF
175
- }
176
-
177
- parse_go_test_output() {
178
- local output="$1"
179
- local total=0 passed=0 failed=0 skipped=0 duration=0
180
- local failed_names=()
181
-
182
- passed=$(echo "$output" | grep -c "^--- PASS:" || true)
183
- failed=$(echo "$output" | grep -c "^--- FAIL:" || true)
184
- skipped=$(echo "$output" | grep -c "^--- SKIP:" || true)
185
- total=$((passed + failed + skipped))
186
-
187
- while IFS= read -r line; do
188
- [[ "$line" =~ ^---\ FAIL:\ (.*) ]] && failed_names+=("${BASH_REMATCH[1]}")
189
- done <<< "$output"
190
-
191
- # OPTIMIZATION: Replace bc with awk
192
- [[ "$output" =~ ok[[:space:]]+[^[:space:]]+[[:space:]]+([0-9.]+)s ]] && duration=$(awk "BEGIN {printf \"%.0f\", ${BASH_REMATCH[1]} * 1000}")
193
-
194
- local pass_rate="0.0000"
195
- if [ "$total" -gt 0 ]; then
196
- pass_rate=$(awk "BEGIN {printf \"%.4f\", $passed / $total}")
197
- fi
198
-
199
- # OPTIMIZATION: Single jq call
200
- local failed_names_json="[]"
201
- [ ${#failed_names[@]} -gt 0 ] && failed_names_json=$(printf '%s\n' "${failed_names[@]}" | jq -Rs 'split("\n") | map(select(length > 0))')
202
-
203
- cat <<EOF
204
- {"framework":"go","total_tests":$total,"passed_tests":$passed,"failed_tests":$failed,"skipped_tests":$skipped,"pass_rate":$pass_rate,"duration_ms":$duration,"failed_test_names":$failed_names_json}
205
- EOF
206
- }
207
-
208
- auto_detect_framework() {
209
- local input="$1"
210
-
211
- if [ -f "$input" ]; then
212
- if grep -q "<testsuite" "$input" 2>/dev/null; then
213
- echo "junit"
214
- return 0
215
- fi
216
- input=$(cat "$input")
217
- fi
218
-
219
- if [[ "$input" =~ Test\ Suites: ]] || [[ "$input" =~ PASS[[:space:]]+.*\.test\.(js|ts) ]]; then
220
- echo "jest"
221
- return 0
222
- fi
223
-
224
- if [[ "$input" =~ [0-9]+\ passing ]] && [[ "$input" =~ [0-9]+\ failing ]]; then
225
- echo "mocha"
226
- return 0
227
- fi
228
-
229
- if [[ "$input" =~ ====.*passed.*==== ]] || [[ "$input" =~ FAILED.*\.py:: ]]; then
230
- echo "pytest"
231
- return 0
232
- fi
233
-
234
- if [[ "$input" =~ 1\.\.[0-9]+ ]] || [[ "$input" =~ ok\ [0-9]+ ]] || [[ "$input" =~ not\ ok\ [0-9]+ ]]; then
235
- echo "tap"
236
- return 0
237
- fi
238
-
239
- if [[ "$input" =~ ---\ PASS: ]] || [[ "$input" =~ ---\ FAIL: ]]; then
240
- echo "go"
241
- return 0
242
- fi
243
-
244
- echo "unknown"
245
- return 1
246
- }
247
-
248
- parse_test_results() {
249
- local framework="$1"
250
- local input="$2"
34
+ set -euo pipefail
251
35
 
252
- if [ "$framework" = "auto" ]; then
253
- framework=$(auto_detect_framework "$input")
254
- if [ "$framework" = "unknown" ]; then
255
- echo '{"error":"Unable to auto-detect testing framework"}'
256
- return 1
257
- fi
258
- fi
36
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
37
+ SKILL_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
259
38
 
260
- local output="$input"
261
- [ -f "$input" ] && output=$(cat "$input")
39
+ # Path to compiled TypeScript
40
+ TS_DIST="$SKILL_ROOT/dist/helpers/parse-test-results.js"
262
41
 
263
- case "$framework" in
264
- jest) parse_jest_output "$output" ;;
265
- mocha) parse_mocha_output "$output" ;;
266
- pytest) parse_pytest_output "$output" ;;
267
- tap) parse_tap_output "$output" ;;
268
- junit) parse_junit_xml "$input" ;;
269
- go) parse_go_test_output "$output" ;;
270
- *) echo '{"error":"Unknown framework"}' && return 1 ;;
271
- esac
272
- }
42
+ # Check if TypeScript implementation exists
43
+ if [ ! -f "$TS_DIST" ]; then
44
+ echo "❌ Error: TypeScript implementation not found at: $TS_DIST" >&2
45
+ echo " Run 'npm run build' in .claude/skills/cfn-loop-orchestration/" >&2
46
+ exit 1
47
+ fi
273
48
 
274
- if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
275
- [ $# -lt 2 ] && echo "Usage: $0 <framework|auto> <output_file_or_string>" && exit 1
276
- parse_test_results "$1" "$2"
49
+ # Check if node is available
50
+ if ! command -v node &>/dev/null; then
51
+ echo "❌ Error: Node.js is required but not found in PATH" >&2
52
+ exit 1
277
53
  fi
54
+
55
+ # Execute TypeScript implementation
56
+ exec node "$TS_DIST" "$@"
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Consensus Collection and Validation
3
+ * Collects Loop 2 validator scores and validates against thresholds
4
+ */
5
+
6
+ export interface ConsensusResult {
7
+ scores: number[];
8
+ average: number;
9
+ count: number;
10
+ min: number;
11
+ max: number;
12
+ }
13
+
14
+ export interface ConsensusValidation {
15
+ passed: boolean;
16
+ average: number;
17
+ threshold: number;
18
+ mode: string;
19
+ gap: number;
20
+ }
21
+
22
+ export type Mode = 'mvp' | 'standard' | 'enterprise';
23
+
24
+ const MODE_THRESHOLDS: Record<Mode, number> = {
25
+ mvp: 0.80,
26
+ standard: 0.90,
27
+ enterprise: 0.95
28
+ };
29
+
30
+ /**
31
+ * Collects consensus scores from multiple validators
32
+ * @param scores Array of validator confidence scores (0.0-1.0)
33
+ * @returns ConsensusResult with statistics
34
+ */
35
+ export function collectConsensus(scores: number[]): ConsensusResult {
36
+ if (!scores || scores.length === 0) {
37
+ throw new Error('No consensus scores provided');
38
+ }
39
+
40
+ // Validate all scores are in valid range
41
+ for (const score of scores) {
42
+ if (score < 0 || score > 1.0) {
43
+ throw new Error(`Invalid consensus score: ${score} (must be 0.0-1.0)`);
44
+ }
45
+ }
46
+
47
+ // Calculate statistics
48
+ const sum = scores.reduce((acc, score) => acc + score, 0);
49
+ const average = sum / scores.length;
50
+ const min = Math.min(...scores);
51
+ const max = Math.max(...scores);
52
+
53
+ return {
54
+ scores,
55
+ average,
56
+ count: scores.length,
57
+ min,
58
+ max
59
+ };
60
+ }
61
+
62
+ /**
63
+ * Validates consensus against mode-specific threshold
64
+ * @param params Validation parameters
65
+ * @returns ConsensusValidation result
66
+ */
67
+ export function validateConsensus(params: {
68
+ average: number;
69
+ threshold?: number;
70
+ mode: Mode | string;
71
+ }): ConsensusValidation {
72
+ // Use explicit threshold if provided, otherwise use mode default
73
+ const threshold = params.threshold !== undefined
74
+ ? params.threshold
75
+ : MODE_THRESHOLDS[params.mode as Mode] || 0.90;
76
+
77
+ const passed = params.average >= threshold;
78
+ const gap = params.average - threshold;
79
+
80
+ return {
81
+ passed,
82
+ average: params.average,
83
+ threshold,
84
+ mode: params.mode,
85
+ gap
86
+ };
87
+ }
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Gate Check Helper - Test-Driven Validation
3
+ * Validates Loop 3 self-assessment against test pass rate thresholds
4
+ */
5
+
6
+ export type Mode = 'mvp' | 'standard' | 'enterprise';
7
+
8
+ export interface GateCheckParams {
9
+ passRate: number;
10
+ threshold?: number;
11
+ mode: Mode;
12
+ }
13
+
14
+ export interface GateCheckResult {
15
+ passed: boolean;
16
+ passRate: number;
17
+ threshold: number;
18
+ mode: Mode;
19
+ gap: number;
20
+ reason: string;
21
+ }
22
+
23
+ /**
24
+ * Mode-specific thresholds
25
+ */
26
+ const MODE_THRESHOLDS: Record<Mode, number> = {
27
+ mvp: 0.70,
28
+ standard: 0.95,
29
+ enterprise: 0.98,
30
+ };
31
+
32
+ /**
33
+ * Get threshold for a specific mode
34
+ */
35
+ export function getModeThreshold(mode: Mode): number {
36
+ return MODE_THRESHOLDS[mode];
37
+ }
38
+
39
+ /**
40
+ * Perform gate check
41
+ */
42
+ export function gateCheck(params: GateCheckParams): GateCheckResult {
43
+ const { passRate, mode } = params;
44
+
45
+ // Use custom threshold if provided, otherwise use mode-specific
46
+ const threshold = params.threshold !== undefined ? params.threshold : getModeThreshold(mode);
47
+
48
+ // Determine if gate passed
49
+ const passed = passRate >= threshold;
50
+
51
+ // Calculate gap (threshold - passRate)
52
+ // Positive gap = need improvement (failing)
53
+ // Zero gap = exactly at threshold
54
+ // Negative gap = exceeded threshold (passing)
55
+ const gap = parseFloat((threshold - passRate).toFixed(4));
56
+
57
+ // Generate reason
58
+ const reason = passed
59
+ ? `Gate PASSED: Pass rate ${passRate.toFixed(4)} >= threshold ${threshold.toFixed(4)} (${mode} mode)`
60
+ : `Gate FAILED: Pass rate ${passRate.toFixed(4)} < threshold ${threshold.toFixed(4)} (${mode} mode)`;
61
+
62
+ return {
63
+ passed,
64
+ passRate,
65
+ threshold,
66
+ mode,
67
+ gap,
68
+ reason,
69
+ };
70
+ }
71
+
72
+ /**
73
+ * CLI entry point for bash wrapper
74
+ */
75
+ if (require.main === module) {
76
+ const args = process.argv.slice(2);
77
+
78
+ // Parse command line arguments
79
+ let passRate = 0;
80
+ let threshold: number | undefined = undefined;
81
+ let mode: Mode = 'standard';
82
+
83
+ for (let i = 0; i < args.length; i++) {
84
+ const arg = args[i];
85
+ if (!arg) continue;
86
+
87
+ switch (arg) {
88
+ case '--pass-rate': {
89
+ const nextArg = args[++i];
90
+ if (nextArg) passRate = parseFloat(nextArg);
91
+ break;
92
+ }
93
+ case '--threshold': {
94
+ const nextArg = args[++i];
95
+ if (nextArg) threshold = parseFloat(nextArg);
96
+ break;
97
+ }
98
+ case '--mode': {
99
+ const nextArg = args[++i];
100
+ if (nextArg) mode = nextArg as Mode;
101
+ break;
102
+ }
103
+ }
104
+ }
105
+
106
+ const params: GateCheckParams = { passRate, mode };
107
+ if (threshold !== undefined) {
108
+ params.threshold = threshold;
109
+ }
110
+
111
+ const result = gateCheck(params);
112
+
113
+ console.log(JSON.stringify(result, null, 2));
114
+ process.exit(result.passed ? 0 : 1);
115
+ }