pumuki-ast-hooks 5.3.20 → 5.3.21
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/docs/RELEASE_NOTES.md +35 -0
- package/docs/VIOLATIONS_RESOLUTION_PLAN.md +58 -58
- package/package.json +3 -3
- package/scripts/hooks-system/.AI_TOKEN_STATUS.txt +1 -1
- package/scripts/hooks-system/.audit-reports/notifications.log +935 -0
- package/scripts/hooks-system/.audit-reports/token-monitor.log +2809 -0
- package/scripts/hooks-system/application/CompositionRoot.js +38 -22
- package/scripts/hooks-system/application/services/AutonomousOrchestrator.js +0 -18
- package/scripts/hooks-system/application/services/ContextDetectionEngine.js +0 -58
- package/scripts/hooks-system/application/services/DynamicRulesLoader.js +2 -12
- package/scripts/hooks-system/application/services/GitFlowService.js +0 -80
- package/scripts/hooks-system/application/services/GitTreeState.js +2 -5
- package/scripts/hooks-system/application/services/HookSystemScheduler.js +0 -4
- package/scripts/hooks-system/application/services/IntelligentCommitAnalyzer.js +0 -25
- package/scripts/hooks-system/application/services/IntelligentGitTreeMonitor.js +0 -11
- package/scripts/hooks-system/application/services/PlatformAnalysisService.js +0 -19
- package/scripts/hooks-system/application/services/PlatformDetectionService.js +0 -19
- package/scripts/hooks-system/application/services/PlaybookRunner.js +1 -22
- package/scripts/hooks-system/application/services/PredictiveHookAdvisor.js +0 -19
- package/scripts/hooks-system/application/services/RealtimeGuardPlugin.js +0 -25
- package/scripts/hooks-system/application/services/RealtimeGuardService.js +71 -41
- package/scripts/hooks-system/application/services/SmartDirtyTreeAnalyzer.js +0 -11
- package/scripts/hooks-system/application/services/commit/CommitMessageGenerator.js +0 -11
- package/scripts/hooks-system/application/services/commit/FeatureDetector.js +0 -11
- package/scripts/hooks-system/application/services/evidence/EvidenceContextManager.js +0 -25
- package/scripts/hooks-system/application/services/guard/GuardAutoManagerService.js +31 -21
- package/scripts/hooks-system/application/services/guard/GuardConfig.js +15 -18
- package/scripts/hooks-system/application/services/guard/GuardEventLogger.js +0 -11
- package/scripts/hooks-system/application/services/guard/GuardHealthReminder.js +0 -26
- package/scripts/hooks-system/application/services/guard/GuardHeartbeatMonitor.js +6 -20
- package/scripts/hooks-system/application/services/guard/GuardLockManager.js +0 -11
- package/scripts/hooks-system/application/services/guard/GuardMonitorLoop.js +0 -25
- package/scripts/hooks-system/application/services/guard/GuardNotificationHandler.js +0 -11
- package/scripts/hooks-system/application/services/guard/GuardProcessManager.js +23 -11
- package/scripts/hooks-system/application/services/guard/GuardRecoveryService.js +0 -11
- package/scripts/hooks-system/application/services/installation/ConfigurationGeneratorService.js +0 -18
- package/scripts/hooks-system/application/services/installation/FileSystemInstallerService.js +0 -18
- package/scripts/hooks-system/application/services/installation/GitEnvironmentService.js +1 -19
- package/scripts/hooks-system/application/services/installation/HookInstaller.js +62 -24
- package/scripts/hooks-system/application/services/installation/IdeIntegrationService.js +0 -11
- package/scripts/hooks-system/application/services/installation/InstallService.js +1 -25
- package/scripts/hooks-system/application/services/installation/McpConfigurator.js +2 -19
- package/scripts/hooks-system/application/services/installation/PlatformDetectorService.js +0 -11
- package/scripts/hooks-system/application/services/installation/VSCodeTaskConfigurator.js +0 -11
- package/scripts/hooks-system/application/services/logging/AuditLogger.js +0 -8
- package/scripts/hooks-system/application/services/logging/UnifiedLogger.js +13 -15
- package/scripts/hooks-system/application/services/monitoring/ActivityMonitor.js +0 -33
- package/scripts/hooks-system/application/services/monitoring/AstMonitor.js +0 -27
- package/scripts/hooks-system/application/services/monitoring/DevDocsMonitor.js +0 -26
- package/scripts/hooks-system/application/services/monitoring/EvidenceMonitor.js +0 -18
- package/scripts/hooks-system/application/services/monitoring/EvidenceMonitorService.js +4 -28
- package/scripts/hooks-system/application/services/monitoring/GitTreeMonitor.js +0 -28
- package/scripts/hooks-system/application/services/monitoring/GitTreeMonitorService.js +0 -26
- package/scripts/hooks-system/application/services/monitoring/HealthCheckProviders.js +0 -4
- package/scripts/hooks-system/application/services/monitoring/HealthCheckService.js +0 -25
- package/scripts/hooks-system/application/services/monitoring/HeartbeatMonitorService.js +0 -26
- package/scripts/hooks-system/application/services/monitoring/TokenMonitor.js +0 -26
- package/scripts/hooks-system/application/services/notification/MacNotificationSender.js +0 -11
- package/scripts/hooks-system/application/services/notification/NotificationCenterService.js +0 -18
- package/scripts/hooks-system/application/services/notification/NotificationDispatcher.js +0 -11
- package/scripts/hooks-system/application/services/notification/components/NotificationCooldownManager.js +0 -18
- package/scripts/hooks-system/application/services/notification/components/NotificationDeduplicator.js +0 -18
- package/scripts/hooks-system/application/services/notification/components/NotificationQueue.js +0 -11
- package/scripts/hooks-system/application/services/notification/components/NotificationRetryExecutor.js +0 -20
- package/scripts/hooks-system/application/services/platform/PlatformHeuristics.js +0 -19
- package/scripts/hooks-system/application/services/recovery/AutoRecoveryManager.js +0 -19
- package/scripts/hooks-system/application/services/smart-commit/CommitMessageSuggester.js +0 -11
- package/scripts/hooks-system/application/services/smart-commit/FileContextGrouper.js +0 -19
- package/scripts/hooks-system/application/services/smart-commit/SmartCommitSummaryBuilder.js +0 -4
- package/scripts/hooks-system/application/services/token/CursorTokenService.js +0 -20
- package/scripts/hooks-system/application/services/token/TokenMetricsService.js +2 -12
- package/scripts/hooks-system/application/services/token/TokenMonitorService.js +0 -19
- package/scripts/hooks-system/application/services/token/TokenStatusReporter.js +0 -12
- package/scripts/hooks-system/bin/cli.js +15 -1
- package/scripts/hooks-system/bin/guard-env.sh +18 -38
- package/scripts/hooks-system/bin/guard-supervisor.js +5 -515
- package/scripts/hooks-system/bin/session-loader.sh +3 -262
- package/scripts/hooks-system/bin/start-guards.sh +21 -184
- package/scripts/hooks-system/bin/update-evidence.sh +10 -1161
- package/scripts/hooks-system/config/project.config.json +1 -1
- package/scripts/hooks-system/domain/events/index.js +31 -24
- package/scripts/hooks-system/infrastructure/ast/android/analyzers/AndroidAnalysisOrchestrator.js +3 -2
- package/scripts/hooks-system/infrastructure/ast/ast-core.js +12 -20
- package/scripts/hooks-system/infrastructure/ast/ast-intelligence.js +8 -18
- package/scripts/hooks-system/infrastructure/ast/backend/analyzers/BackendPatternDetector.js +2 -1
- package/scripts/hooks-system/infrastructure/ast/backend/ast-backend.js +18 -14
- package/scripts/hooks-system/infrastructure/ast/frontend/ast-frontend.js +196 -196
- package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSASTIntelligentAnalyzer.js +3 -2
- package/scripts/hooks-system/infrastructure/hooks/skill-activation-prompt.js +3 -2
- package/scripts/hooks-system/infrastructure/logging/UnifiedLoggerFactory.js +5 -4
- package/scripts/hooks-system/infrastructure/mcp/ast-intelligence-automation.js +88 -0
- package/scripts/hooks-system/infrastructure/orchestration/intelligent-audit.js +17 -16
- package/scripts/hooks-system/infrastructure/shell/orchestrators/audit-orchestrator.sh +92 -54
- package/scripts/hooks-system/infrastructure/telemetry/metrics-server.js +3 -2
- package/scripts/hooks-system/infrastructure/validators/enforce-english-literals.js +6 -8
|
@@ -8,9 +8,10 @@ const { TokenManager } = require('../utils/token-manager');
|
|
|
8
8
|
const { toErrorMessage } = require('../utils/error-utils');
|
|
9
9
|
const fs = require('fs');
|
|
10
10
|
const path = require('path');
|
|
11
|
+
const env = require('../../config/env');
|
|
11
12
|
|
|
12
13
|
function resolveAuditTmpDir() {
|
|
13
|
-
const configured = (
|
|
14
|
+
const configured = (env.get('AUDIT_TMP', '') || '').trim();
|
|
14
15
|
if (configured.length > 0) {
|
|
15
16
|
return path.isAbsolute(configured) ? configured : path.join(process.cwd(), configured);
|
|
16
17
|
}
|
|
@@ -28,7 +29,7 @@ async function runIntelligentAudit() {
|
|
|
28
29
|
const rawViolations = loadRawViolations();
|
|
29
30
|
console.log(`[Intelligent Audit] Loaded ${rawViolations.length} violations from AST`);
|
|
30
31
|
|
|
31
|
-
const gateScope = String(
|
|
32
|
+
const gateScope = String(env.get('AI_GATE_SCOPE', 'staging') || 'staging').trim().toLowerCase();
|
|
32
33
|
const isRepoScope = gateScope === 'repo' || gateScope === 'repository';
|
|
33
34
|
|
|
34
35
|
let violationsForGate = [];
|
|
@@ -212,21 +213,21 @@ function updateAIEvidence(violations, gateResult, tokenUsage) {
|
|
|
212
213
|
const currentBranch = execSync('git branch --show-current', { encoding: 'utf8' }).trim();
|
|
213
214
|
|
|
214
215
|
const resolveBaseBranch = () => {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
216
|
+
const configured = env.get('AST_BASE_BRANCH', '');
|
|
217
|
+
if (configured && configured.trim().length > 0) {
|
|
218
|
+
return configured.trim();
|
|
219
|
+
}
|
|
220
|
+
try {
|
|
221
|
+
execSync('git show-ref --verify --quiet refs/heads/develop', { stdio: 'ignore' });
|
|
222
|
+
return 'develop';
|
|
223
|
+
} catch {
|
|
219
224
|
try {
|
|
220
|
-
|
|
221
|
-
|
|
225
|
+
execSync('git show-ref --verify --quiet refs/heads/main', { stdio: 'ignore' });
|
|
226
|
+
return 'main';
|
|
222
227
|
} catch {
|
|
223
|
-
|
|
224
|
-
execSync('git show-ref --verify --quiet refs/heads/main', { stdio: 'ignore' });
|
|
225
|
-
return 'main';
|
|
226
|
-
} catch {
|
|
227
|
-
return 'main';
|
|
228
|
-
}
|
|
228
|
+
return 'main';
|
|
229
229
|
}
|
|
230
|
+
}
|
|
230
231
|
};
|
|
231
232
|
const baseBranch = resolveBaseBranch();
|
|
232
233
|
const isProtected = ['main', 'master', baseBranch].includes(currentBranch);
|
|
@@ -234,12 +235,12 @@ function updateAIEvidence(violations, gateResult, tokenUsage) {
|
|
|
234
235
|
const highViolations = violations.filter(v => v.severity === 'HIGH');
|
|
235
236
|
const blockingViolations = [...criticalViolations, ...highViolations].slice(0, 50);
|
|
236
237
|
|
|
237
|
-
const gateScope = String(
|
|
238
|
+
const gateScope = String(env.get('AI_GATE_SCOPE', 'staging') || 'staging').trim().toLowerCase();
|
|
238
239
|
|
|
239
240
|
const existingGate = evidence.ai_gate && typeof evidence.ai_gate === 'object' ? evidence.ai_gate : null;
|
|
240
241
|
let preserveExistingRepoGate = false;
|
|
241
242
|
if (gateScope !== 'repo' && gateScope !== 'repository' && existingGate && existingGate.scope === 'repo' && existingGate.status === 'BLOCKED') {
|
|
242
|
-
const preserveMs =
|
|
243
|
+
const preserveMs = env.getNumber('AI_GATE_REPO_PRESERVE_MS', 600000);
|
|
243
244
|
const lastCheckMs = Date.parse(existingGate.last_check || '');
|
|
244
245
|
if (!Number.isNaN(preserveMs) && preserveMs > 0 && !Number.isNaN(lastCheckMs)) {
|
|
245
246
|
const ageMs = Date.now() - lastCheckMs;
|
|
@@ -31,15 +31,15 @@ elif [[ "$SCRIPT_DIR" == *"scripts/hooks-system"* ]]; then
|
|
|
31
31
|
fi
|
|
32
32
|
else
|
|
33
33
|
# Fallback: try to find it relative to current directory
|
|
34
|
-
|
|
35
|
-
if [[ -d "$
|
|
36
|
-
HOOKS_SYSTEM_DIR="$
|
|
37
|
-
elif [[ -d "$
|
|
38
|
-
HOOKS_SYSTEM_DIR="$
|
|
34
|
+
REPO_ROOT="$(pwd)"
|
|
35
|
+
if [[ -d "$REPO_ROOT/node_modules/@pumuki/ast-intelligence-hooks" ]]; then
|
|
36
|
+
HOOKS_SYSTEM_DIR="$REPO_ROOT/node_modules/@pumuki/ast-intelligence-hooks"
|
|
37
|
+
elif [[ -d "$REPO_ROOT/scripts/hooks-system" ]]; then
|
|
38
|
+
HOOKS_SYSTEM_DIR="$REPO_ROOT/scripts/hooks-system"
|
|
39
39
|
else
|
|
40
40
|
echo "Error: Could not determine HOOKS_SYSTEM_DIR" >&2
|
|
41
41
|
echo " SCRIPT_DIR: $SCRIPT_DIR" >&2
|
|
42
|
-
echo "
|
|
42
|
+
echo " REPO_ROOT: $REPO_ROOT" >&2
|
|
43
43
|
exit 1
|
|
44
44
|
fi
|
|
45
45
|
fi
|
|
@@ -58,7 +58,11 @@ source "$INFRASTRUCTURE_DIR/eslint/eslint-integration.sh"
|
|
|
58
58
|
START_TIME=$(date +%s)
|
|
59
59
|
|
|
60
60
|
# Determine repository root using git
|
|
61
|
-
|
|
61
|
+
if command -v git >/dev/null 2>&1; then
|
|
62
|
+
ROOT_DIR=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
63
|
+
else
|
|
64
|
+
ROOT_DIR=$(pwd)
|
|
65
|
+
fi
|
|
62
66
|
|
|
63
67
|
# Default to temp directories to avoid polluting repositories.
|
|
64
68
|
# Can be overridden by setting AUDIT_TMP / AUDIT_REPORTS.
|
|
@@ -208,11 +212,6 @@ run_intelligent_audit() {
|
|
|
208
212
|
}
|
|
209
213
|
|
|
210
214
|
full_audit() {
|
|
211
|
-
export AUDIT_STRICT=1
|
|
212
|
-
export BLOCK_ALL_SEVERITIES=1
|
|
213
|
-
export BLOCK_ON_REPO_VIOLATIONS=1
|
|
214
|
-
export AUDIT_LIBRARY=true
|
|
215
|
-
unset STAGING_ONLY_MODE
|
|
216
215
|
run_basic_checks
|
|
217
216
|
run_eslint_suite
|
|
218
217
|
run_ast_intelligence
|
|
@@ -277,8 +276,8 @@ full_audit_strict_staging_only() {
|
|
|
277
276
|
printf "\n%b✅ STAGING CLEAN - COMMIT ALLOWED%b\n" "$GREEN" "$NC"
|
|
278
277
|
printf " 🔴 CRITICAL: 0\n"
|
|
279
278
|
printf " 🟠 HIGH: 0\n"
|
|
280
|
-
printf " 🟡 MEDIUM:
|
|
281
|
-
printf " 🔵 LOW:
|
|
279
|
+
printf " 🟡 MEDIUM: 0\n"
|
|
280
|
+
printf " 🔵 LOW: 0\n"
|
|
282
281
|
printf "\n All staged files pass strict quality gates.\n"
|
|
283
282
|
printf " Ready to commit! 🚀\n\n"
|
|
284
283
|
print_final_signature
|
|
@@ -545,8 +544,8 @@ summarize_all() {
|
|
|
545
544
|
printf "\n%b2. ESLINT AUDIT RESULTS%b\n" "$YELLOW" "$NC"
|
|
546
545
|
printf "─────────────────────────────────────────────────────────────\n"
|
|
547
546
|
if [[ -f "$TMP_DIR/eslint-summary.txt" ]]; then
|
|
548
|
-
es_err=$(grep -o 'errors=[0-9]\+' "$TMP_DIR/eslint-summary.txt"
|
|
549
|
-
es_warn=$(grep -o 'warnings=[0-9]\+' "$TMP_DIR/eslint-summary.txt"
|
|
547
|
+
es_err=$(grep -o 'errors=[0-9]\+' "$TMP_DIR/eslint-summary.txt" | head -n1 | sed 's/[^0-9]//g')
|
|
548
|
+
es_warn=$(grep -o 'warnings=[0-9]\+' "$TMP_DIR/eslint-summary.txt" | head -n1 | sed 's/[^0-9]//g')
|
|
550
549
|
es_err=${es_err:-0}; es_warn=${es_warn:-0}
|
|
551
550
|
if [[ $es_err -gt 0 ]]; then
|
|
552
551
|
printf " %bESLint:%b 🔴 errors=%s 🟡 warnings=%s\n" "$RED" "$NC" "$es_err" "$es_warn"
|
|
@@ -842,32 +841,31 @@ save_audit_reports() {
|
|
|
842
841
|
local report_prefix="${REPORTS_DIR}/audit_${timestamp}"
|
|
843
842
|
|
|
844
843
|
if [[ -f "$TMP_DIR/ast-summary.json" ]]; then
|
|
845
|
-
|
|
846
|
-
cp "$TMP_DIR/ast-summary.json" "$ROOT_DIR/.audit-reports/latest_ast-summary.json" || { echo "Failed to copy AST summary"; exit 1; }
|
|
844
|
+
cp "$TMP_DIR/ast-summary.json" "${report_prefix}_ast_summary.json"
|
|
847
845
|
fi
|
|
848
846
|
|
|
849
847
|
if [[ -f "$TMP_DIR/ast-findings.json" ]]; then
|
|
850
|
-
cp "$TMP_DIR/ast-findings.json" "$
|
|
848
|
+
cp "$TMP_DIR/ast-findings.json" "${report_prefix}_ast_findings.json"
|
|
851
849
|
fi
|
|
852
850
|
|
|
853
851
|
if [[ -f "$TMP_DIR/pattern-summary.txt" ]]; then
|
|
854
|
-
cp "$TMP_DIR/pattern-summary.txt" "$
|
|
852
|
+
cp "$TMP_DIR/pattern-summary.txt" "${report_prefix}_patterns.txt"
|
|
855
853
|
fi
|
|
856
854
|
|
|
857
855
|
if [[ -f "$TMP_DIR/eslint-summary.txt" ]]; then
|
|
858
|
-
cp "$TMP_DIR/eslint-summary.txt" "$
|
|
856
|
+
cp "$TMP_DIR/eslint-summary.txt" "${report_prefix}_eslint.txt"
|
|
859
857
|
fi
|
|
860
858
|
|
|
861
|
-
local latest_summary="$REPORTS_DIR/latest_ast_summary.json"
|
|
862
|
-
local latest_findings="$REPORTS_DIR/latest_ast_findings.json"
|
|
863
|
-
local latest_critical="$REPORTS_DIR/latest_critical.json"
|
|
864
|
-
local latest_high="$REPORTS_DIR/latest_high.json"
|
|
865
|
-
local latest_medium="$REPORTS_DIR/latest_medium.json"
|
|
866
|
-
local latest_low="$REPORTS_DIR/latest_low.json"
|
|
859
|
+
local latest_summary="${REPORTS_DIR}/latest_ast_summary.json"
|
|
860
|
+
local latest_findings="${REPORTS_DIR}/latest_ast_findings.json"
|
|
861
|
+
local latest_critical="${REPORTS_DIR}/latest_critical.json"
|
|
862
|
+
local latest_high="${REPORTS_DIR}/latest_high.json"
|
|
863
|
+
local latest_medium="${REPORTS_DIR}/latest_medium.json"
|
|
864
|
+
local latest_low="${REPORTS_DIR}/latest_low.json"
|
|
867
865
|
|
|
868
866
|
if [[ -f "$TMP_DIR/ast-summary.json" ]]; then
|
|
869
867
|
cp "$TMP_DIR/ast-summary.json" "$latest_summary"
|
|
870
|
-
cp "$TMP_DIR/ast-summary.json" "$REPORTS_DIR/baseline_ast_summary.json"
|
|
868
|
+
cp "$TMP_DIR/ast-summary.json" "${REPORTS_DIR}/baseline_ast_summary.json"
|
|
871
869
|
|
|
872
870
|
if command -v jq >/dev/null 2>&1; then
|
|
873
871
|
jq '{
|
|
@@ -925,15 +923,15 @@ save_audit_reports() {
|
|
|
925
923
|
}
|
|
926
924
|
|
|
927
925
|
export_markdown() {
|
|
928
|
-
local out="$TMP_DIR/audit-report.md"
|
|
926
|
+
local out="${TMP_DIR}/audit-report.md"
|
|
929
927
|
printf "# Audit Report\n\n" > "$out"
|
|
930
928
|
printf "## %s\n\n" "$MSG_SUMMARY" >> "$out"
|
|
931
|
-
if [[ -f "$TMP_DIR/pattern-summary.txt" ]]; then
|
|
932
|
-
cat "$TMP_DIR/pattern-summary.txt" >> "$out"
|
|
929
|
+
if [[ -f "${TMP_DIR}/pattern-summary.txt" ]]; then
|
|
930
|
+
cat "${TMP_DIR}/pattern-summary.txt" >> "$out"
|
|
933
931
|
printf "\n" >> "$out"
|
|
934
932
|
fi
|
|
935
|
-
if [[ -f "$TMP_DIR/eslint-summary.txt" ]]; then
|
|
936
|
-
cat "$TMP_DIR/eslint-summary.txt" >> "$out"
|
|
933
|
+
if [[ -f "${TMP_DIR}/eslint-summary.txt" ]]; then
|
|
934
|
+
cat "${TMP_DIR}/eslint-summary.txt" >> "$out"
|
|
937
935
|
printf "\n" >> "$out"
|
|
938
936
|
fi
|
|
939
937
|
printf "%s %s\n" "$EMJ_OK" "$out"
|
|
@@ -962,33 +960,77 @@ run_ast_intelligence() {
|
|
|
962
960
|
if [[ -x "/usr/bin/node" ]]; then node_bin="/usr/bin/node"; fi
|
|
963
961
|
fi
|
|
964
962
|
if [[ -z "$node_bin" ]]; then
|
|
965
|
-
|
|
963
|
+
local nvm_dir="${NVM_DIR:-$HOME/.nvm}"
|
|
964
|
+
local nvm_default=""
|
|
965
|
+
if [[ -f "$nvm_dir/alias/default" ]]; then
|
|
966
|
+
nvm_default="$(cat "$nvm_dir/alias/default" 2>/dev/null || true)"
|
|
967
|
+
nvm_default="${nvm_default##v}"
|
|
968
|
+
nvm_default="${nvm_default%%[[:space:]]*}"
|
|
969
|
+
fi
|
|
970
|
+
if [[ -n "$nvm_default" ]] && [[ -x "$nvm_dir/versions/node/v${nvm_default}/bin/node" ]]; then
|
|
971
|
+
node_bin="$nvm_dir/versions/node/v${nvm_default}/bin/node"
|
|
972
|
+
fi
|
|
966
973
|
fi
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
974
|
+
if [[ -z "$node_bin" ]]; then
|
|
975
|
+
local nvm_dir_fallback="${NVM_DIR:-$HOME/.nvm}"
|
|
976
|
+
local latest_node=""
|
|
977
|
+
latest_node="$(ls -1 "$nvm_dir_fallback/versions/node" 2>/dev/null | grep -E '^v[0-9]+' | sort -V | tail -n 1 || true)"
|
|
978
|
+
if [[ -n "$latest_node" ]] && [[ -x "$nvm_dir_fallback/versions/node/${latest_node}/bin/node" ]]; then
|
|
979
|
+
node_bin="$nvm_dir_fallback/versions/node/${latest_node}/bin/node"
|
|
980
|
+
fi
|
|
971
981
|
fi
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
export AI_GATE_SCOPE="repo"
|
|
976
|
-
else
|
|
977
|
-
export AI_GATE_SCOPE="staging"
|
|
982
|
+
if [[ -z "$node_bin" ]]; then
|
|
983
|
+
printf "%b❌ Node.js not found in PATH. Install Node.js >= 18 or ensure your shell loads nvm/asdf for non-interactive scripts.%b\n" "$RED" "$NC" >&2
|
|
984
|
+
return 127
|
|
978
985
|
fi
|
|
979
986
|
|
|
980
|
-
|
|
987
|
+
# Determine NODE_PATH to include library's node_modules
|
|
988
|
+
# Try multiple locations: HOOKS_SYSTEM_DIR/node_modules, or project root node_modules
|
|
989
|
+
local -a node_path_parts
|
|
990
|
+
node_path_parts=()
|
|
991
|
+
|
|
992
|
+
# If HOOKS_SYSTEM_DIR has its own node_modules
|
|
981
993
|
if [[ -d "$HOOKS_SYSTEM_DIR/node_modules" ]]; then
|
|
982
|
-
|
|
994
|
+
node_path_parts+=("$HOOKS_SYSTEM_DIR/node_modules")
|
|
983
995
|
fi
|
|
984
|
-
|
|
985
|
-
|
|
996
|
+
|
|
997
|
+
# Also check if we're in a project with node_modules/@pumuki/ast-intelligence-hooks
|
|
998
|
+
local repo_root=""
|
|
999
|
+
if [[ "$HOOKS_SYSTEM_DIR" == *"scripts/hooks-system"* ]]; then
|
|
1000
|
+
# Running from scripts/hooks-system, go to repo root
|
|
1001
|
+
repo_root="$(cd "$HOOKS_SYSTEM_DIR/../.." && pwd)"
|
|
1002
|
+
elif [[ "$HOOKS_SYSTEM_DIR" == *"node_modules/@pumuki/ast-intelligence-hooks"* ]]; then
|
|
1003
|
+
# Running from node_modules, go to repo root
|
|
1004
|
+
repo_root="$(cd "$HOOKS_SYSTEM_DIR/../../.." && pwd)"
|
|
1005
|
+
else
|
|
1006
|
+
# Try current directory
|
|
1007
|
+
repo_root="$(pwd)"
|
|
1008
|
+
fi
|
|
1009
|
+
|
|
1010
|
+
if [[ -n "$repo_root" ]] && [[ -d "$repo_root/node_modules/@pumuki/ast-intelligence-hooks/node_modules" ]]; then
|
|
1011
|
+
node_path_parts+=("$repo_root/node_modules/@pumuki/ast-intelligence-hooks/node_modules")
|
|
986
1012
|
fi
|
|
1013
|
+
|
|
1014
|
+
if [[ -n "$repo_root" ]] && [[ -d "$repo_root/node_modules" ]]; then
|
|
1015
|
+
node_path_parts+=("$repo_root/node_modules")
|
|
1016
|
+
fi
|
|
1017
|
+
|
|
1018
|
+
# Build NODE_PATH
|
|
1019
|
+
local node_path_value="${NODE_PATH:-}"
|
|
1020
|
+
for path_part in "${node_path_parts[@]:-}"; do
|
|
1021
|
+
if [[ -n "$node_path_value" ]]; then
|
|
1022
|
+
node_path_value="$path_part:$node_path_value"
|
|
1023
|
+
else
|
|
1024
|
+
node_path_value="$path_part"
|
|
1025
|
+
fi
|
|
1026
|
+
done
|
|
987
1027
|
|
|
1028
|
+
# Execute AST with proper error handling and NODE_PATH
|
|
1029
|
+
# Change to HOOKS_SYSTEM_DIR so Node.js resolves modules correctly
|
|
988
1030
|
if [[ -n "$node_path_value" ]]; then
|
|
989
|
-
(cd "$
|
|
1031
|
+
ast_output=$(cd "$HOOKS_SYSTEM_DIR" && export NODE_PATH="$node_path_value" && export AUDIT_TMP="$TMP_DIR" && export AUDIT_LIBRARY="${AUDIT_LIBRARY:-false}" && "$node_bin" "${AST_DIR}/ast-intelligence.js" 2>&1) || ast_exit_code=$?
|
|
990
1032
|
else
|
|
991
|
-
(cd "$
|
|
1033
|
+
ast_output=$(cd "$HOOKS_SYSTEM_DIR" && export AUDIT_TMP="$TMP_DIR" && export AUDIT_LIBRARY="${AUDIT_LIBRARY:-false}" && "$node_bin" "${AST_DIR}/ast-intelligence.js" 2>&1) || ast_exit_code=$?
|
|
992
1034
|
fi
|
|
993
1035
|
|
|
994
1036
|
# Check if AST script failed
|
|
@@ -1041,10 +1083,6 @@ run_ast_intelligence() {
|
|
|
1041
1083
|
fi
|
|
1042
1084
|
|
|
1043
1085
|
printf "%b✅ AST Intelligence completed%b\n\n" "$GREEN" "$NC"
|
|
1044
|
-
|
|
1045
|
-
# Ensure the .audit-reports directory exists and copy the AST summary
|
|
1046
|
-
mkdir -p "$ROOT_DIR/.audit-reports" || { echo "Failed to create .audit-reports directory"; exit 1; }
|
|
1047
|
-
cp "$TMP_DIR/ast-summary.json" "$ROOT_DIR/.audit-reports/latest_ast-summary.json" || { echo "Failed to copy AST summary"; exit 1; }
|
|
1048
1086
|
}
|
|
1049
1087
|
|
|
1050
1088
|
interactive_menu() {
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
const http = require('http');
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
|
+
const env = require('../../config/env');
|
|
6
7
|
|
|
7
|
-
const PORT =
|
|
8
|
-
const METRICS_FILE = path.join(process.cwd(),
|
|
8
|
+
const PORT = env.getNumber('HOOK_METRICS_PORT', 9464);
|
|
9
|
+
const METRICS_FILE = path.join(process.cwd(), env.get('HOOK_METRICS_FILE', '.audit_tmp/hook-metrics.jsonl'));
|
|
9
10
|
|
|
10
11
|
function loadMetrics() {
|
|
11
12
|
if (!fs.existsSync(METRICS_FILE)) return [];
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const { execSync } = require('child_process');
|
|
7
|
+
const env = require('../../config/env');
|
|
7
8
|
|
|
8
|
-
const REPO_ROOT =
|
|
9
|
+
const REPO_ROOT = env.get('HOOK_GUARD_REPO_ROOT', process.cwd());
|
|
9
10
|
const CONFIG_PATH = path.join(REPO_ROOT, 'scripts', 'hooks-system', 'config', 'language-guard.json');
|
|
10
11
|
const DEFAULT_IGNORED_SEGMENTS = [
|
|
11
12
|
`${path.sep}node_modules${path.sep}`,
|
|
@@ -22,7 +23,7 @@ function decodeUnicode(value) {
|
|
|
22
23
|
try {
|
|
23
24
|
return JSON.parse(`"${value}"`);
|
|
24
25
|
} catch (error) {
|
|
25
|
-
if (
|
|
26
|
+
if (env.isDev || env.getBool('DEBUG', false)) {
|
|
26
27
|
console.debug(`[enforce-english-literals] Failed to decode Unicode value "${value}": ${error.message}`);
|
|
27
28
|
}
|
|
28
29
|
return value;
|
|
@@ -119,13 +120,10 @@ function analyzeFile(relativePath, config) {
|
|
|
119
120
|
|
|
120
121
|
function collectStagedFiles() {
|
|
121
122
|
try {
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
encoding: 'utf8'
|
|
125
|
-
});
|
|
126
|
-
return raw.split('\n').map(entry => entry.trim()).filter(Boolean);
|
|
123
|
+
const stagedFilesRaw = execSync('git diff --cached --name-only', { encoding: 'utf8' });
|
|
124
|
+
return stagedFilesRaw.split('\n').filter(Boolean).map(file => file.trim());
|
|
127
125
|
} catch (error) {
|
|
128
|
-
if (
|
|
126
|
+
if (env.isDev || env.getBool('DEBUG', false)) {
|
|
129
127
|
console.debug(`[enforce-english-literals] Failed to collect staged files: ${error.message}`);
|
|
130
128
|
}
|
|
131
129
|
return [];
|