pumuki-ast-hooks 5.3.18 → 5.3.20

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 (91) hide show
  1. package/docs/VIOLATIONS_RESOLUTION_PLAN.md +39 -37
  2. package/package.json +8 -2
  3. package/scripts/hooks-system/application/CompositionRoot.js +24 -73
  4. package/scripts/hooks-system/application/services/AutonomousOrchestrator.js +18 -0
  5. package/scripts/hooks-system/application/services/ContextDetectionEngine.js +58 -0
  6. package/scripts/hooks-system/application/services/DynamicRulesLoader.js +12 -2
  7. package/scripts/hooks-system/application/services/GitFlowService.js +80 -0
  8. package/scripts/hooks-system/application/services/GitTreeState.js +143 -13
  9. package/scripts/hooks-system/application/services/HookSystemScheduler.js +47 -0
  10. package/scripts/hooks-system/application/services/IntelligentCommitAnalyzer.js +25 -0
  11. package/scripts/hooks-system/application/services/IntelligentGitTreeMonitor.js +11 -0
  12. package/scripts/hooks-system/application/services/PlatformAnalysisService.js +19 -0
  13. package/scripts/hooks-system/application/services/PlatformDetectionService.js +19 -0
  14. package/scripts/hooks-system/application/services/PlaybookRunner.js +22 -1
  15. package/scripts/hooks-system/application/services/PredictiveHookAdvisor.js +19 -0
  16. package/scripts/hooks-system/application/services/RealtimeGuardPlugin.js +25 -0
  17. package/scripts/hooks-system/application/services/RealtimeGuardService.js +41 -84
  18. package/scripts/hooks-system/application/services/SmartDirtyTreeAnalyzer.js +11 -0
  19. package/scripts/hooks-system/application/services/commit/CommitMessageGenerator.js +11 -0
  20. package/scripts/hooks-system/application/services/commit/FeatureDetector.js +11 -0
  21. package/scripts/hooks-system/application/services/evidence/EvidenceContextManager.js +25 -0
  22. package/scripts/hooks-system/application/services/guard/GuardAutoManagerService.js +21 -31
  23. package/scripts/hooks-system/application/services/guard/GuardConfig.js +18 -15
  24. package/scripts/hooks-system/application/services/guard/GuardEventLogger.js +11 -0
  25. package/scripts/hooks-system/application/services/guard/GuardHealthReminder.js +26 -0
  26. package/scripts/hooks-system/application/services/guard/GuardHeartbeatMonitor.js +20 -6
  27. package/scripts/hooks-system/application/services/guard/GuardLockManager.js +11 -0
  28. package/scripts/hooks-system/application/services/guard/GuardMonitorLoop.js +25 -0
  29. package/scripts/hooks-system/application/services/guard/GuardNotificationHandler.js +11 -0
  30. package/scripts/hooks-system/application/services/guard/GuardProcessManager.js +10 -28
  31. package/scripts/hooks-system/application/services/guard/GuardRecoveryService.js +11 -0
  32. package/scripts/hooks-system/application/services/installation/ConfigurationGeneratorService.js +18 -0
  33. package/scripts/hooks-system/application/services/installation/FileSystemInstallerService.js +18 -0
  34. package/scripts/hooks-system/application/services/installation/GitEnvironmentService.js +18 -3
  35. package/scripts/hooks-system/application/services/installation/HookInstaller.js +19 -0
  36. package/scripts/hooks-system/application/services/installation/IdeIntegrationService.js +11 -0
  37. package/scripts/hooks-system/application/services/installation/InstallService.js +25 -1
  38. package/scripts/hooks-system/application/services/installation/McpConfigurator.js +19 -2
  39. package/scripts/hooks-system/application/services/installation/PlatformDetectorService.js +11 -0
  40. package/scripts/hooks-system/application/services/installation/VSCodeTaskConfigurator.js +11 -0
  41. package/scripts/hooks-system/application/services/logging/AuditLogger.js +90 -1
  42. package/scripts/hooks-system/application/services/logging/UnifiedLogger.js +15 -13
  43. package/scripts/hooks-system/application/services/monitoring/ActivityMonitor.js +33 -0
  44. package/scripts/hooks-system/application/services/monitoring/AstMonitor.js +27 -0
  45. package/scripts/hooks-system/application/services/monitoring/DevDocsMonitor.js +26 -0
  46. package/scripts/hooks-system/application/services/monitoring/EvidenceMonitor.js +19 -0
  47. package/scripts/hooks-system/application/services/monitoring/EvidenceMonitorService.js +27 -6
  48. package/scripts/hooks-system/application/services/monitoring/GitTreeMonitor.js +28 -0
  49. package/scripts/hooks-system/application/services/monitoring/GitTreeMonitorService.js +26 -0
  50. package/scripts/hooks-system/application/services/monitoring/HealthCheckProviders.js +4 -0
  51. package/scripts/hooks-system/application/services/monitoring/HealthCheckService.js +25 -0
  52. package/scripts/hooks-system/application/services/monitoring/HeartbeatMonitorService.js +26 -0
  53. package/scripts/hooks-system/application/services/monitoring/TokenMonitor.js +26 -0
  54. package/scripts/hooks-system/application/services/notification/MacNotificationSender.js +11 -0
  55. package/scripts/hooks-system/application/services/notification/NotificationCenterService.js +18 -0
  56. package/scripts/hooks-system/application/services/notification/NotificationDispatcher.js +11 -0
  57. package/scripts/hooks-system/application/services/notification/components/NotificationCooldownManager.js +18 -0
  58. package/scripts/hooks-system/application/services/notification/components/NotificationDeduplicator.js +18 -0
  59. package/scripts/hooks-system/application/services/notification/components/NotificationQueue.js +11 -0
  60. package/scripts/hooks-system/application/services/notification/components/NotificationRetryExecutor.js +20 -0
  61. package/scripts/hooks-system/application/services/platform/PlatformHeuristics.js +19 -0
  62. package/scripts/hooks-system/application/services/recovery/AutoRecoveryManager.js +19 -0
  63. package/scripts/hooks-system/application/services/smart-commit/CommitMessageSuggester.js +11 -0
  64. package/scripts/hooks-system/application/services/smart-commit/FileContextGrouper.js +19 -0
  65. package/scripts/hooks-system/application/services/smart-commit/SmartCommitSummaryBuilder.js +4 -0
  66. package/scripts/hooks-system/application/services/token/CursorTokenService.js +20 -0
  67. package/scripts/hooks-system/application/services/token/TokenMetricsService.js +11 -13
  68. package/scripts/hooks-system/application/services/token/TokenMonitorService.js +19 -0
  69. package/scripts/hooks-system/application/services/token/TokenStatusReporter.js +12 -0
  70. package/scripts/hooks-system/bin/__tests__/evidence-update.spec.js +49 -0
  71. package/scripts/hooks-system/bin/cli.js +1 -15
  72. package/scripts/hooks-system/config/project.config.json +1 -1
  73. package/scripts/hooks-system/domain/events/index.js +24 -31
  74. package/scripts/hooks-system/domain/exceptions/index.js +87 -0
  75. package/scripts/hooks-system/infrastructure/ast/android/analyzers/AndroidAnalysisOrchestrator.js +2 -3
  76. package/scripts/hooks-system/infrastructure/ast/ast-core.js +20 -12
  77. package/scripts/hooks-system/infrastructure/ast/ast-intelligence.js +18 -8
  78. package/scripts/hooks-system/infrastructure/ast/backend/analyzers/BackendPatternDetector.js +1 -2
  79. package/scripts/hooks-system/infrastructure/ast/backend/ast-backend.js +14 -18
  80. package/scripts/hooks-system/infrastructure/ast/frontend/ast-frontend.js +196 -196
  81. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/__tests__/iOSASTIntelligentAnalyzer.spec.js +66 -0
  82. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSASTIntelligentAnalyzer.js +2 -3
  83. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSArchitectureRules.js +24 -86
  84. package/scripts/hooks-system/infrastructure/config/config.js +5 -0
  85. package/scripts/hooks-system/infrastructure/hooks/skill-activation-prompt.js +2 -3
  86. package/scripts/hooks-system/infrastructure/logging/UnifiedLoggerFactory.js +5 -35
  87. package/scripts/hooks-system/infrastructure/orchestration/intelligent-audit.js +16 -86
  88. package/scripts/hooks-system/infrastructure/shell/orchestrators/audit-orchestrator.sh +54 -92
  89. package/scripts/hooks-system/infrastructure/telemetry/metric-scope.js +98 -0
  90. package/scripts/hooks-system/infrastructure/telemetry/metrics-server.js +2 -51
  91. package/scripts/hooks-system/infrastructure/validators/enforce-english-literals.js +8 -6
@@ -1,8 +1,18 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
 
4
+ const {
5
+ createMetricScope: createMetricScope
6
+ } = require('../../../infrastructure/telemetry/metric-scope');
7
+
4
8
  class VSCodeTaskConfigurator {
5
9
  constructor(targetRoot, logger = null) {
10
+ const m_constructor = createMetricScope({
11
+ hook: 'vscode_task_configurator',
12
+ operation: 'constructor'
13
+ });
14
+
15
+ m_constructor.started();
6
16
  this.targetRoot = targetRoot;
7
17
  this.logger = logger;
8
18
  this.COLORS = {
@@ -11,6 +21,7 @@ class VSCodeTaskConfigurator {
11
21
  yellow: '\x1b[33m',
12
22
  cyan: '\x1b[36m'
13
23
  };
24
+ m_constructor.success();
14
25
  }
15
26
 
16
27
  configure() {
@@ -1,6 +1,13 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
 
4
+ // Import recordMetric for prometheus metrics
5
+ const { recordMetric } = require('../../../infrastructure/telemetry/metrics-logger');
6
+
7
+ const {
8
+ createMetricScope: createMetricScope
9
+ } = require('../../../infrastructure/telemetry/metric-scope');
10
+
4
11
  class AuditLogger {
5
12
  /**
6
13
  * @param {Object} options
@@ -9,6 +16,13 @@ class AuditLogger {
9
16
  * @param {Object} [options.logger=console] - fallback logger for warnings
10
17
  */
11
18
  constructor({ repoRoot = process.cwd(), filename, logger = console } = {}) {
19
+ recordMetric({
20
+ hook: 'audit_logger',
21
+ operation: 'constructor',
22
+ status: 'started',
23
+ repoRoot: repoRoot.substring(0, 100)
24
+ });
25
+
12
26
  this.repoRoot = repoRoot;
13
27
  this.logger = logger;
14
28
  this.logPath = filename
@@ -16,9 +30,22 @@ class AuditLogger {
16
30
  : path.join(repoRoot, '.audit_tmp', 'audit.log');
17
31
 
18
32
  this.ensureDir();
33
+
34
+ recordMetric({
35
+ hook: 'audit_logger',
36
+ operation: 'constructor',
37
+ status: 'success',
38
+ repoRoot: repoRoot.substring(0, 100)
39
+ });
19
40
  }
20
41
 
21
42
  ensureDir() {
43
+ recordMetric({
44
+ hook: 'audit_logger',
45
+ operation: 'ensure_dir',
46
+ status: 'started'
47
+ });
48
+
22
49
  try {
23
50
  const dir = path.dirname(this.logPath);
24
51
  if (!fs.existsSync(dir)) {
@@ -30,14 +57,33 @@ class AuditLogger {
30
57
  } catch (error) {
31
58
  this.warn('AUDIT_LOGGER_INIT_ERROR', error);
32
59
  }
60
+
61
+ recordMetric({
62
+ hook: 'audit_logger',
63
+ operation: 'ensure_dir',
64
+ status: 'success'
65
+ });
33
66
  }
34
67
 
35
68
  warn(message, error) {
69
+ recordMetric({
70
+ hook: 'audit_logger',
71
+ operation: 'warn',
72
+ status: 'started',
73
+ message: message
74
+ });
75
+
36
76
  if (this.logger?.warn) {
37
77
  this.logger.warn(message, { error: error?.message });
38
78
  } else {
39
79
  console.warn(message, error?.message);
40
80
  }
81
+
82
+ recordMetric({
83
+ hook: 'audit_logger',
84
+ operation: 'warn',
85
+ status: 'success'
86
+ });
41
87
  }
42
88
 
43
89
  /**
@@ -50,7 +96,22 @@ class AuditLogger {
50
96
  * @param {string|null} [entry.correlationId=null]
51
97
  */
52
98
  record(entry = {}) {
53
- if (!entry.action) return;
99
+ recordMetric({
100
+ hook: 'audit_logger',
101
+ operation: 'record',
102
+ status: 'started',
103
+ action: entry.action
104
+ });
105
+
106
+ if (!entry.action) {
107
+ recordMetric({
108
+ hook: 'audit_logger',
109
+ operation: 'record',
110
+ status: 'success',
111
+ reason: 'no_action'
112
+ });
113
+ return;
114
+ }
54
115
  const safeMeta = this.sanitizeMeta(entry.meta || {});
55
116
 
56
117
  const payload = {
@@ -65,12 +126,32 @@ class AuditLogger {
65
126
 
66
127
  try {
67
128
  fs.appendFileSync(this.logPath, `${JSON.stringify(payload)}\n`, { encoding: 'utf8' });
129
+ recordMetric({
130
+ hook: 'audit_logger',
131
+ operation: 'record',
132
+ status: 'success',
133
+ action: entry.action
134
+ });
68
135
  } catch (error) {
69
136
  this.warn('AUDIT_LOGGER_WRITE_ERROR', error);
137
+ recordMetric({
138
+ hook: 'audit_logger',
139
+ operation: 'record',
140
+ status: 'failed',
141
+ action: entry.action,
142
+ error: error.message
143
+ });
70
144
  }
71
145
  }
72
146
 
73
147
  sanitizeMeta(meta) {
148
+ recordMetric({
149
+ hook: 'audit_logger',
150
+ operation: 'sanitize_meta',
151
+ status: 'started',
152
+ metaKeys: Object.keys(meta || {}).length
153
+ });
154
+
74
155
  const forbidden = ['token', 'password', 'secret', 'authorization', 'auth', 'apiKey'];
75
156
  const clone = {};
76
157
  Object.entries(meta).forEach(([k, v]) => {
@@ -81,6 +162,14 @@ class AuditLogger {
81
162
  clone[k] = v;
82
163
  }
83
164
  });
165
+
166
+ recordMetric({
167
+ hook: 'audit_logger',
168
+ operation: 'sanitize_meta',
169
+ status: 'success',
170
+ metaKeys: Object.keys(clone).length
171
+ });
172
+
84
173
  return clone;
85
174
  }
86
175
  }
@@ -2,6 +2,10 @@ const fs = require('fs');
2
2
  const path = require('path');
3
3
  const { ConfigurationError } = require('../../../domain/errors');
4
4
 
5
+ const {
6
+ createMetricScope: createMetricScope
7
+ } = require('../../../infrastructure/telemetry/metric-scope');
8
+
5
9
  class UnifiedLogger {
6
10
  constructor({
7
11
  component = 'HookSystem',
@@ -9,6 +13,12 @@ class UnifiedLogger {
9
13
  file: fileConfig = { enabled: false },
10
14
  defaultData = {}
11
15
  } = {}) {
16
+ const m_constructor = createMetricScope({
17
+ hook: 'unified_logger',
18
+ operation: 'constructor'
19
+ });
20
+
21
+ m_constructor.started();
12
22
  this.component = component;
13
23
  this.consoleConfig = {
14
24
  enabled: consoleConfig.enabled !== false,
@@ -41,6 +51,7 @@ class UnifiedLogger {
41
51
  // Directory creation might fail if race condition, can be ignored as next write will retry or fail
42
52
  }
43
53
  }
54
+ m_constructor.success();
44
55
  }
45
56
 
46
57
  debug(event, data = {}, context = {}) {
@@ -97,19 +108,10 @@ class UnifiedLogger {
97
108
  this.rotateFileIfNeeded();
98
109
  fs.appendFileSync(this.fileConfig.path, `${JSON.stringify(entry)}\n`, 'utf8');
99
110
  } catch (error) {
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
111
+ if (process.env.DEBUG) {
112
+ console.error('[UnifiedLogger] Failed to write log file', {
113
+ path: this.fileConfig.path,
114
+ error: error.message
113
115
  });
114
116
  }
115
117
  }
@@ -1,22 +1,40 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
 
4
+ const {
5
+ createMetricScope: createMetricScope
6
+ } = require('../../../infrastructure/telemetry/metric-scope');
7
+
4
8
  class ActivityMonitor {
5
9
  constructor({
6
10
  repoRoot = process.cwd(),
7
11
  inactivityGraceMs = 420000, // 7 minutes
8
12
  logger = console
9
13
  } = {}) {
14
+ const m_constructor = createMetricScope({
15
+ hook: 'activity_monitor',
16
+ operation: 'constructor'
17
+ });
18
+
19
+ m_constructor.started();
10
20
  this.repoRoot = repoRoot;
11
21
  this.inactivityGraceMs = inactivityGraceMs;
12
22
  this.logger = logger;
13
23
  this.lastUserActivityAt = Date.now();
14
24
  this.watcher = null;
15
25
  this.debounceTimer = null;
26
+ m_constructor.success();
16
27
  }
17
28
 
18
29
  start() {
30
+ const m_start = createMetricScope({
31
+ hook: 'activity_monitor',
32
+ operation: 'start'
33
+ });
34
+
35
+ m_start.started();
19
36
  if (this.watcher) {
37
+ m_start.success();
20
38
  return;
21
39
  }
22
40
 
@@ -42,9 +60,16 @@ class ActivityMonitor {
42
60
  } catch (error) {
43
61
  this.logger.error('[ActivityMonitor] Failed to start watcher:', { error: error.message });
44
62
  }
63
+ m_start.success();
45
64
  }
46
65
 
47
66
  stop() {
67
+ const m_stop = createMetricScope({
68
+ hook: 'activity_monitor',
69
+ operation: 'stop'
70
+ });
71
+
72
+ m_stop.started();
48
73
  if (this.watcher) {
49
74
  this.watcher.close();
50
75
  this.watcher = null;
@@ -53,6 +78,7 @@ class ActivityMonitor {
53
78
  clearTimeout(this.debounceTimer);
54
79
  this.debounceTimer = null;
55
80
  }
81
+ m_stop.success();
56
82
  }
57
83
 
58
84
  recordActivity(source = 'unknown') {
@@ -73,6 +99,13 @@ class ActivityMonitor {
73
99
  }
74
100
 
75
101
  getLastActivityTime() {
102
+ const m_get_last_activity_time = createMetricScope({
103
+ hook: 'activity_monitor',
104
+ operation: 'get_last_activity_time'
105
+ });
106
+
107
+ m_get_last_activity_time.started();
108
+ m_get_last_activity_time.success();
76
109
  return this.lastUserActivityAt;
77
110
  }
78
111
  }
@@ -2,6 +2,10 @@ const fs = require('fs');
2
2
  const path = require('path');
3
3
  const { spawn } = require('child_process');
4
4
 
5
+ const {
6
+ createMetricScope: createMetricScope
7
+ } = require('../../../infrastructure/telemetry/metric-scope');
8
+
5
9
  class AstMonitor {
6
10
  constructor({
7
11
  repoRoot = process.cwd(),
@@ -11,6 +15,12 @@ class AstMonitor {
11
15
  logger = console,
12
16
  notificationService = null
13
17
  } = {}) {
18
+ const m_constructor = createMetricScope({
19
+ hook: 'ast_monitor',
20
+ operation: 'constructor'
21
+ });
22
+
23
+ m_constructor.started();
14
24
  this.repoRoot = repoRoot;
15
25
  this.debounceMs = debounceMs;
16
26
  this.cooldownMs = cooldownMs;
@@ -26,15 +36,24 @@ class AstMonitor {
26
36
  this.evidencePath = path.join(repoRoot, '.AI_EVIDENCE.json');
27
37
  this.tempDir = path.join(repoRoot, '.audit_tmp');
28
38
  this.astScript = path.join(repoRoot, 'infrastructure', 'ast', 'ast-intelligence.js');
39
+ m_constructor.success();
29
40
  }
30
41
 
31
42
  start() {
43
+ const m_start = createMetricScope({
44
+ hook: 'ast_monitor',
45
+ operation: 'start'
46
+ });
47
+
48
+ m_start.started();
32
49
  if (!this.enabled) {
33
50
  this.logger.info('[AstMonitor] AST Watch disabled');
51
+ m_start.success();
34
52
  return;
35
53
  }
36
54
 
37
55
  if (this.watcher) {
56
+ m_start.success();
38
57
  return;
39
58
  }
40
59
 
@@ -58,9 +77,16 @@ class AstMonitor {
58
77
  } catch (error) {
59
78
  this.logger.error('[AstMonitor] Failed to start watchers:', { error: error.message });
60
79
  }
80
+ m_start.success();
61
81
  }
62
82
 
63
83
  stop() {
84
+ const m_stop = createMetricScope({
85
+ hook: 'ast_monitor',
86
+ operation: 'stop'
87
+ });
88
+
89
+ m_stop.started();
64
90
  // fs.watch returns FSWatcher which has close().
65
91
  // Since we might have multiple watchers (one per dir), we should track them if we want to close properly.
66
92
  // For simplicity in this iteration, we assume the process exit handles it, or we rely on the debounce timer clear.
@@ -70,6 +96,7 @@ class AstMonitor {
70
96
  this.timer = null;
71
97
  }
72
98
  // Ideally we would close all FSWatchers here
99
+ m_stop.success();
73
100
  }
74
101
 
75
102
  scheduleAnalysis() {
@@ -1,6 +1,10 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
 
4
+ const {
5
+ createMetricScope: createMetricScope
6
+ } = require('../../../infrastructure/telemetry/metric-scope');
7
+
4
8
  class DevDocsMonitor {
5
9
  constructor({
6
10
  repoRoot = process.cwd(),
@@ -10,6 +14,12 @@ class DevDocsMonitor {
10
14
  logger = console,
11
15
  notificationService = null
12
16
  } = {}) {
17
+ const m_constructor = createMetricScope({
18
+ hook: 'dev_docs_monitor',
19
+ operation: 'constructor'
20
+ });
21
+
22
+ m_constructor.started();
13
23
  this.repoRoot = repoRoot;
14
24
  this.checkIntervalMs = checkIntervalMs;
15
25
  this.staleThresholdMs = staleThresholdMs;
@@ -18,11 +28,19 @@ class DevDocsMonitor {
18
28
  this.notificationService = notificationService;
19
29
  this.timer = null;
20
30
  this.docsStatePath = path.join(repoRoot, '.audit_tmp', 'dev-docs-state.json');
31
+ m_constructor.success();
21
32
  }
22
33
 
23
34
  start() {
35
+ const m_start = createMetricScope({
36
+ hook: 'dev_docs_monitor',
37
+ operation: 'start'
38
+ });
39
+
40
+ m_start.started();
24
41
  if (!this.autoRefreshEnabled) {
25
42
  this.logger.info('[DevDocsMonitor] Auto-refresh disabled');
43
+ m_start.success();
26
44
  return;
27
45
  }
28
46
 
@@ -32,13 +50,21 @@ class DevDocsMonitor {
32
50
  this.timer.unref();
33
51
  }
34
52
  this.logger.info('[DevDocsMonitor] Started');
53
+ m_start.success();
35
54
  }
36
55
 
37
56
  stop() {
57
+ const m_stop = createMetricScope({
58
+ hook: 'dev_docs_monitor',
59
+ operation: 'stop'
60
+ });
61
+
62
+ m_stop.started();
38
63
  if (this.timer) {
39
64
  clearInterval(this.timer);
40
65
  this.timer = null;
41
66
  }
67
+ m_stop.success();
42
68
  }
43
69
 
44
70
  async checkDocs() {
@@ -3,8 +3,18 @@ const path = require('path');
3
3
  const { execSync } = require('child_process');
4
4
  const { ConfigurationError, DomainError } = require('../../../domain/errors');
5
5
 
6
+ const {
7
+ createMetricScope: createMetricScope
8
+ } = require('../../../infrastructure/telemetry/metric-scope');
9
+
6
10
  class EvidenceMonitor {
7
11
  constructor(repoRoot, options = {}) {
12
+ const m_constructor = createMetricScope({
13
+ hook: 'evidence_monitor',
14
+ operation: 'constructor'
15
+ });
16
+
17
+ m_constructor.started();
8
18
  this.repoRoot = repoRoot;
9
19
  this.staleThresholdMs = options.staleThresholdMs || 180000;
10
20
  this.pollIntervalMs = options.pollIntervalMs || 30000;
@@ -14,11 +24,13 @@ class EvidenceMonitor {
14
24
  this.evidencePath = path.join(repoRoot, '.AI_EVIDENCE.json');
15
25
  this.tempDir = path.join(repoRoot, '.audit_tmp');
16
26
  this.updateScript = this.resolveUpdateEvidenceScript();
27
+ m_constructor.success();
17
28
  }
18
29
 
19
30
  resolveUpdateEvidenceScript() {
20
31
  const candidates = [
21
32
  path.join(this.repoRoot, 'node_modules/@pumuki/ast-intelligence-hooks/bin/update-evidence.sh'),
33
+ path.join(this.repoRoot, 'scripts/hooks-system/bin/update-evidence.sh'),
22
34
  path.join(this.repoRoot, 'bin/update-evidence.sh')
23
35
  ];
24
36
 
@@ -93,10 +105,17 @@ class EvidenceMonitor {
93
105
  }
94
106
 
95
107
  stop() {
108
+ const m_stop = createMetricScope({
109
+ hook: 'evidence_monitor',
110
+ operation: 'stop'
111
+ });
112
+
113
+ m_stop.started();
96
114
  if (this.pollTimer) {
97
115
  clearInterval(this.pollTimer);
98
116
  this.pollTimer = null;
99
117
  }
118
+ m_stop.success();
100
119
  }
101
120
  }
102
121
 
@@ -1,10 +1,10 @@
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');
5
4
 
6
- // Import recordMetric for prometheus metrics
7
- const { recordMetric } = require('../../../infrastructure/telemetry/metrics-logger');
5
+ const {
6
+ createMetricScope: createMetricScope
7
+ } = require('../../../infrastructure/telemetry/metric-scope');
8
8
 
9
9
  function resolveUpdateEvidenceScript(repoRoot) {
10
10
  const candidates = [
@@ -29,12 +29,18 @@ class EvidenceMonitorService {
29
29
  updateScriptPath = resolveUpdateEvidenceScript(repoRoot) || path.join(process.cwd(), 'scripts', 'hooks-system', 'bin', 'update-evidence.sh'),
30
30
  notifier = () => { },
31
31
  logger = console,
32
- autoRefreshEnabled = env.getBool('HOOK_GUARD_AUTO_REFRESH', true),
33
- autoRefreshCooldownMs = env.getNumber('HOOK_GUARD_AUTO_REFRESH_COOLDOWN', 180000),
34
- staleThresholdMs = env.getNumber('HOOK_GUARD_EVIDENCE_STALE_THRESHOLD', 10 * 60 * 1000),
32
+ autoRefreshEnabled = process.env.HOOK_GUARD_AUTO_REFRESH !== 'false',
33
+ autoRefreshCooldownMs = Number(process.env.HOOK_GUARD_AUTO_REFRESH_COOLDOWN || 180000),
34
+ staleThresholdMs = Number(process.env.HOOK_GUARD_EVIDENCE_STALE_THRESHOLD || 10 * 60 * 1000),
35
35
  fsModule = fs,
36
36
  execFn = execSync
37
37
  } = {}) {
38
+ const m_constructor = createMetricScope({
39
+ hook: 'evidence_monitor_service',
40
+ operation: 'constructor'
41
+ });
42
+
43
+ m_constructor.started();
38
44
  this.repoRoot = repoRoot;
39
45
  this.evidencePath = evidencePath;
40
46
  this.updateScriptPath = updateScriptPath;
@@ -47,14 +53,28 @@ class EvidenceMonitorService {
47
53
  this.exec = execFn;
48
54
  this.watchers = [];
49
55
  this.lastAutoRefresh = 0;
56
+ m_constructor.success();
50
57
  }
51
58
 
52
59
  start() {
60
+ const m_start = createMetricScope({
61
+ hook: 'evidence_monitor_service',
62
+ operation: 'start'
63
+ });
64
+
65
+ m_start.started();
53
66
  this.performInitialChecks();
54
67
  this.watchEvidenceFreshness();
68
+ m_start.success();
55
69
  }
56
70
 
57
71
  stop() {
72
+ const m_stop = createMetricScope({
73
+ hook: 'evidence_monitor_service',
74
+ operation: 'stop'
75
+ });
76
+
77
+ m_stop.started();
58
78
  this.watchers.forEach(watcher => {
59
79
  try {
60
80
  watcher.close();
@@ -63,6 +83,7 @@ class EvidenceMonitorService {
63
83
  }
64
84
  });
65
85
  this.watchers = [];
86
+ m_stop.success();
66
87
  }
67
88
 
68
89
  performInitialChecks() {
@@ -2,8 +2,18 @@ const fs = require('fs');
2
2
  const path = require('path');
3
3
  const { execSync } = require('child_process');
4
4
 
5
+ const {
6
+ createMetricScope: createMetricScope
7
+ } = require('../../../infrastructure/telemetry/metric-scope');
8
+
5
9
  class GitTreeMonitor {
6
10
  constructor(repoRoot, options = {}) {
11
+ const m_constructor = createMetricScope({
12
+ hook: 'git_tree_monitor',
13
+ operation: 'constructor'
14
+ });
15
+
16
+ m_constructor.started();
7
17
  this.repoRoot = repoRoot;
8
18
  this.stagedThreshold = options.stagedThreshold || 10;
9
19
  this.unstagedThreshold = options.unstagedThreshold || 15;
@@ -17,6 +27,7 @@ class GitTreeMonitor {
17
27
  this.timer = null;
18
28
  this.lastState = null;
19
29
  this.loadState();
30
+ m_constructor.success();
20
31
  }
21
32
 
22
33
  loadState() {
@@ -39,6 +50,12 @@ class GitTreeMonitor {
39
50
  }
40
51
 
41
52
  getTreeState() {
53
+ const m_get_tree_state = createMetricScope({
54
+ hook: 'git_tree_monitor',
55
+ operation: 'get_tree_state'
56
+ });
57
+
58
+ m_get_tree_state.started();
42
59
  try {
43
60
  const stagedRaw = execSync('git diff --cached --name-only', {
44
61
  cwd: this.repoRoot,
@@ -58,6 +75,8 @@ class GitTreeMonitor {
58
75
  const untracked = untrackedRaw ? untrackedRaw.split('\n').length : 0;
59
76
  const total = staged + unstaged + untracked;
60
77
 
78
+ m_get_tree_state.success();
79
+
61
80
  return {
62
81
  staged,
63
82
  unstaged,
@@ -69,6 +88,7 @@ class GitTreeMonitor {
69
88
  timestamp: Date.now()
70
89
  };
71
90
  } catch (error) {
91
+ m_get_tree_state.success();
72
92
  return {
73
93
  staged: 0,
74
94
  unstaged: 0,
@@ -79,6 +99,7 @@ class GitTreeMonitor {
79
99
  timestamp: Date.now()
80
100
  };
81
101
  }
102
+ m_get_tree_state.success();
82
103
  }
83
104
 
84
105
  startMonitoring(onStateChange) {
@@ -109,10 +130,17 @@ class GitTreeMonitor {
109
130
  }
110
131
 
111
132
  stop() {
133
+ const m_stop = createMetricScope({
134
+ hook: 'git_tree_monitor',
135
+ operation: 'stop'
136
+ });
137
+
138
+ m_stop.started();
112
139
  if (this.timer) {
113
140
  clearInterval(this.timer);
114
141
  this.timer = null;
115
142
  }
143
+ m_stop.success();
116
144
  }
117
145
 
118
146
  isActive() {