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.
Files changed (95) hide show
  1. package/docs/RELEASE_NOTES.md +35 -0
  2. package/docs/VIOLATIONS_RESOLUTION_PLAN.md +58 -58
  3. package/package.json +3 -3
  4. package/scripts/hooks-system/.AI_TOKEN_STATUS.txt +1 -1
  5. package/scripts/hooks-system/.audit-reports/notifications.log +935 -0
  6. package/scripts/hooks-system/.audit-reports/token-monitor.log +2809 -0
  7. package/scripts/hooks-system/application/CompositionRoot.js +38 -22
  8. package/scripts/hooks-system/application/services/AutonomousOrchestrator.js +0 -18
  9. package/scripts/hooks-system/application/services/ContextDetectionEngine.js +0 -58
  10. package/scripts/hooks-system/application/services/DynamicRulesLoader.js +2 -12
  11. package/scripts/hooks-system/application/services/GitFlowService.js +0 -80
  12. package/scripts/hooks-system/application/services/GitTreeState.js +2 -5
  13. package/scripts/hooks-system/application/services/HookSystemScheduler.js +0 -4
  14. package/scripts/hooks-system/application/services/IntelligentCommitAnalyzer.js +0 -25
  15. package/scripts/hooks-system/application/services/IntelligentGitTreeMonitor.js +0 -11
  16. package/scripts/hooks-system/application/services/PlatformAnalysisService.js +0 -19
  17. package/scripts/hooks-system/application/services/PlatformDetectionService.js +0 -19
  18. package/scripts/hooks-system/application/services/PlaybookRunner.js +1 -22
  19. package/scripts/hooks-system/application/services/PredictiveHookAdvisor.js +0 -19
  20. package/scripts/hooks-system/application/services/RealtimeGuardPlugin.js +0 -25
  21. package/scripts/hooks-system/application/services/RealtimeGuardService.js +71 -41
  22. package/scripts/hooks-system/application/services/SmartDirtyTreeAnalyzer.js +0 -11
  23. package/scripts/hooks-system/application/services/commit/CommitMessageGenerator.js +0 -11
  24. package/scripts/hooks-system/application/services/commit/FeatureDetector.js +0 -11
  25. package/scripts/hooks-system/application/services/evidence/EvidenceContextManager.js +0 -25
  26. package/scripts/hooks-system/application/services/guard/GuardAutoManagerService.js +31 -21
  27. package/scripts/hooks-system/application/services/guard/GuardConfig.js +15 -18
  28. package/scripts/hooks-system/application/services/guard/GuardEventLogger.js +0 -11
  29. package/scripts/hooks-system/application/services/guard/GuardHealthReminder.js +0 -26
  30. package/scripts/hooks-system/application/services/guard/GuardHeartbeatMonitor.js +6 -20
  31. package/scripts/hooks-system/application/services/guard/GuardLockManager.js +0 -11
  32. package/scripts/hooks-system/application/services/guard/GuardMonitorLoop.js +0 -25
  33. package/scripts/hooks-system/application/services/guard/GuardNotificationHandler.js +0 -11
  34. package/scripts/hooks-system/application/services/guard/GuardProcessManager.js +23 -11
  35. package/scripts/hooks-system/application/services/guard/GuardRecoveryService.js +0 -11
  36. package/scripts/hooks-system/application/services/installation/ConfigurationGeneratorService.js +0 -18
  37. package/scripts/hooks-system/application/services/installation/FileSystemInstallerService.js +0 -18
  38. package/scripts/hooks-system/application/services/installation/GitEnvironmentService.js +1 -19
  39. package/scripts/hooks-system/application/services/installation/HookInstaller.js +62 -24
  40. package/scripts/hooks-system/application/services/installation/IdeIntegrationService.js +0 -11
  41. package/scripts/hooks-system/application/services/installation/InstallService.js +1 -25
  42. package/scripts/hooks-system/application/services/installation/McpConfigurator.js +2 -19
  43. package/scripts/hooks-system/application/services/installation/PlatformDetectorService.js +0 -11
  44. package/scripts/hooks-system/application/services/installation/VSCodeTaskConfigurator.js +0 -11
  45. package/scripts/hooks-system/application/services/logging/AuditLogger.js +0 -8
  46. package/scripts/hooks-system/application/services/logging/UnifiedLogger.js +13 -15
  47. package/scripts/hooks-system/application/services/monitoring/ActivityMonitor.js +0 -33
  48. package/scripts/hooks-system/application/services/monitoring/AstMonitor.js +0 -27
  49. package/scripts/hooks-system/application/services/monitoring/DevDocsMonitor.js +0 -26
  50. package/scripts/hooks-system/application/services/monitoring/EvidenceMonitor.js +0 -18
  51. package/scripts/hooks-system/application/services/monitoring/EvidenceMonitorService.js +4 -28
  52. package/scripts/hooks-system/application/services/monitoring/GitTreeMonitor.js +0 -28
  53. package/scripts/hooks-system/application/services/monitoring/GitTreeMonitorService.js +0 -26
  54. package/scripts/hooks-system/application/services/monitoring/HealthCheckProviders.js +0 -4
  55. package/scripts/hooks-system/application/services/monitoring/HealthCheckService.js +0 -25
  56. package/scripts/hooks-system/application/services/monitoring/HeartbeatMonitorService.js +0 -26
  57. package/scripts/hooks-system/application/services/monitoring/TokenMonitor.js +0 -26
  58. package/scripts/hooks-system/application/services/notification/MacNotificationSender.js +0 -11
  59. package/scripts/hooks-system/application/services/notification/NotificationCenterService.js +0 -18
  60. package/scripts/hooks-system/application/services/notification/NotificationDispatcher.js +0 -11
  61. package/scripts/hooks-system/application/services/notification/components/NotificationCooldownManager.js +0 -18
  62. package/scripts/hooks-system/application/services/notification/components/NotificationDeduplicator.js +0 -18
  63. package/scripts/hooks-system/application/services/notification/components/NotificationQueue.js +0 -11
  64. package/scripts/hooks-system/application/services/notification/components/NotificationRetryExecutor.js +0 -20
  65. package/scripts/hooks-system/application/services/platform/PlatformHeuristics.js +0 -19
  66. package/scripts/hooks-system/application/services/recovery/AutoRecoveryManager.js +0 -19
  67. package/scripts/hooks-system/application/services/smart-commit/CommitMessageSuggester.js +0 -11
  68. package/scripts/hooks-system/application/services/smart-commit/FileContextGrouper.js +0 -19
  69. package/scripts/hooks-system/application/services/smart-commit/SmartCommitSummaryBuilder.js +0 -4
  70. package/scripts/hooks-system/application/services/token/CursorTokenService.js +0 -20
  71. package/scripts/hooks-system/application/services/token/TokenMetricsService.js +2 -12
  72. package/scripts/hooks-system/application/services/token/TokenMonitorService.js +0 -19
  73. package/scripts/hooks-system/application/services/token/TokenStatusReporter.js +0 -12
  74. package/scripts/hooks-system/bin/cli.js +15 -1
  75. package/scripts/hooks-system/bin/guard-env.sh +18 -38
  76. package/scripts/hooks-system/bin/guard-supervisor.js +5 -515
  77. package/scripts/hooks-system/bin/session-loader.sh +3 -262
  78. package/scripts/hooks-system/bin/start-guards.sh +21 -184
  79. package/scripts/hooks-system/bin/update-evidence.sh +10 -1161
  80. package/scripts/hooks-system/config/project.config.json +1 -1
  81. package/scripts/hooks-system/domain/events/index.js +31 -24
  82. package/scripts/hooks-system/infrastructure/ast/android/analyzers/AndroidAnalysisOrchestrator.js +3 -2
  83. package/scripts/hooks-system/infrastructure/ast/ast-core.js +12 -20
  84. package/scripts/hooks-system/infrastructure/ast/ast-intelligence.js +8 -18
  85. package/scripts/hooks-system/infrastructure/ast/backend/analyzers/BackendPatternDetector.js +2 -1
  86. package/scripts/hooks-system/infrastructure/ast/backend/ast-backend.js +18 -14
  87. package/scripts/hooks-system/infrastructure/ast/frontend/ast-frontend.js +196 -196
  88. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSASTIntelligentAnalyzer.js +3 -2
  89. package/scripts/hooks-system/infrastructure/hooks/skill-activation-prompt.js +3 -2
  90. package/scripts/hooks-system/infrastructure/logging/UnifiedLoggerFactory.js +5 -4
  91. package/scripts/hooks-system/infrastructure/mcp/ast-intelligence-automation.js +88 -0
  92. package/scripts/hooks-system/infrastructure/orchestration/intelligent-audit.js +17 -16
  93. package/scripts/hooks-system/infrastructure/shell/orchestrators/audit-orchestrator.sh +92 -54
  94. package/scripts/hooks-system/infrastructure/telemetry/metrics-server.js +3 -2
  95. 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 = (process.env.AUDIT_TMP || '').trim();
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(process.env.AI_GATE_SCOPE || 'staging').trim().toLowerCase();
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
- const configured = process.env.AST_BASE_BRANCH;
216
- if (configured && configured.trim().length > 0) {
217
- return configured.trim();
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
- execSync('git show-ref --verify --quiet refs/heads/develop', { stdio: 'ignore' });
221
- return 'develop';
225
+ execSync('git show-ref --verify --quiet refs/heads/main', { stdio: 'ignore' });
226
+ return 'main';
222
227
  } catch {
223
- try {
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(process.env.AI_GATE_SCOPE || 'staging').trim().toLowerCase();
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 = Number(process.env.AI_GATE_REPO_PRESERVE_MS || 600000);
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
- ROOT_DIR="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
35
- if [[ -d "$ROOT_DIR/node_modules/@pumuki/ast-intelligence-hooks" ]]; then
36
- HOOKS_SYSTEM_DIR="$ROOT_DIR/node_modules/@pumuki/ast-intelligence-hooks"
37
- elif [[ -d "$ROOT_DIR/scripts/hooks-system" ]]; then
38
- HOOKS_SYSTEM_DIR="$ROOT_DIR/scripts/hooks-system"
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 " ROOT_DIR: $ROOT_DIR" >&2
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
- ROOT_DIR=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
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: %s\n" "$gate_med"
281
- printf " 🔵 LOW: %s\n" "$gate_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" 2>/dev/null | head -n1 | sed 's/[^0-9]//g')
549
- es_warn=$(grep -o 'warnings=[0-9]\+' "$TMP_DIR/eslint-summary.txt" 2>/dev/null | head -n1 | sed 's/[^0-9]//g')
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
- mkdir -p "$ROOT_DIR/.audit-reports" || { echo "Failed to create .audit-reports directory"; exit 1; }
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" "$REPORTS_DIR/latest_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" "$REPORTS_DIR/latest_patterns.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" "$REPORTS_DIR/latest_eslint.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
- return 0
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
- local intelligent_audit="$HOOKS_SYSTEM_DIR/infrastructure/orchestration/intelligent-audit.js"
969
- if [[ ! -f "$intelligent_audit" ]]; then
970
- return 0
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
- export AUDIT_TMP="$TMP_DIR"
974
- if [[ "${BLOCK_ON_REPO_VIOLATIONS:-0}" == "1" ]]; then
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
- local node_path_value="${NODE_PATH:-}"
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
- node_path_value="$HOOKS_SYSTEM_DIR/node_modules${node_path_value:+:$node_path_value}"
994
+ node_path_parts+=("$HOOKS_SYSTEM_DIR/node_modules")
983
995
  fi
984
- if [[ -d "$ROOT_DIR/node_modules" ]]; then
985
- node_path_value="$ROOT_DIR/node_modules${node_path_value:+:$node_path_value}"
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 "$ROOT_DIR" && export NODE_PATH="$node_path_value" && "$node_bin" "${AST_DIR}/ast-intelligence.js" 2>&1) || ast_exit_code=$?
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 "$ROOT_DIR" && "$node_bin" "${AST_DIR}/ast-intelligence.js" 2>&1) || ast_exit_code=$?
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 = Number(process.env.HOOK_METRICS_PORT || 9464);
8
- const METRICS_FILE = path.join(process.cwd(), '.audit_tmp', 'hook-metrics.jsonl');
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 = process.env.HOOK_GUARD_REPO_ROOT || process.cwd();
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 (process.env.NODE_ENV === 'development' || process.env.DEBUG) {
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 raw = execSync('git diff --cached --name-only --diff-filter=ACMR', {
123
- cwd: REPO_ROOT,
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 (process.env.NODE_ENV === 'development' || process.env.DEBUG) {
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 [];