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,22 @@
|
|
|
1
1
|
const { execSync, spawnSync } = require('child_process');
|
|
2
2
|
const { ConfigurationError } = require('../../domain/errors');
|
|
3
3
|
|
|
4
|
+
const { recordMetric } = require('../../../infrastructure/telemetry/metrics-logger');
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
createMetricScope: createMetricScope
|
|
8
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
9
|
+
|
|
4
10
|
class GitFlowService {
|
|
5
11
|
constructor(repoRoot, options = {}, logger = console, gitQuery = null, gitCommand = null, githubAdapter = null) {
|
|
12
|
+
recordMetric({
|
|
13
|
+
hook: 'git_flow_service',
|
|
14
|
+
operation: 'constructor',
|
|
15
|
+
status: 'started',
|
|
16
|
+
repoRoot: repoRoot.substring(0, 100),
|
|
17
|
+
hasOptions: !!options
|
|
18
|
+
});
|
|
19
|
+
|
|
6
20
|
this.repoRoot = repoRoot;
|
|
7
21
|
this.logger = logger;
|
|
8
22
|
this.gitQuery = gitQuery;
|
|
@@ -16,6 +30,16 @@ class GitFlowService {
|
|
|
16
30
|
this.requireClean = options.requireClean !== false;
|
|
17
31
|
|
|
18
32
|
this._validateDependencies();
|
|
33
|
+
|
|
34
|
+
recordMetric({
|
|
35
|
+
hook: 'git_flow_service',
|
|
36
|
+
operation: 'constructor',
|
|
37
|
+
status: 'success',
|
|
38
|
+
developBranch: this.developBranch,
|
|
39
|
+
mainBranch: this.mainBranch,
|
|
40
|
+
autoSyncEnabled: this.autoSyncEnabled,
|
|
41
|
+
autoCleanEnabled: this.autoCleanEnabled
|
|
42
|
+
});
|
|
19
43
|
}
|
|
20
44
|
|
|
21
45
|
_validateDependencies() {
|
|
@@ -25,9 +49,17 @@ class GitFlowService {
|
|
|
25
49
|
}
|
|
26
50
|
|
|
27
51
|
getCurrentBranch() {
|
|
52
|
+
const m_get_current_branch = createMetricScope({
|
|
53
|
+
hook: 'git_flow_service',
|
|
54
|
+
operation: 'get_current_branch'
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
m_get_current_branch.started();
|
|
28
58
|
if (this.gitQuery) {
|
|
59
|
+
m_get_current_branch.success();
|
|
29
60
|
return this.gitQuery.getCurrentBranch();
|
|
30
61
|
}
|
|
62
|
+
m_get_current_branch.success();
|
|
31
63
|
return 'unknown';
|
|
32
64
|
}
|
|
33
65
|
|
|
@@ -40,12 +72,31 @@ class GitFlowService {
|
|
|
40
72
|
}
|
|
41
73
|
|
|
42
74
|
syncBranches() {
|
|
75
|
+
recordMetric({
|
|
76
|
+
hook: 'git_flow_service',
|
|
77
|
+
operation: 'sync_branches',
|
|
78
|
+
status: 'started',
|
|
79
|
+
autoSyncEnabled: this.autoSyncEnabled
|
|
80
|
+
});
|
|
81
|
+
|
|
43
82
|
if (!this.autoSyncEnabled) {
|
|
83
|
+
recordMetric({
|
|
84
|
+
hook: 'git_flow_service',
|
|
85
|
+
operation: 'sync_branches',
|
|
86
|
+
status: 'skipped',
|
|
87
|
+
reason: 'auto_sync_disabled'
|
|
88
|
+
});
|
|
44
89
|
return { success: false, message: 'Auto-sync disabled' };
|
|
45
90
|
}
|
|
46
91
|
|
|
47
92
|
if (!this.isClean()) {
|
|
48
93
|
this.logger.warn('Skipping sync: working directory not clean');
|
|
94
|
+
recordMetric({
|
|
95
|
+
hook: 'git_flow_service',
|
|
96
|
+
operation: 'sync_branches',
|
|
97
|
+
status: 'skipped',
|
|
98
|
+
reason: 'working_directory_not_clean'
|
|
99
|
+
});
|
|
49
100
|
return { success: false, message: 'Working directory not clean' };
|
|
50
101
|
}
|
|
51
102
|
|
|
@@ -64,22 +115,47 @@ class GitFlowService {
|
|
|
64
115
|
|
|
65
116
|
this.gitCommand.checkout(current);
|
|
66
117
|
} else {
|
|
118
|
+
recordMetric({
|
|
119
|
+
hook: 'git_flow_service',
|
|
120
|
+
operation: 'sync_branches',
|
|
121
|
+
status: 'failed',
|
|
122
|
+
reason: 'no_git_command_adapter'
|
|
123
|
+
});
|
|
67
124
|
throw new ConfigurationError('GitCommandAdapter is required for branch synchronization', 'gitCommand');
|
|
68
125
|
}
|
|
69
126
|
|
|
70
127
|
this.logger.info('Branches synchronized successfully', {
|
|
71
128
|
branches: [this.developBranch, this.mainBranch]
|
|
72
129
|
});
|
|
130
|
+
recordMetric({
|
|
131
|
+
hook: 'git_flow_service',
|
|
132
|
+
operation: 'sync_branches',
|
|
133
|
+
status: 'success',
|
|
134
|
+
branches: [this.developBranch, this.mainBranch].join(',')
|
|
135
|
+
});
|
|
73
136
|
return { success: true, message: 'Branches synchronized' };
|
|
74
137
|
} catch (error) {
|
|
75
138
|
this.logger.error('Branch synchronization failed', { error: error.message });
|
|
139
|
+
recordMetric({
|
|
140
|
+
hook: 'git_flow_service',
|
|
141
|
+
operation: 'sync_branches',
|
|
142
|
+
status: 'failed',
|
|
143
|
+
error: error.message.substring(0, 100)
|
|
144
|
+
});
|
|
76
145
|
return { success: false, message: error.message };
|
|
77
146
|
}
|
|
78
147
|
}
|
|
79
148
|
|
|
80
149
|
createPullRequest(sourceBranch, targetBranch, title, body) {
|
|
150
|
+
const m_create_pull_request = createMetricScope({
|
|
151
|
+
hook: 'git_flow_service',
|
|
152
|
+
operation: 'create_pull_request'
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
m_create_pull_request.started();
|
|
81
156
|
if (!this.github) {
|
|
82
157
|
this.logger.error('GitHub adapter not available');
|
|
158
|
+
m_create_pull_request.success();
|
|
83
159
|
return null;
|
|
84
160
|
}
|
|
85
161
|
|
|
@@ -94,11 +170,15 @@ class GitFlowService {
|
|
|
94
170
|
this.logger.warn('Pull Request creation failed or returned no URL');
|
|
95
171
|
}
|
|
96
172
|
|
|
173
|
+
m_create_pull_request.success();
|
|
174
|
+
|
|
97
175
|
return prUrl;
|
|
98
176
|
} catch (error) {
|
|
99
177
|
this.logger.error('[GitFlowService] Failed to create PR:', { error: error.message });
|
|
178
|
+
m_create_pull_request.success();
|
|
100
179
|
return null;
|
|
101
180
|
}
|
|
181
|
+
m_create_pull_request.success();
|
|
102
182
|
}
|
|
103
183
|
|
|
104
184
|
mergeDevelopToMain() {
|
|
@@ -1,16 +1,57 @@
|
|
|
1
1
|
const { execSync } = require('child_process');
|
|
2
2
|
|
|
3
|
+
// Import recordMetric for prometheus metrics
|
|
4
|
+
const { recordMetric } = require('../../../infrastructure/telemetry/metrics-logger');
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
createMetricScope: createMetricScope
|
|
8
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
9
|
+
|
|
3
10
|
const extractFilePath = line => {
|
|
11
|
+
recordMetric({
|
|
12
|
+
hook: 'git_tree_state',
|
|
13
|
+
operation: 'extract_file_path',
|
|
14
|
+
status: 'started',
|
|
15
|
+
lineLength: line ? line.length : 0
|
|
16
|
+
});
|
|
17
|
+
|
|
4
18
|
if (!line) {
|
|
19
|
+
recordMetric({
|
|
20
|
+
hook: 'git_tree_state',
|
|
21
|
+
operation: 'extract_file_path',
|
|
22
|
+
status: 'success',
|
|
23
|
+
result: ''
|
|
24
|
+
});
|
|
5
25
|
return '';
|
|
6
26
|
}
|
|
7
27
|
if (line.startsWith('??')) {
|
|
8
|
-
|
|
28
|
+
const result = line.slice(3).trim();
|
|
29
|
+
recordMetric({
|
|
30
|
+
hook: 'git_tree_state',
|
|
31
|
+
operation: 'extract_file_path',
|
|
32
|
+
status: 'success',
|
|
33
|
+
resultLength: result.length
|
|
34
|
+
});
|
|
35
|
+
return result;
|
|
9
36
|
}
|
|
10
|
-
|
|
37
|
+
const result = line.length > 3 ? line.slice(3).trim() : line.trim();
|
|
38
|
+
recordMetric({
|
|
39
|
+
hook: 'git_tree_state',
|
|
40
|
+
operation: 'extract_file_path',
|
|
41
|
+
status: 'success',
|
|
42
|
+
resultLength: result.length
|
|
43
|
+
});
|
|
44
|
+
return result;
|
|
11
45
|
};
|
|
12
46
|
|
|
13
47
|
const buildStateFromStatus = (statusOutput = '') => {
|
|
48
|
+
recordMetric({
|
|
49
|
+
hook: 'git_tree_state',
|
|
50
|
+
operation: 'build_state_from_status',
|
|
51
|
+
status: 'started',
|
|
52
|
+
statusOutputLength: statusOutput ? statusOutput.length : 0
|
|
53
|
+
});
|
|
54
|
+
|
|
14
55
|
const lines = statusOutput
|
|
15
56
|
.split('\n')
|
|
16
57
|
.map(entry => entry.replace(/\r$/, ''))
|
|
@@ -44,24 +85,51 @@ const buildStateFromStatus = (statusOutput = '') => {
|
|
|
44
85
|
|
|
45
86
|
const uniqueSet = new Set([...stagedSet, ...workingSet]);
|
|
46
87
|
|
|
47
|
-
|
|
88
|
+
const result = {
|
|
48
89
|
stagedFiles: Array.from(stagedSet),
|
|
49
90
|
workingFiles: Array.from(workingSet),
|
|
50
91
|
stagedCount: stagedSet.size,
|
|
51
92
|
workingCount: workingSet.size,
|
|
52
93
|
uniqueCount: uniqueSet.size
|
|
53
94
|
};
|
|
95
|
+
|
|
96
|
+
recordMetric({
|
|
97
|
+
hook: 'git_tree_state',
|
|
98
|
+
operation: 'build_state_from_status',
|
|
99
|
+
status: 'success',
|
|
100
|
+
stagedCount: stagedSet.size,
|
|
101
|
+
workingCount: workingSet.size,
|
|
102
|
+
uniqueCount: uniqueSet.size
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return result;
|
|
54
106
|
};
|
|
55
107
|
|
|
56
108
|
const getGitTreeState = ({ repoRoot = process.cwd() } = {}) => {
|
|
109
|
+
recordMetric({
|
|
110
|
+
hook: 'git_tree_state',
|
|
111
|
+
operation: 'get_git_tree_state',
|
|
112
|
+
status: 'started',
|
|
113
|
+
repoRoot: repoRoot.substring(0, 100)
|
|
114
|
+
});
|
|
115
|
+
|
|
57
116
|
try {
|
|
58
117
|
const statusOutput = execSync('git status --porcelain', {
|
|
59
118
|
cwd: repoRoot,
|
|
60
119
|
encoding: 'utf8'
|
|
61
120
|
});
|
|
62
|
-
|
|
121
|
+
const result = buildStateFromStatus(statusOutput);
|
|
122
|
+
recordMetric({
|
|
123
|
+
hook: 'git_tree_state',
|
|
124
|
+
operation: 'get_git_tree_state',
|
|
125
|
+
status: 'success',
|
|
126
|
+
stagedCount: result.stagedCount,
|
|
127
|
+
workingCount: result.workingCount,
|
|
128
|
+
uniqueCount: result.uniqueCount
|
|
129
|
+
});
|
|
130
|
+
return result;
|
|
63
131
|
} catch (error) {
|
|
64
|
-
|
|
132
|
+
const result = {
|
|
65
133
|
stagedFiles: [],
|
|
66
134
|
workingFiles: [],
|
|
67
135
|
stagedCount: 0,
|
|
@@ -69,37 +137,92 @@ const getGitTreeState = ({ repoRoot = process.cwd() } = {}) => {
|
|
|
69
137
|
uniqueCount: 0,
|
|
70
138
|
error: error.message
|
|
71
139
|
};
|
|
140
|
+
recordMetric({
|
|
141
|
+
hook: 'git_tree_state',
|
|
142
|
+
operation: 'get_git_tree_state',
|
|
143
|
+
status: 'failed',
|
|
144
|
+
error: error.message
|
|
145
|
+
});
|
|
146
|
+
return result;
|
|
72
147
|
}
|
|
73
148
|
};
|
|
74
149
|
|
|
75
150
|
const isTreeBeyondLimit = (state, limits) => {
|
|
151
|
+
recordMetric({
|
|
152
|
+
hook: 'git_tree_state',
|
|
153
|
+
operation: 'is_tree_beyond_limit',
|
|
154
|
+
status: 'started',
|
|
155
|
+
hasState: !!state,
|
|
156
|
+
limitsType: typeof limits
|
|
157
|
+
});
|
|
158
|
+
|
|
76
159
|
if (!state) {
|
|
160
|
+
recordMetric({
|
|
161
|
+
hook: 'git_tree_state',
|
|
162
|
+
operation: 'is_tree_beyond_limit',
|
|
163
|
+
status: 'success',
|
|
164
|
+
result: false
|
|
165
|
+
});
|
|
77
166
|
return false;
|
|
78
167
|
}
|
|
79
|
-
|
|
168
|
+
|
|
80
169
|
if (typeof limits === 'number') {
|
|
81
170
|
const limit = limits;
|
|
82
171
|
if (!Number.isFinite(limit) || limit <= 0) {
|
|
172
|
+
recordMetric({
|
|
173
|
+
hook: 'git_tree_state',
|
|
174
|
+
operation: 'is_tree_beyond_limit',
|
|
175
|
+
status: 'success',
|
|
176
|
+
result: false
|
|
177
|
+
});
|
|
83
178
|
return false;
|
|
84
179
|
}
|
|
85
|
-
|
|
180
|
+
const result = (
|
|
86
181
|
state.stagedCount > limit ||
|
|
87
182
|
state.workingCount > limit ||
|
|
88
183
|
state.uniqueCount > limit
|
|
89
184
|
);
|
|
185
|
+
recordMetric({
|
|
186
|
+
hook: 'git_tree_state',
|
|
187
|
+
operation: 'is_tree_beyond_limit',
|
|
188
|
+
status: 'success',
|
|
189
|
+
result: result
|
|
190
|
+
});
|
|
191
|
+
return result;
|
|
90
192
|
}
|
|
91
|
-
|
|
193
|
+
|
|
92
194
|
const { stagedLimit = 10, unstagedLimit = 15, totalLimit = 20 } = limits || {};
|
|
93
|
-
|
|
195
|
+
|
|
94
196
|
const stagedExceeded = Number.isFinite(stagedLimit) && stagedLimit > 0 && state.stagedCount > stagedLimit;
|
|
95
197
|
const unstagedExceeded = Number.isFinite(unstagedLimit) && unstagedLimit > 0 && state.workingCount > unstagedLimit;
|
|
96
198
|
const totalExceeded = Number.isFinite(totalLimit) && totalLimit > 0 && state.uniqueCount > totalLimit;
|
|
97
|
-
|
|
98
|
-
|
|
199
|
+
|
|
200
|
+
const result = stagedExceeded || unstagedExceeded || totalExceeded;
|
|
201
|
+
recordMetric({
|
|
202
|
+
hook: 'git_tree_state',
|
|
203
|
+
operation: 'is_tree_beyond_limit',
|
|
204
|
+
status: 'success',
|
|
205
|
+
result: result
|
|
206
|
+
});
|
|
207
|
+
return result;
|
|
99
208
|
};
|
|
100
209
|
|
|
101
210
|
const summarizeTreeState = (state, limits) => {
|
|
211
|
+
recordMetric({
|
|
212
|
+
hook: 'git_tree_state',
|
|
213
|
+
operation: 'summarize_tree_state',
|
|
214
|
+
status: 'started',
|
|
215
|
+
hasState: !!state,
|
|
216
|
+
limitsType: typeof limits
|
|
217
|
+
});
|
|
218
|
+
|
|
102
219
|
if (!state) {
|
|
220
|
+
recordMetric({
|
|
221
|
+
hook: 'git_tree_state',
|
|
222
|
+
operation: 'summarize_tree_state',
|
|
223
|
+
status: 'success',
|
|
224
|
+
result: 'no data'
|
|
225
|
+
});
|
|
103
226
|
return 'no data';
|
|
104
227
|
}
|
|
105
228
|
const parts = [
|
|
@@ -107,7 +230,7 @@ const summarizeTreeState = (state, limits) => {
|
|
|
107
230
|
`working ${state.workingCount}`,
|
|
108
231
|
`unique ${state.uniqueCount}`
|
|
109
232
|
];
|
|
110
|
-
|
|
233
|
+
|
|
111
234
|
if (typeof limits === 'number') {
|
|
112
235
|
const limit = limits;
|
|
113
236
|
if (Number.isFinite(limit) && limit > 0) {
|
|
@@ -129,7 +252,14 @@ const summarizeTreeState = (state, limits) => {
|
|
|
129
252
|
parts.push(`(${limitParts.join(', ')})`);
|
|
130
253
|
}
|
|
131
254
|
}
|
|
132
|
-
|
|
255
|
+
const result = parts.join(', ');
|
|
256
|
+
recordMetric({
|
|
257
|
+
hook: 'git_tree_state',
|
|
258
|
+
operation: 'summarize_tree_state',
|
|
259
|
+
status: 'success',
|
|
260
|
+
resultLength: result.length
|
|
261
|
+
});
|
|
262
|
+
return result;
|
|
133
263
|
};
|
|
134
264
|
|
|
135
265
|
module.exports = {
|
|
@@ -1,25 +1,72 @@
|
|
|
1
1
|
const { recordMetric } = require('../../infrastructure/telemetry/metrics-logger');
|
|
2
2
|
const HookSystemStateMachine = require('../state/HookSystemStateMachine');
|
|
3
3
|
|
|
4
|
+
const {
|
|
5
|
+
createMetricScope: createMetricScope
|
|
6
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
7
|
+
|
|
4
8
|
class HookSystemScheduler {
|
|
5
9
|
constructor({ orchestrator, contextEngine, intervalMs = 30000 }) {
|
|
10
|
+
recordMetric({
|
|
11
|
+
hook: 'hook_system_scheduler',
|
|
12
|
+
operation: 'constructor',
|
|
13
|
+
status: 'started',
|
|
14
|
+
intervalMs
|
|
15
|
+
});
|
|
16
|
+
|
|
6
17
|
this.orchestrator = orchestrator;
|
|
7
18
|
this.contextEngine = contextEngine;
|
|
8
19
|
this.intervalMs = intervalMs;
|
|
9
20
|
this.stateMachine = new HookSystemStateMachine();
|
|
10
21
|
this.timer = null;
|
|
22
|
+
|
|
23
|
+
recordMetric({
|
|
24
|
+
hook: 'hook_system_scheduler',
|
|
25
|
+
operation: 'constructor',
|
|
26
|
+
status: 'success',
|
|
27
|
+
intervalMs
|
|
28
|
+
});
|
|
11
29
|
}
|
|
12
30
|
|
|
13
31
|
start() {
|
|
32
|
+
recordMetric({
|
|
33
|
+
hook: 'hook_system_scheduler',
|
|
34
|
+
operation: 'start',
|
|
35
|
+
status: 'started',
|
|
36
|
+
intervalMs: this.intervalMs
|
|
37
|
+
});
|
|
38
|
+
|
|
14
39
|
if (this.timer) return;
|
|
40
|
+
|
|
15
41
|
this.timer = setInterval(() => this.tick(), this.intervalMs);
|
|
42
|
+
|
|
43
|
+
recordMetric({
|
|
44
|
+
hook: 'hook_system_scheduler',
|
|
45
|
+
operation: 'start',
|
|
46
|
+
status: 'success',
|
|
47
|
+
intervalMs: this.intervalMs
|
|
48
|
+
});
|
|
16
49
|
}
|
|
17
50
|
|
|
18
51
|
stop() {
|
|
52
|
+
recordMetric({
|
|
53
|
+
hook: 'hook_system_scheduler',
|
|
54
|
+
operation: 'stop',
|
|
55
|
+
status: 'started',
|
|
56
|
+
hadTimer: !!this.timer
|
|
57
|
+
});
|
|
58
|
+
|
|
19
59
|
if (this.timer) {
|
|
20
60
|
clearInterval(this.timer);
|
|
21
61
|
this.timer = null;
|
|
22
62
|
}
|
|
63
|
+
|
|
64
|
+
recordMetric({
|
|
65
|
+
hook: 'hook_system_scheduler',
|
|
66
|
+
operation: 'stop',
|
|
67
|
+
status: 'success',
|
|
68
|
+
hadTimer: !!this.timer
|
|
69
|
+
});
|
|
23
70
|
}
|
|
24
71
|
|
|
25
72
|
async tick() {
|
|
@@ -5,12 +5,23 @@ const FeatureDetector = require('./commit/FeatureDetector');
|
|
|
5
5
|
const CommitMessageGenerator = require('./commit/CommitMessageGenerator');
|
|
6
6
|
const UnifiedLogger = require('./logging/UnifiedLogger');
|
|
7
7
|
|
|
8
|
+
const {
|
|
9
|
+
createMetricScope: createMetricScope
|
|
10
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
11
|
+
|
|
8
12
|
class IntelligentCommitAnalyzer {
|
|
9
13
|
constructor({ repoRoot = process.cwd(), logger = null } = {}) {
|
|
14
|
+
const m_constructor = createMetricScope({
|
|
15
|
+
hook: 'intelligent_commit_analyzer',
|
|
16
|
+
operation: 'constructor'
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
m_constructor.started();
|
|
10
20
|
this.repoRoot = repoRoot;
|
|
11
21
|
this.logger = logger || console;
|
|
12
22
|
this.featureDetector = new FeatureDetector(this.logger);
|
|
13
23
|
this.messageGenerator = new CommitMessageGenerator(this.logger);
|
|
24
|
+
m_constructor.success();
|
|
14
25
|
}
|
|
15
26
|
|
|
16
27
|
detectFeature(filePath) {
|
|
@@ -137,6 +148,13 @@ class IntelligentCommitAnalyzer {
|
|
|
137
148
|
* Get ready-to-commit groups (all groups are ready - no verification)
|
|
138
149
|
*/
|
|
139
150
|
getReadyCommits(suggestions) {
|
|
151
|
+
const m_get_ready_commits = createMetricScope({
|
|
152
|
+
hook: 'intelligent_commit_analyzer',
|
|
153
|
+
operation: 'get_ready_commits'
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
m_get_ready_commits.started();
|
|
157
|
+
m_get_ready_commits.success();
|
|
140
158
|
return suggestions;
|
|
141
159
|
}
|
|
142
160
|
|
|
@@ -144,6 +162,13 @@ class IntelligentCommitAnalyzer {
|
|
|
144
162
|
* Get groups that need attention (none - we don't verify)
|
|
145
163
|
*/
|
|
146
164
|
getNeedsAttention(suggestions) {
|
|
165
|
+
const m_get_needs_attention = createMetricScope({
|
|
166
|
+
hook: 'intelligent_commit_analyzer',
|
|
167
|
+
operation: 'get_needs_attention'
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
m_get_needs_attention.started();
|
|
171
|
+
m_get_needs_attention.success();
|
|
147
172
|
return [];
|
|
148
173
|
}
|
|
149
174
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
const IntelligentCommitAnalyzer = require('./IntelligentCommitAnalyzer');
|
|
2
2
|
const { getGitTreeState } = require('./GitTreeState');
|
|
3
3
|
|
|
4
|
+
const {
|
|
5
|
+
createMetricScope: createMetricScope
|
|
6
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
7
|
+
|
|
4
8
|
class IntelligentGitTreeMonitor {
|
|
5
9
|
constructor({
|
|
6
10
|
repoRoot = process.cwd(),
|
|
@@ -8,11 +12,18 @@ class IntelligentGitTreeMonitor {
|
|
|
8
12
|
logger = console,
|
|
9
13
|
autoCommitEnabled = false
|
|
10
14
|
} = {}) {
|
|
15
|
+
const m_constructor = createMetricScope({
|
|
16
|
+
hook: 'intelligent_git_tree_monitor',
|
|
17
|
+
operation: 'constructor'
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
m_constructor.started();
|
|
11
21
|
this.repoRoot = repoRoot;
|
|
12
22
|
this.notifier = notifier;
|
|
13
23
|
this.logger = logger;
|
|
14
24
|
this.autoCommitEnabled = autoCommitEnabled;
|
|
15
25
|
this.analyzer = new IntelligentCommitAnalyzer({ repoRoot, logger });
|
|
26
|
+
m_constructor.success();
|
|
16
27
|
}
|
|
17
28
|
|
|
18
29
|
/**
|
|
@@ -2,10 +2,21 @@ const path = require('path');
|
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const PlatformHeuristics = require('./platform/PlatformHeuristics');
|
|
4
4
|
|
|
5
|
+
const {
|
|
6
|
+
createMetricScope: createMetricScope
|
|
7
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
8
|
+
|
|
5
9
|
class PlatformAnalysisService {
|
|
6
10
|
constructor(platformDetector) {
|
|
11
|
+
const m_constructor = createMetricScope({
|
|
12
|
+
hook: 'platform_analysis_service',
|
|
13
|
+
operation: 'constructor'
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
m_constructor.started();
|
|
7
17
|
this.platformDetector = platformDetector;
|
|
8
18
|
this.heuristics = new PlatformHeuristics(platformDetector);
|
|
19
|
+
m_constructor.success();
|
|
9
20
|
}
|
|
10
21
|
|
|
11
22
|
/**
|
|
@@ -130,6 +141,12 @@ class PlatformAnalysisService {
|
|
|
130
141
|
}
|
|
131
142
|
|
|
132
143
|
getScoreReasons(platform, context) {
|
|
144
|
+
const m_get_score_reasons = createMetricScope({
|
|
145
|
+
hook: 'platform_analysis_service',
|
|
146
|
+
operation: 'get_score_reasons'
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
m_get_score_reasons.started();
|
|
133
150
|
const reasons = [];
|
|
134
151
|
|
|
135
152
|
if (context.stagedFiles && context.stagedFiles.length > 0) {
|
|
@@ -166,6 +183,8 @@ class PlatformAnalysisService {
|
|
|
166
183
|
}
|
|
167
184
|
}
|
|
168
185
|
|
|
186
|
+
m_get_score_reasons.success();
|
|
187
|
+
|
|
169
188
|
return reasons;
|
|
170
189
|
}
|
|
171
190
|
}
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
|
|
2
|
+
const {
|
|
3
|
+
createMetricScope: createMetricScope
|
|
4
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
5
|
+
|
|
2
6
|
const fs = require('fs').promises;
|
|
3
7
|
const path = require('path');
|
|
4
8
|
|
|
5
9
|
class PlatformDetectionService {
|
|
6
10
|
constructor() {
|
|
11
|
+
const m_constructor = createMetricScope({
|
|
12
|
+
hook: 'platform_detection_service',
|
|
13
|
+
operation: 'constructor'
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
m_constructor.started();
|
|
7
17
|
this.cache = {
|
|
8
18
|
detections: new Map(),
|
|
9
19
|
timestamp: 0,
|
|
@@ -43,6 +53,7 @@ class PlatformDetectionService {
|
|
|
43
53
|
'*.java',
|
|
44
54
|
],
|
|
45
55
|
};
|
|
56
|
+
m_constructor.success();
|
|
46
57
|
}
|
|
47
58
|
|
|
48
59
|
async detectPlatforms(targetPath) {
|
|
@@ -142,6 +153,12 @@ class PlatformDetectionService {
|
|
|
142
153
|
}
|
|
143
154
|
|
|
144
155
|
getAmbiguityScore(filePath) {
|
|
156
|
+
const m_get_ambiguity_score = createMetricScope({
|
|
157
|
+
hook: 'platform_detection_service',
|
|
158
|
+
operation: 'get_ambiguity_score'
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
m_get_ambiguity_score.started();
|
|
145
162
|
const platform = this._detectPlatformUncached(filePath);
|
|
146
163
|
const lowerPath = filePath.toLowerCase();
|
|
147
164
|
const ext = path.extname(filePath);
|
|
@@ -156,6 +173,8 @@ class PlatformDetectionService {
|
|
|
156
173
|
if (ext === '.ts' || ext === '.tsx') return 60;
|
|
157
174
|
if (ext === '.js' || ext === '.jsx') return 70;
|
|
158
175
|
|
|
176
|
+
m_get_ambiguity_score.success();
|
|
177
|
+
|
|
159
178
|
return 100;
|
|
160
179
|
}
|
|
161
180
|
|
|
@@ -2,13 +2,27 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { spawnSync } = require('child_process');
|
|
4
4
|
const { DomainError, NotFoundError } = require('../../domain/errors');
|
|
5
|
+
const { NotFoundException } = require('../domain/exceptions');
|
|
6
|
+
|
|
7
|
+
const { recordMetric } = require('../../../infrastructure/telemetry/metrics-logger');
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
createMetricScope: createMetricScope
|
|
11
|
+
} = require('../../../infrastructure/telemetry/metric-scope');
|
|
5
12
|
|
|
6
13
|
const PLAYBOOKS_PATH = path.join(process.cwd(), 'scripts', 'hooks-system', 'config', 'playbooks.json');
|
|
7
14
|
|
|
8
15
|
class PlaybookRunner {
|
|
9
16
|
constructor(options = {}) {
|
|
17
|
+
const m_constructor = createMetricScope({
|
|
18
|
+
hook: 'playbook_runner',
|
|
19
|
+
operation: 'constructor'
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
m_constructor.started();
|
|
10
23
|
this.cwd = options.cwd || process.cwd();
|
|
11
24
|
this.playbooks = JSON.parse(fs.readFileSync(PLAYBOOKS_PATH, 'utf8'));
|
|
25
|
+
m_constructor.success();
|
|
12
26
|
}
|
|
13
27
|
|
|
14
28
|
list() {
|
|
@@ -16,9 +30,15 @@ class PlaybookRunner {
|
|
|
16
30
|
}
|
|
17
31
|
|
|
18
32
|
run(id) {
|
|
33
|
+
const m_run = createMetricScope({
|
|
34
|
+
hook: 'playbook_runner',
|
|
35
|
+
operation: 'run'
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
m_run.started();
|
|
19
39
|
const playbook = this.playbooks[id];
|
|
20
40
|
if (!playbook) {
|
|
21
|
-
throw new
|
|
41
|
+
throw new NotFoundException('Playbook', { id });
|
|
22
42
|
}
|
|
23
43
|
|
|
24
44
|
for (const step of playbook.steps) {
|
|
@@ -33,6 +53,7 @@ class PlaybookRunner {
|
|
|
33
53
|
}
|
|
34
54
|
}
|
|
35
55
|
}
|
|
56
|
+
m_run.success();
|
|
36
57
|
}
|
|
37
58
|
}
|
|
38
59
|
|