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.
- package/docs/VIOLATIONS_RESOLUTION_PLAN.md +39 -37
- package/package.json +8 -2
- package/scripts/hooks-system/application/CompositionRoot.js +24 -73
- package/scripts/hooks-system/application/services/AutonomousOrchestrator.js +18 -0
- package/scripts/hooks-system/application/services/ContextDetectionEngine.js +58 -0
- package/scripts/hooks-system/application/services/DynamicRulesLoader.js +12 -2
- package/scripts/hooks-system/application/services/GitFlowService.js +80 -0
- package/scripts/hooks-system/application/services/GitTreeState.js +143 -13
- package/scripts/hooks-system/application/services/HookSystemScheduler.js +47 -0
- package/scripts/hooks-system/application/services/IntelligentCommitAnalyzer.js +25 -0
- package/scripts/hooks-system/application/services/IntelligentGitTreeMonitor.js +11 -0
- package/scripts/hooks-system/application/services/PlatformAnalysisService.js +19 -0
- package/scripts/hooks-system/application/services/PlatformDetectionService.js +19 -0
- package/scripts/hooks-system/application/services/PlaybookRunner.js +22 -1
- package/scripts/hooks-system/application/services/PredictiveHookAdvisor.js +19 -0
- package/scripts/hooks-system/application/services/RealtimeGuardPlugin.js +25 -0
- package/scripts/hooks-system/application/services/RealtimeGuardService.js +41 -84
- package/scripts/hooks-system/application/services/SmartDirtyTreeAnalyzer.js +11 -0
- package/scripts/hooks-system/application/services/commit/CommitMessageGenerator.js +11 -0
- package/scripts/hooks-system/application/services/commit/FeatureDetector.js +11 -0
- package/scripts/hooks-system/application/services/evidence/EvidenceContextManager.js +25 -0
- package/scripts/hooks-system/application/services/guard/GuardAutoManagerService.js +21 -31
- package/scripts/hooks-system/application/services/guard/GuardConfig.js +18 -15
- package/scripts/hooks-system/application/services/guard/GuardEventLogger.js +11 -0
- package/scripts/hooks-system/application/services/guard/GuardHealthReminder.js +26 -0
- package/scripts/hooks-system/application/services/guard/GuardHeartbeatMonitor.js +20 -6
- package/scripts/hooks-system/application/services/guard/GuardLockManager.js +11 -0
- package/scripts/hooks-system/application/services/guard/GuardMonitorLoop.js +25 -0
- package/scripts/hooks-system/application/services/guard/GuardNotificationHandler.js +11 -0
- package/scripts/hooks-system/application/services/guard/GuardProcessManager.js +10 -28
- package/scripts/hooks-system/application/services/guard/GuardRecoveryService.js +11 -0
- package/scripts/hooks-system/application/services/installation/ConfigurationGeneratorService.js +18 -0
- package/scripts/hooks-system/application/services/installation/FileSystemInstallerService.js +18 -0
- package/scripts/hooks-system/application/services/installation/GitEnvironmentService.js +18 -3
- package/scripts/hooks-system/application/services/installation/HookInstaller.js +19 -0
- package/scripts/hooks-system/application/services/installation/IdeIntegrationService.js +11 -0
- package/scripts/hooks-system/application/services/installation/InstallService.js +25 -1
- package/scripts/hooks-system/application/services/installation/McpConfigurator.js +19 -2
- package/scripts/hooks-system/application/services/installation/PlatformDetectorService.js +11 -0
- package/scripts/hooks-system/application/services/installation/VSCodeTaskConfigurator.js +11 -0
- package/scripts/hooks-system/application/services/logging/AuditLogger.js +90 -1
- package/scripts/hooks-system/application/services/logging/UnifiedLogger.js +15 -13
- package/scripts/hooks-system/application/services/monitoring/ActivityMonitor.js +33 -0
- package/scripts/hooks-system/application/services/monitoring/AstMonitor.js +27 -0
- package/scripts/hooks-system/application/services/monitoring/DevDocsMonitor.js +26 -0
- package/scripts/hooks-system/application/services/monitoring/EvidenceMonitor.js +19 -0
- package/scripts/hooks-system/application/services/monitoring/EvidenceMonitorService.js +27 -6
- package/scripts/hooks-system/application/services/monitoring/GitTreeMonitor.js +28 -0
- package/scripts/hooks-system/application/services/monitoring/GitTreeMonitorService.js +26 -0
- package/scripts/hooks-system/application/services/monitoring/HealthCheckProviders.js +4 -0
- package/scripts/hooks-system/application/services/monitoring/HealthCheckService.js +25 -0
- package/scripts/hooks-system/application/services/monitoring/HeartbeatMonitorService.js +26 -0
- package/scripts/hooks-system/application/services/monitoring/TokenMonitor.js +26 -0
- package/scripts/hooks-system/application/services/notification/MacNotificationSender.js +11 -0
- package/scripts/hooks-system/application/services/notification/NotificationCenterService.js +18 -0
- package/scripts/hooks-system/application/services/notification/NotificationDispatcher.js +11 -0
- package/scripts/hooks-system/application/services/notification/components/NotificationCooldownManager.js +18 -0
- package/scripts/hooks-system/application/services/notification/components/NotificationDeduplicator.js +18 -0
- package/scripts/hooks-system/application/services/notification/components/NotificationQueue.js +11 -0
- package/scripts/hooks-system/application/services/notification/components/NotificationRetryExecutor.js +20 -0
- package/scripts/hooks-system/application/services/platform/PlatformHeuristics.js +19 -0
- package/scripts/hooks-system/application/services/recovery/AutoRecoveryManager.js +19 -0
- package/scripts/hooks-system/application/services/smart-commit/CommitMessageSuggester.js +11 -0
- package/scripts/hooks-system/application/services/smart-commit/FileContextGrouper.js +19 -0
- package/scripts/hooks-system/application/services/smart-commit/SmartCommitSummaryBuilder.js +4 -0
- package/scripts/hooks-system/application/services/token/CursorTokenService.js +20 -0
- package/scripts/hooks-system/application/services/token/TokenMetricsService.js +11 -13
- package/scripts/hooks-system/application/services/token/TokenMonitorService.js +19 -0
- package/scripts/hooks-system/application/services/token/TokenStatusReporter.js +12 -0
- package/scripts/hooks-system/bin/__tests__/evidence-update.spec.js +49 -0
- package/scripts/hooks-system/bin/cli.js +1 -15
- package/scripts/hooks-system/config/project.config.json +1 -1
- package/scripts/hooks-system/domain/events/index.js +24 -31
- package/scripts/hooks-system/domain/exceptions/index.js +87 -0
- package/scripts/hooks-system/infrastructure/ast/android/analyzers/AndroidAnalysisOrchestrator.js +2 -3
- package/scripts/hooks-system/infrastructure/ast/ast-core.js +20 -12
- package/scripts/hooks-system/infrastructure/ast/ast-intelligence.js +18 -8
- package/scripts/hooks-system/infrastructure/ast/backend/analyzers/BackendPatternDetector.js +1 -2
- package/scripts/hooks-system/infrastructure/ast/backend/ast-backend.js +14 -18
- package/scripts/hooks-system/infrastructure/ast/frontend/ast-frontend.js +196 -196
- package/scripts/hooks-system/infrastructure/ast/ios/analyzers/__tests__/iOSASTIntelligentAnalyzer.spec.js +66 -0
- package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSASTIntelligentAnalyzer.js +2 -3
- package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSArchitectureRules.js +24 -86
- package/scripts/hooks-system/infrastructure/config/config.js +5 -0
- package/scripts/hooks-system/infrastructure/hooks/skill-activation-prompt.js +2 -3
- package/scripts/hooks-system/infrastructure/logging/UnifiedLoggerFactory.js +5 -35
- package/scripts/hooks-system/infrastructure/orchestration/intelligent-audit.js +16 -86
- package/scripts/hooks-system/infrastructure/shell/orchestrators/audit-orchestrator.sh +54 -92
- package/scripts/hooks-system/infrastructure/telemetry/metric-scope.js +98 -0
- package/scripts/hooks-system/infrastructure/telemetry/metrics-server.js +2 -51
- 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
|
-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
|
|
7
|
-
|
|
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.
|
|
33
|
-
autoRefreshCooldownMs = env.
|
|
34
|
-
staleThresholdMs = env.
|
|
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() {
|