pumuki-ast-hooks 5.3.19 → 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 (46) hide show
  1. package/docs/RELEASE_NOTES.md +35 -0
  2. package/docs/VIOLATIONS_RESOLUTION_PLAN.md +64 -60
  3. package/package.json +9 -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/DynamicRulesLoader.js +2 -1
  9. package/scripts/hooks-system/application/services/GitTreeState.js +2 -1
  10. package/scripts/hooks-system/application/services/PlaybookRunner.js +1 -1
  11. package/scripts/hooks-system/application/services/RealtimeGuardService.js +71 -14
  12. package/scripts/hooks-system/application/services/guard/GuardAutoManagerService.js +31 -2
  13. package/scripts/hooks-system/application/services/guard/GuardConfig.js +17 -9
  14. package/scripts/hooks-system/application/services/guard/GuardHeartbeatMonitor.js +6 -9
  15. package/scripts/hooks-system/application/services/guard/GuardProcessManager.js +23 -0
  16. package/scripts/hooks-system/application/services/installation/GitEnvironmentService.js +1 -1
  17. package/scripts/hooks-system/application/services/installation/HookInstaller.js +62 -5
  18. package/scripts/hooks-system/application/services/installation/McpConfigurator.js +2 -1
  19. package/scripts/hooks-system/application/services/logging/AuditLogger.js +0 -4
  20. package/scripts/hooks-system/application/services/logging/UnifiedLogger.js +13 -4
  21. package/scripts/hooks-system/application/services/monitoring/EvidenceMonitorService.js +4 -3
  22. package/scripts/hooks-system/application/services/token/TokenMetricsService.js +2 -1
  23. package/scripts/hooks-system/bin/cli.js +15 -1
  24. package/scripts/hooks-system/bin/guard-env.sh +18 -38
  25. package/scripts/hooks-system/bin/guard-supervisor.js +5 -515
  26. package/scripts/hooks-system/bin/session-loader.sh +3 -262
  27. package/scripts/hooks-system/bin/start-guards.sh +21 -184
  28. package/scripts/hooks-system/bin/update-evidence.sh +10 -1161
  29. package/scripts/hooks-system/config/project.config.json +1 -1
  30. package/scripts/hooks-system/domain/events/index.js +32 -6
  31. package/scripts/hooks-system/domain/exceptions/index.js +87 -0
  32. package/scripts/hooks-system/infrastructure/ast/android/analyzers/AndroidAnalysisOrchestrator.js +3 -2
  33. package/scripts/hooks-system/infrastructure/ast/ast-core.js +12 -20
  34. package/scripts/hooks-system/infrastructure/ast/ast-intelligence.js +8 -18
  35. package/scripts/hooks-system/infrastructure/ast/backend/analyzers/BackendPatternDetector.js +2 -1
  36. package/scripts/hooks-system/infrastructure/ast/backend/ast-backend.js +10 -8
  37. package/scripts/hooks-system/infrastructure/ast/frontend/ast-frontend.js +196 -196
  38. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSASTIntelligentAnalyzer.js +3 -2
  39. package/scripts/hooks-system/infrastructure/config/config.js +5 -0
  40. package/scripts/hooks-system/infrastructure/hooks/skill-activation-prompt.js +3 -2
  41. package/scripts/hooks-system/infrastructure/logging/UnifiedLoggerFactory.js +5 -4
  42. package/scripts/hooks-system/infrastructure/mcp/ast-intelligence-automation.js +88 -0
  43. package/scripts/hooks-system/infrastructure/orchestration/intelligent-audit.js +17 -16
  44. package/scripts/hooks-system/infrastructure/telemetry/metric-scope.js +98 -0
  45. package/scripts/hooks-system/infrastructure/telemetry/metrics-server.js +3 -2
  46. package/scripts/hooks-system/infrastructure/validators/enforce-english-literals.js +6 -8
@@ -14,6 +14,50 @@ class HookInstaller {
14
14
  };
15
15
  }
16
16
 
17
+ getPackageRoot() {
18
+ let dir = this.hookSystemRoot;
19
+ for (let i = 0; i < 8; i++) {
20
+ const pkgJson = path.join(dir, 'package.json');
21
+ try {
22
+ if (fs.existsSync(pkgJson) && fs.statSync(pkgJson).isFile()) {
23
+ return dir;
24
+ }
25
+ } catch (error) {
26
+ const msg = error && error.message ? error.message : String(error);
27
+ this.logger?.debug?.('HOOK_INSTALLER_PACKAGE_ROOT_PROBE_ERROR', {
28
+ pkgJson,
29
+ error: msg
30
+ });
31
+ }
32
+
33
+ const parent = path.dirname(dir);
34
+ if (parent === dir) {
35
+ break;
36
+ }
37
+ dir = parent;
38
+ }
39
+
40
+ return path.resolve(this.hookSystemRoot, '..', '..', '..');
41
+ }
42
+
43
+ resolveFirstExistingDir(candidates) {
44
+ for (const candidate of candidates) {
45
+ if (!candidate) continue;
46
+ try {
47
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {
48
+ return candidate;
49
+ }
50
+ } catch (error) {
51
+ const msg = error && error.message ? error.message : String(error);
52
+ this.logger?.debug?.('HOOK_INSTALLER_DIR_PROBE_ERROR', {
53
+ candidate,
54
+ error: msg
55
+ });
56
+ }
57
+ }
58
+ return null;
59
+ }
60
+
17
61
  install(platforms) {
18
62
  const claudeDir = path.join(this.targetRoot, '.ast-intelligence');
19
63
  const claudeSkillsDir = path.join(claudeDir, 'skills');
@@ -31,12 +75,20 @@ class HookInstaller {
31
75
  }
32
76
 
33
77
  installSkills(claudeSkillsDir, platforms) {
34
- const librarySkillsDir = path.join(this.hookSystemRoot, 'skills');
78
+ const packageRoot = this.getPackageRoot();
79
+ const librarySkillsDir = this.resolveFirstExistingDir([
80
+ path.join(this.hookSystemRoot, 'skills'),
81
+ path.join(packageRoot, 'skills')
82
+ ]);
35
83
 
36
- if (!fs.existsSync(librarySkillsDir)) {
84
+ if (!librarySkillsDir) {
37
85
  return;
38
86
  }
39
87
 
88
+ if (!fs.existsSync(claudeSkillsDir)) {
89
+ fs.mkdirSync(claudeSkillsDir, { recursive: true });
90
+ }
91
+
40
92
  const relevantSkills = this.getRelevantSkills(platforms);
41
93
 
42
94
  relevantSkills.forEach(skillName => {
@@ -58,9 +110,13 @@ class HookInstaller {
58
110
  }
59
111
 
60
112
  installHooks(claudeHooksDir) {
61
- const libraryHooksDir = path.join(this.hookSystemRoot, 'hooks');
113
+ const packageRoot = this.getPackageRoot();
114
+ const libraryHooksDir = this.resolveFirstExistingDir([
115
+ path.join(this.hookSystemRoot, 'hooks'),
116
+ path.join(packageRoot, 'hooks')
117
+ ]);
62
118
 
63
- if (!fs.existsSync(libraryHooksDir)) {
119
+ if (!libraryHooksDir) {
64
120
  return;
65
121
  }
66
122
 
@@ -100,7 +156,8 @@ class HookInstaller {
100
156
  }
101
157
 
102
158
  copyIDERules() {
103
- const sourceRulesDir = path.join(this.hookSystemRoot, '.cursor', 'rules');
159
+ const packageRoot = this.getPackageRoot();
160
+ const sourceRulesDir = path.join(packageRoot, '.cursor', 'rules');
104
161
 
105
162
  if (!fs.existsSync(sourceRulesDir)) {
106
163
  return;
@@ -3,6 +3,7 @@ const path = require('path');
3
3
  const { execSync } = require('child_process');
4
4
  const crypto = require('crypto');
5
5
  const os = require('os');
6
+ const env = require('../../config/env');
6
7
 
7
8
  const COLORS = {
8
9
  reset: '\x1b[0m',
@@ -31,7 +32,7 @@ function computeRepoFingerprint(repoRoot) {
31
32
 
32
33
  function computeServerIdForRepo(repoRoot) {
33
34
  const legacyServerId = 'ast-intelligence-automation';
34
- const forced = (process.env.MCP_SERVER_ID || '').trim();
35
+ const forced = (env.get('MCP_SERVER_ID', '') || '').trim();
35
36
  if (forced.length > 0) return forced;
36
37
 
37
38
  const repoName = path.basename(repoRoot || process.cwd());
@@ -3,7 +3,6 @@ const path = require('path');
3
3
 
4
4
  // Import recordMetric for prometheus metrics
5
5
  const { recordMetric } = require('../../../infrastructure/telemetry/metrics-logger');
6
-
7
6
  class AuditLogger {
8
7
  /**
9
8
  * @param {Object} options
@@ -18,7 +17,6 @@ class AuditLogger {
18
17
  status: 'started',
19
18
  repoRoot: repoRoot.substring(0, 100)
20
19
  });
21
-
22
20
  this.repoRoot = repoRoot;
23
21
  this.logger = logger;
24
22
  this.logPath = filename
@@ -147,7 +145,6 @@ class AuditLogger {
147
145
  status: 'started',
148
146
  metaKeys: Object.keys(meta || {}).length
149
147
  });
150
-
151
148
  const forbidden = ['token', 'password', 'secret', 'authorization', 'auth', 'apiKey'];
152
149
  const clone = {};
153
150
  Object.entries(meta).forEach(([k, v]) => {
@@ -165,7 +162,6 @@ class AuditLogger {
165
162
  status: 'success',
166
163
  metaKeys: Object.keys(clone).length
167
164
  });
168
-
169
165
  return clone;
170
166
  }
171
167
  }
@@ -97,10 +97,19 @@ class UnifiedLogger {
97
97
  this.rotateFileIfNeeded();
98
98
  fs.appendFileSync(this.fileConfig.path, `${JSON.stringify(entry)}\n`, 'utf8');
99
99
  } catch (error) {
100
- if (process.env.DEBUG) {
101
- console.error('[UnifiedLogger] Failed to write log file', {
102
- path: this.fileConfig.path,
103
- error: error.message
100
+ try {
101
+ const env = require('../../../config/env');
102
+ if (env.getBool('DEBUG', false)) {
103
+ console.error('[UnifiedLogger] Failed to write log file', {
104
+ path: this.fileConfig.path,
105
+ error: error.message
106
+ });
107
+ } else {
108
+ console.warn('[UnifiedLogger] File logging skipped due to error');
109
+ }
110
+ } catch (secondaryError) {
111
+ console.error('[UnifiedLogger] Secondary logging failure', {
112
+ error: secondaryError.message
104
113
  });
105
114
  }
106
115
  }
@@ -1,6 +1,7 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
  const { execSync } = require('child_process');
4
+ const env = require('../../config/env');
4
5
 
5
6
  function resolveUpdateEvidenceScript(repoRoot) {
6
7
  const candidates = [
@@ -25,9 +26,9 @@ class EvidenceMonitorService {
25
26
  updateScriptPath = resolveUpdateEvidenceScript(repoRoot) || path.join(process.cwd(), 'scripts', 'hooks-system', 'bin', 'update-evidence.sh'),
26
27
  notifier = () => { },
27
28
  logger = console,
28
- autoRefreshEnabled = process.env.HOOK_GUARD_AUTO_REFRESH !== 'false',
29
- autoRefreshCooldownMs = Number(process.env.HOOK_GUARD_AUTO_REFRESH_COOLDOWN || 180000),
30
- staleThresholdMs = Number(process.env.HOOK_GUARD_EVIDENCE_STALE_THRESHOLD || 10 * 60 * 1000),
29
+ autoRefreshEnabled = env.getBool('HOOK_GUARD_AUTO_REFRESH', true),
30
+ autoRefreshCooldownMs = env.getNumber('HOOK_GUARD_AUTO_REFRESH_COOLDOWN', 180000),
31
+ staleThresholdMs = env.getNumber('HOOK_GUARD_EVIDENCE_STALE_THRESHOLD', 10 * 60 * 1000),
31
32
  fsModule = fs,
32
33
  execFn = execSync
33
34
  } = {}) {
@@ -54,7 +54,8 @@ class TokenMetricsService {
54
54
  if (untrusted) {
55
55
  level = 'ok';
56
56
  }
57
- const forceLevel = (process.env.TOKEN_MONITOR_FORCE_LEVEL || '').toLowerCase();
57
+ const env = require('../../config/env');
58
+ const forceLevel = (env.get('TOKEN_MONITOR_FORCE_LEVEL', '') || '').toLowerCase();
58
59
  if (forceLevel === 'warning' || forceLevel === 'critical' || forceLevel === 'ok') {
59
60
  level = forceLevel;
60
61
  }
@@ -121,7 +121,21 @@ const commands = {
121
121
  },
122
122
 
123
123
  ast: () => {
124
- execSync(`node ${path.join(HOOKS_ROOT, 'infrastructure/ast/ast-intelligence.js')}`, { stdio: 'inherit' });
124
+ const env = { ...process.env };
125
+ const filteredArgs = [];
126
+
127
+ for (const arg of args) {
128
+ if (arg === '--staged') {
129
+ env.STAGING_ONLY_MODE = '1';
130
+ } else {
131
+ filteredArgs.push(arg);
132
+ }
133
+ }
134
+
135
+ execSync(
136
+ `node ${path.join(HOOKS_ROOT, 'infrastructure/ast/ast-intelligence.js')} ${filteredArgs.join(' ')}`,
137
+ { stdio: 'inherit', env }
138
+ );
125
139
  },
126
140
 
127
141
  install: () => {
@@ -1,40 +1,20 @@
1
1
  #!/bin/bash
2
- # ═══════════════════════════════════════════════════════════════
3
- # Guard Environment Defaults
4
- # ═══════════════════════════════════════════════════════════════
2
+ # Script Wrapper
3
+ # Redirects to the centralized implementation in scripts/hooks-system
4
+ REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo ".")
5
+ IMPL="$REPO_ROOT/node_modules/@pumuki/ast-intelligence-hooks/scripts/hooks-system/bin/guard-env.sh"
6
+ if [[ -f "$IMPL" ]]; then
7
+ # shellcheck disable=SC1090
8
+ source "$IMPL"
9
+ return 0 2>/dev/null || exit 0
10
+ fi
5
11
 
6
- export HOOK_GUARD_EVIDENCE_STALE_THRESHOLD=${HOOK_GUARD_EVIDENCE_STALE_THRESHOLD:-180000}
7
- export HOOK_GUARD_EVIDENCE_POLL_INTERVAL=${HOOK_GUARD_EVIDENCE_POLL_INTERVAL:-30000}
8
- export HOOK_GUARD_EVIDENCE_REMINDER_INTERVAL=${HOOK_GUARD_EVIDENCE_REMINDER_INTERVAL:-120000}
9
- export HOOK_GUARD_INACTIVITY_GRACE_MS=${HOOK_GUARD_INACTIVITY_GRACE_MS:-60000}
10
- export HOOK_GUARD_AUTO_REFRESH=${HOOK_GUARD_AUTO_REFRESH:-true}
11
- export HOOK_GUARD_AI_START=${HOOK_GUARD_AI_START:-true}
12
- export HOOK_GUARD_AI_START_COOLDOWN=${HOOK_GUARD_AI_START_COOLDOWN:-60000}
13
- export HOOK_GUARD_EMBEDDED_TOKEN_MONITOR=${HOOK_GUARD_EMBEDDED_TOKEN_MONITOR:-false}
14
- export HOOK_GUARD_AUTORELOAD_DEBOUNCE=${HOOK_GUARD_AUTORELOAD_DEBOUNCE:-1500}
15
- export HOOK_GUARD_AUTORELOAD_FORCE=${HOOK_GUARD_AUTORELOAD_FORCE:-5000}
16
- export HOOK_GUARD_DIRTY_TREE_LIMIT=${HOOK_GUARD_DIRTY_TREE_LIMIT:-24}
17
- export HOOK_GUARD_DIRTY_TREE_WARNING=${HOOK_GUARD_DIRTY_TREE_WARNING:-12}
18
- export HOOK_GUARD_DIRTY_TREE_INTERVAL=${HOOK_GUARD_DIRTY_TREE_INTERVAL:-60000}
19
- export HOOK_GUARD_DIRTY_TREE_REMINDER=${HOOK_GUARD_DIRTY_TREE_REMINDER:-300000}
20
- export TOKEN_MONITOR_INTERVAL=${TOKEN_MONITOR_INTERVAL:-180}
21
- export TOKEN_MONITOR_REMINDER_SECONDS=${TOKEN_MONITOR_REMINDER_SECONDS:-180}
22
- export TOKEN_MONITOR_MIN_DELTA=${TOKEN_MONITOR_MIN_DELTA:-25000}
23
- export HOOK_GUARD_GITFLOW_AUTOSYNC=${HOOK_GUARD_GITFLOW_AUTOSYNC:-true}
24
- export HOOK_GUARD_GITFLOW_AUTOSYNC_INTERVAL=${HOOK_GUARD_GITFLOW_AUTOSYNC_INTERVAL:-300000}
25
- export HOOK_GUARD_GITFLOW_AUTOSYNC_COOLDOWN=${HOOK_GUARD_GITFLOW_AUTOSYNC_COOLDOWN:-900000}
26
- export HOOK_GUARD_GITFLOW_AUTOCLEAN=${HOOK_GUARD_GITFLOW_AUTOCLEAN:-true}
27
- export HOOK_GUARD_GITFLOW_MAIN_BRANCH=${HOOK_GUARD_GITFLOW_MAIN_BRANCH:-main}
28
- export HOOK_GUARD_GITFLOW_DEVELOP_BRANCH=${HOOK_GUARD_GITFLOW_DEVELOP_BRANCH:-develop}
29
- export HOOK_GUARD_GITFLOW_REQUIRE_CLEAN=${HOOK_GUARD_GITFLOW_REQUIRE_CLEAN:-true}
30
- export GUARD_AUTOSTART_HEALTHY_INTERVAL=${GUARD_AUTOSTART_HEALTHY_INTERVAL:-0}
31
- export GUARD_AUTOSTART_HEALTHY_COOLDOWN=${GUARD_AUTOSTART_HEALTHY_COOLDOWN:-900000}
32
- export HOOK_GUARD_HEARTBEAT_PATH="${HOOK_GUARD_HEARTBEAT_PATH:-.audit_tmp/guard-heartbeat.json}"
33
- export HOOK_GUARD_HEARTBEAT_INTERVAL=${HOOK_GUARD_HEARTBEAT_INTERVAL:-15000}
34
- export HOOK_GUARD_HEARTBEAT_MAX_AGE=${HOOK_GUARD_HEARTBEAT_MAX_AGE:-45000}
35
- export HOOK_GUARD_HEARTBEAT_CHECK_INTERVAL=${HOOK_GUARD_HEARTBEAT_CHECK_INTERVAL:-15000}
36
- export HOOK_GUARD_HEARTBEAT_NOTIFY_COOLDOWN=${HOOK_GUARD_HEARTBEAT_NOTIFY_COOLDOWN:-180000}
37
- export HOOK_GUARD_GITFLOW_MONITOR=${HOOK_GUARD_GITFLOW_MONITOR:-true}
38
- export HOOK_GUARD_GITFLOW_MONITOR_INTERVAL=${HOOK_GUARD_GITFLOW_MONITOR_INTERVAL:-300000}
39
- export HOOK_GUARD_GITFLOW_BRANCH_COOLDOWN=${HOOK_GUARD_GITFLOW_BRANCH_COOLDOWN:-900000}
40
- export HOOK_GUARD_DEV_DOCS_AUTO_REFRESH=${HOOK_GUARD_DEV_DOCS_AUTO_REFRESH:-true}
12
+ IMPL="$REPO_ROOT/node_modules/pumuki-ast-hooks/scripts/hooks-system/bin/guard-env.sh"
13
+ if [[ -f "$IMPL" ]]; then
14
+ # shellcheck disable=SC1090
15
+ source "$IMPL"
16
+ return 0 2>/dev/null || exit 0
17
+ fi
18
+
19
+ echo "guard-env.sh implementation not found. Please reinstall dependencies." >&2
20
+ return 1 2>/dev/null || exit 1