pumuki-ast-hooks 5.4.5 → 5.4.7

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 (166) hide show
  1. package/package.json +2 -2
  2. package/scripts/hooks-system/application/services/AutonomousOrchestrator.js +2 -0
  3. package/scripts/hooks-system/application/services/ContextDetectionEngine.js +2 -0
  4. package/scripts/hooks-system/application/services/DynamicRulesLoader.js +3 -1
  5. package/scripts/hooks-system/application/services/GitFlowService.js +2 -0
  6. package/scripts/hooks-system/application/services/GitTreeState.js +1 -0
  7. package/scripts/hooks-system/application/services/HookSystemScheduler.js +2 -0
  8. package/scripts/hooks-system/application/services/IntelligentCommitAnalyzer.js +4 -1
  9. package/scripts/hooks-system/application/services/IntelligentGitTreeMonitor.js +2 -0
  10. package/scripts/hooks-system/application/services/PlatformAnalysisService.js +2 -0
  11. package/scripts/hooks-system/application/services/PlatformDetectionService.js +3 -1
  12. package/scripts/hooks-system/application/services/PlaybookRunner.js +3 -0
  13. package/scripts/hooks-system/application/services/PredictiveHookAdvisor.js +2 -0
  14. package/scripts/hooks-system/application/services/RealtimeGuardPlugin.js +2 -0
  15. package/scripts/hooks-system/application/services/SmartDirtyTreeAnalyzer.js +2 -0
  16. package/scripts/hooks-system/application/services/commit/CommitMessageGenerator.js +3 -1
  17. package/scripts/hooks-system/application/services/commit/FeatureDetector.js +5 -1
  18. package/scripts/hooks-system/application/services/evidence/EvidenceContextManager.js +2 -0
  19. package/scripts/hooks-system/application/services/guard/GuardAutoManagerService.js +1 -0
  20. package/scripts/hooks-system/application/services/guard/GuardConfig.js +3 -1
  21. package/scripts/hooks-system/application/services/guard/GuardEventLogger.js +2 -0
  22. package/scripts/hooks-system/application/services/guard/GuardHealthReminder.js +5 -1
  23. package/scripts/hooks-system/application/services/guard/GuardHeartbeatMonitor.js +2 -0
  24. package/scripts/hooks-system/application/services/guard/GuardLockManager.js +2 -0
  25. package/scripts/hooks-system/application/services/guard/GuardMonitorLoop.js +3 -1
  26. package/scripts/hooks-system/application/services/guard/GuardNotificationHandler.js +4 -0
  27. package/scripts/hooks-system/application/services/guard/GuardNotifier.js +3 -1
  28. package/scripts/hooks-system/application/services/guard/GuardProcessManager.js +2 -0
  29. package/scripts/hooks-system/application/services/guard/GuardRecoveryService.js +3 -0
  30. package/scripts/hooks-system/application/services/installation/ConfigurationGeneratorService.js +4 -0
  31. package/scripts/hooks-system/application/services/installation/FileSystemInstallerService.js +3 -0
  32. package/scripts/hooks-system/application/services/installation/GitEnvironmentService.js +3 -0
  33. package/scripts/hooks-system/application/services/installation/HookInstaller.js +4 -0
  34. package/scripts/hooks-system/application/services/installation/IdeIntegrationService.js +3 -0
  35. package/scripts/hooks-system/application/services/installation/InstallService.js +3 -0
  36. package/scripts/hooks-system/application/services/installation/McpConfigurator.js +1 -0
  37. package/scripts/hooks-system/application/services/installation/PlatformDetectorService.js +4 -0
  38. package/scripts/hooks-system/application/services/installation/VSCodeTaskConfigurator.js +4 -0
  39. package/scripts/hooks-system/application/services/logging/UnifiedLogger.js +2 -0
  40. package/scripts/hooks-system/application/services/monitoring/ActivityMonitor.js +2 -0
  41. package/scripts/hooks-system/application/services/monitoring/AstMonitor.js +2 -0
  42. package/scripts/hooks-system/application/services/monitoring/DevDocsMonitor.js +2 -0
  43. package/scripts/hooks-system/application/services/monitoring/EvidenceMonitor.js +2 -0
  44. package/scripts/hooks-system/application/services/monitoring/EvidenceMonitorService.js +1 -0
  45. package/scripts/hooks-system/application/services/monitoring/GitTreeMonitor.js +2 -0
  46. package/scripts/hooks-system/application/services/monitoring/GitTreeMonitorService.js +3 -0
  47. package/scripts/hooks-system/application/services/monitoring/HealthCheckService.js +2 -0
  48. package/scripts/hooks-system/application/services/monitoring/HeartbeatMonitorService.js +2 -0
  49. package/scripts/hooks-system/application/services/monitoring/TokenMonitor.js +2 -0
  50. package/scripts/hooks-system/application/services/notification/MacNotificationSender.js +2 -0
  51. package/scripts/hooks-system/application/services/notification/NotificationCenterService.js +2 -0
  52. package/scripts/hooks-system/application/services/notification/NotificationDispatcher.js +3 -0
  53. package/scripts/hooks-system/application/services/notification/components/NotificationCooldownManager.js +3 -0
  54. package/scripts/hooks-system/application/services/notification/components/NotificationDeduplicator.js +2 -0
  55. package/scripts/hooks-system/application/services/notification/components/NotificationQueue.js +3 -0
  56. package/scripts/hooks-system/application/services/notification/components/NotificationRetryExecutor.js +4 -0
  57. package/scripts/hooks-system/application/services/platform/PlatformHeuristics.js +2 -0
  58. package/scripts/hooks-system/application/services/recovery/AutoRecoveryManager.js +2 -0
  59. package/scripts/hooks-system/application/services/smart-commit/CommitMessageSuggester.js +4 -0
  60. package/scripts/hooks-system/application/services/smart-commit/FileContextGrouper.js +2 -0
  61. package/scripts/hooks-system/application/services/smart-commit/SmartCommitSummaryBuilder.js +6 -0
  62. package/scripts/hooks-system/application/services/token/CursorTokenService.js +3 -0
  63. package/scripts/hooks-system/application/services/token/TokenMetricsService.js +4 -0
  64. package/scripts/hooks-system/application/services/token/TokenMonitorService.js +1 -0
  65. package/scripts/hooks-system/application/services/token/TokenStatusReporter.js +2 -0
  66. package/scripts/hooks-system/application/state/HookSystemStateMachine.js +2 -0
  67. package/scripts/hooks-system/application/use-cases/AnalyzeCodebaseUseCase.js +2 -0
  68. package/scripts/hooks-system/application/use-cases/AnalyzeStagedFilesUseCase.js +2 -0
  69. package/scripts/hooks-system/application/use-cases/AutoExecuteAIStartUseCase.js +2 -0
  70. package/scripts/hooks-system/application/use-cases/BlockCommitUseCase.js +2 -0
  71. package/scripts/hooks-system/application/use-cases/GenerateAuditReportUseCase.js +3 -0
  72. package/scripts/hooks-system/bin/audit-library.js +5 -4
  73. package/scripts/hooks-system/bin/auto-fix-violations.js +1 -0
  74. package/scripts/hooks-system/bin/auto-restart-guards.js +3 -2
  75. package/scripts/hooks-system/bin/check-doc-drift.js +1 -0
  76. package/scripts/hooks-system/bin/check-version.js +26 -25
  77. package/scripts/hooks-system/bin/cli.js +1 -0
  78. package/scripts/hooks-system/bin/guard-auto-manager.js +1 -0
  79. package/scripts/hooks-system/bin/guard-supervisor.js +1 -0
  80. package/scripts/hooks-system/bin/hook-status.js +1 -0
  81. package/scripts/hooks-system/bin/install.js +1 -0
  82. package/scripts/hooks-system/bin/nightly-metrics-report.js +1 -0
  83. package/scripts/hooks-system/bin/plan-review.js +1 -0
  84. package/scripts/hooks-system/bin/predictive-hooks.js +1 -0
  85. package/scripts/hooks-system/bin/pumuki-audit.js +1 -0
  86. package/scripts/hooks-system/bin/pumuki-init.js +1 -0
  87. package/scripts/hooks-system/bin/pumuki-mcp.js +1 -0
  88. package/scripts/hooks-system/bin/pumuki-rules.js +1 -0
  89. package/scripts/hooks-system/bin/run-ast-adapter.js +2 -0
  90. package/scripts/hooks-system/bin/run-orchestrator.js +1 -0
  91. package/scripts/hooks-system/bin/run-playbook.js +1 -0
  92. package/scripts/hooks-system/bin/setup-eslint.js +1 -0
  93. package/scripts/hooks-system/bin/violations-api.js +1 -0
  94. package/scripts/hooks-system/bin/watch-hooks.js +1 -0
  95. package/scripts/hooks-system/domain/errors/index.js +2 -0
  96. package/scripts/hooks-system/domain/services/AuditAnalyzer.js +2 -0
  97. package/scripts/hooks-system/domain/services/AuditFilter.js +5 -0
  98. package/scripts/hooks-system/domain/services/AuditResultSerializer.js +5 -0
  99. package/scripts/hooks-system/domain/services/AuditScorer.js +6 -0
  100. package/scripts/hooks-system/infrastructure/adapters/AstAnalyzerAdapter.js +3 -0
  101. package/scripts/hooks-system/infrastructure/adapters/FileEvidenceAdapter.js +2 -0
  102. package/scripts/hooks-system/infrastructure/adapters/GitCliAdapter.js +4 -0
  103. package/scripts/hooks-system/infrastructure/adapters/GitCommandAdapter.js +4 -0
  104. package/scripts/hooks-system/infrastructure/adapters/GitHubCliAdapter.js +2 -0
  105. package/scripts/hooks-system/infrastructure/adapters/GitQueryAdapter.js +4 -0
  106. package/scripts/hooks-system/infrastructure/adapters/LegacyAnalyzerAdapter.js +2 -0
  107. package/scripts/hooks-system/infrastructure/adapters/MacOSNotificationAdapter.js +4 -0
  108. package/scripts/hooks-system/infrastructure/adapters/git/GitCommandRunner.js +2 -0
  109. package/scripts/hooks-system/infrastructure/adapters/git/GitCommandService.js +3 -0
  110. package/scripts/hooks-system/infrastructure/adapters/git/GitQueryService.js +3 -0
  111. package/scripts/hooks-system/infrastructure/ast/android/analyzers/AndroidASTIntelligentAnalyzer.js +2 -0
  112. package/scripts/hooks-system/infrastructure/ast/android/analyzers/AndroidASTParser.js +2 -0
  113. package/scripts/hooks-system/infrastructure/ast/android/analyzers/AndroidAnalysisOrchestrator.js +2 -0
  114. package/scripts/hooks-system/infrastructure/ast/android/analyzers/AndroidArchitectureDetector.js +7 -5
  115. package/scripts/hooks-system/infrastructure/ast/android/analyzers/AndroidClassAnalyzer.js +3 -0
  116. package/scripts/hooks-system/infrastructure/ast/android/analyzers/AndroidForbiddenLiteralsAnalyzer.js +1 -0
  117. package/scripts/hooks-system/infrastructure/ast/android/analyzers/AndroidSOLIDAnalyzer.js +2 -0
  118. package/scripts/hooks-system/infrastructure/ast/archive/ios-rules.js +2 -0
  119. package/scripts/hooks-system/infrastructure/ast/archive/kotlin-analyzer.js +2 -0
  120. package/scripts/hooks-system/infrastructure/ast/archive/kotlin-parser.js +2 -0
  121. package/scripts/hooks-system/infrastructure/ast/archive/swift-analyzer.js +2 -0
  122. package/scripts/hooks-system/infrastructure/ast/backend/analyzers/BackendArchitectureDetector.js +2 -0
  123. package/scripts/hooks-system/infrastructure/ast/backend/analyzers/BackendPatternDetector.js +2 -0
  124. package/scripts/hooks-system/infrastructure/ast/common/BDDTDDWorkflowRules.js +2 -0
  125. package/scripts/hooks-system/infrastructure/ast/common/rules/BDDRules.js +2 -0
  126. package/scripts/hooks-system/infrastructure/ast/common/rules/ImplementationRules.js +2 -0
  127. package/scripts/hooks-system/infrastructure/ast/common/rules/TDDRules.js +2 -0
  128. package/scripts/hooks-system/infrastructure/ast/common/rules/WorkflowRules.js +2 -0
  129. package/scripts/hooks-system/infrastructure/ast/frontend/analyzers/FrontendArchitectureDetector.js +16 -14
  130. package/scripts/hooks-system/infrastructure/ast/frontend/analyzers/FrontendForbiddenLiteralsAnalyzer.js +5 -0
  131. package/scripts/hooks-system/infrastructure/ast/frontend/analyzers/FrontendSOLIDAnalyzer.js +2 -0
  132. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSASTIntelligentAnalyzer.js +2 -0
  133. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSArchitectureDetector.js +12 -10
  134. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSArchitectureRules.js +2 -0
  135. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSCICDRules.js +2 -0
  136. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSEnterpriseAnalyzer.js +2 -0
  137. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSForbiddenLiteralsAnalyzer.js +1 -0
  138. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSNetworkingAdvancedRules.js +2 -0
  139. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSPerformanceRules.js +3 -0
  140. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSSPMRules.js +2 -0
  141. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSSwiftUIAdvancedRules.js +2 -0
  142. package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSTestingAdvancedRules.js +2 -0
  143. package/scripts/hooks-system/infrastructure/ast/ios/native-bridge.js +1 -0
  144. package/scripts/hooks-system/infrastructure/ast/ios/parsers/SourceKittenParser.js +2 -0
  145. package/scripts/hooks-system/infrastructure/cli/install-wizard.js +1 -0
  146. package/scripts/hooks-system/infrastructure/mcp/ast-intelligence-automation.js +98 -42
  147. package/scripts/hooks-system/infrastructure/mcp/evidence-watcher.js +1 -0
  148. package/scripts/hooks-system/infrastructure/mcp/services/EvidenceService.js +4 -0
  149. package/scripts/hooks-system/infrastructure/mcp/services/McpProtocolHandler.js +2 -0
  150. package/scripts/hooks-system/infrastructure/orchestration/intelligent-audit.js +1 -1
  151. package/scripts/hooks-system/infrastructure/reporting/report-generator.js +4 -0
  152. package/scripts/hooks-system/infrastructure/reporting/severity-tracker.js +2 -0
  153. package/scripts/hooks-system/infrastructure/repositories/CursorTokenRepository.js +4 -0
  154. package/scripts/hooks-system/infrastructure/repositories/FileFindingsRepository.js +2 -0
  155. package/scripts/hooks-system/infrastructure/repositories/datasources/CursorApiDataSource.js +4 -0
  156. package/scripts/hooks-system/infrastructure/repositories/datasources/CursorFileDataSource.js +2 -0
  157. package/scripts/hooks-system/infrastructure/severity/context/context-builder.js +2 -0
  158. package/scripts/hooks-system/infrastructure/severity/policies/gate-policies.js +1 -0
  159. package/scripts/hooks-system/infrastructure/severity/severity-evaluator.js +2 -0
  160. package/scripts/hooks-system/infrastructure/telemetry/TelemetryService.js +2 -0
  161. package/scripts/hooks-system/infrastructure/telemetry/metrics-logger.js +2 -0
  162. package/scripts/hooks-system/infrastructure/utils/token-manager.js +2 -0
  163. package/scripts/hooks-system/infrastructure/validators/detect-commit-language.js +1 -0
  164. package/scripts/hooks-system/infrastructure/watchdog/auto-recovery.js +2 -1
  165. package/scripts/hooks-system/infrastructure/watchdog/health-check.js +2 -1
  166. package/scripts/hooks-system/infrastructure/watchdog/token-monitor.js +3 -1
@@ -1,10 +1,12 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
  const glob = require('glob');
4
+ const AuditLogger = require('../../../application/services/logging/AuditLogger');
4
5
 
5
6
  class FrontendArchitectureDetector {
6
7
  constructor(projectRoot) {
7
8
  this.projectRoot = projectRoot;
9
+ this.auditLogger = new AuditLogger({ repoRoot: projectRoot });
8
10
  this.patterns = {
9
11
  featureFirstClean: 0, // Feature-First + DDD + Clean Architecture
10
12
  componentBased: 0, // Component-Based Architecture
@@ -128,7 +130,7 @@ class FrontendArchitectureDetector {
128
130
 
129
131
  detectComponentBased(files) {
130
132
  const hasComponentsFolder = files.some(f => f.includes('/components/'));
131
-
133
+
132
134
  if (hasComponentsFolder) {
133
135
  this.patterns.componentBased += 10;
134
136
  }
@@ -143,10 +145,10 @@ class FrontendArchitectureDetector {
143
145
 
144
146
  files.forEach(file => {
145
147
  if (!file.includes('/components/')) return;
146
-
148
+
147
149
  const content = this.readFile(file);
148
150
  const componentImports = content.match(/from\s+['"]\.\.\/components\//g) || [];
149
-
151
+
150
152
  if (componentImports.length > 0) {
151
153
  this.patterns.componentBased += componentImports.length;
152
154
  }
@@ -155,7 +157,7 @@ class FrontendArchitectureDetector {
155
157
 
156
158
  detectAtomicDesign(files) {
157
159
  const atomicFolders = ['atoms', 'molecules', 'organisms', 'templates', 'pages'];
158
-
160
+
159
161
  const foundFolders = atomicFolders.filter(folder => {
160
162
  return files.some(f => f.includes(`/${folder}/`));
161
163
  });
@@ -164,9 +166,9 @@ class FrontendArchitectureDetector {
164
166
  this.patterns.atomicDesign += foundFolders.length * 5;
165
167
  }
166
168
 
167
- if (files.some(f => f.includes('/atoms/')) &&
168
- files.some(f => f.includes('/molecules/')) &&
169
- files.some(f => f.includes('/organisms/'))) {
169
+ if (files.some(f => f.includes('/atoms/')) &&
170
+ files.some(f => f.includes('/molecules/')) &&
171
+ files.some(f => f.includes('/organisms/'))) {
170
172
  this.patterns.atomicDesign += 10;
171
173
  }
172
174
  }
@@ -179,8 +181,8 @@ class FrontendArchitectureDetector {
179
181
  this.patterns.stateManagement += 5;
180
182
  }
181
183
 
182
- if (content.includes('redux') || content.includes('@reduxjs/toolkit') ||
183
- file.includes('slice') || file.includes('reducer')) {
184
+ if (content.includes('redux') || content.includes('@reduxjs/toolkit') ||
185
+ file.includes('slice') || file.includes('reducer')) {
184
186
  this.patterns.stateManagement += 5;
185
187
  }
186
188
 
@@ -197,17 +199,17 @@ class FrontendArchitectureDetector {
197
199
  detectMVC(files) {
198
200
  files.forEach(file => {
199
201
  if (!file.includes('component') && !file.endsWith('.tsx') && !file.endsWith('.jsx')) return;
200
-
202
+
201
203
  const content = this.readFile(file);
202
-
204
+
203
205
  if (content.includes('fetch(') || content.includes('axios.') || content.includes('.get(')) {
204
- const hasHook = files.some(f =>
206
+ const hasHook = files.some(f =>
205
207
  f.includes('use') && f.endsWith('.ts') && !f.includes('component')
206
208
  );
207
- const hasService = files.some(f =>
209
+ const hasService = files.some(f =>
208
210
  f.includes('service') || f.includes('api')
209
211
  );
210
-
212
+
211
213
  if (!hasHook && !hasService) {
212
214
  this.patterns.mvc += 3;
213
215
  }
@@ -1,4 +1,5 @@
1
1
  const { SyntaxKind } = require('../../ast-core');
2
+ const AuditLogger = require('../../../application/services/logging/AuditLogger');
2
3
 
3
4
  const FORBIDDEN_STRING_LITERALS = [
4
5
  'unknown',
@@ -22,6 +23,10 @@ const FORBIDDEN_STATUS_LITERALS = [
22
23
  const MAGIC_NUMBERS = [0, 1];
23
24
 
24
25
  class FrontendForbiddenLiteralsAnalyzer {
26
+ constructor() {
27
+ this.auditLogger = new AuditLogger({ repoRoot: process.cwd() });
28
+ }
29
+
25
30
  analyze(sf, findings, pushFinding) {
26
31
  const stringLiterals = sf.getDescendantsOfKind(SyntaxKind.StringLiteral);
27
32
  const numericLiterals = sf.getDescendantsOfKind(SyntaxKind.NumericLiteral);
@@ -1,6 +1,7 @@
1
1
 
2
2
  const path = require('path');
3
3
  const { pushFinding, SyntaxKind } = require(path.join(__dirname, '../../ast-core'));
4
+ const AuditLogger = require('../../../application/services/logging/AuditLogger');
4
5
 
5
6
  /**
6
7
  * FrontendSOLIDAnalyzer
@@ -12,6 +13,7 @@ const { pushFinding, SyntaxKind } = require(path.join(__dirname, '../../ast-core
12
13
  class FrontendSOLIDAnalyzer {
13
14
  constructor() {
14
15
  this.findings = [];
16
+ this.auditLogger = new AuditLogger({ repoRoot: process.cwd() });
15
17
  }
16
18
 
17
19
  /**
@@ -4,10 +4,12 @@ const fs = require('fs');
4
4
  const path = require('path');
5
5
  const crypto = require('crypto');
6
6
  const env = require(path.join(__dirname, '../../../../config/env'));
7
+ const AuditLogger = require('../../application/services/logging/AuditLogger');
7
8
 
8
9
  class iOSASTIntelligentAnalyzer {
9
10
  constructor(findings) {
10
11
  this.findings = findings;
12
+ this.auditLogger = new AuditLogger({ repoRoot: process.cwd() });
11
13
  this.sourceKittenPath = '/opt/homebrew/bin/sourcekitten';
12
14
  this.isAvailable = this.checkSourceKitten();
13
15
  this.hasSwiftSyntax = this.checkSwiftSyntax();
@@ -1,12 +1,14 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
  const glob = require('glob');
4
+ const AuditLogger = require('../../application/services/logging/AuditLogger');
4
5
 
5
6
  class iOSArchitectureDetector {
6
7
  constructor(projectRoot) {
7
8
  this.projectRoot = projectRoot;
9
+ this.auditLogger = new AuditLogger({ repoRoot: projectRoot });
8
10
  this.patterns = {
9
- featureFirstClean: 0,
11
+ featureFirstClean: 0,
10
12
  mvvm: 0,
11
13
  mvvmc: 0,
12
14
  mvp: 0,
@@ -81,7 +83,7 @@ class iOSArchitectureDetector {
81
83
  );
82
84
 
83
85
  if (hasFeaturesFolders) {
84
- this.patterns.featureFirstClean += 10;
86
+ this.patterns.featureFirstClean += 10;
85
87
  }
86
88
 
87
89
  if (foundCleanFolders.length >= 3) {
@@ -247,8 +249,8 @@ class iOSArchitectureDetector {
247
249
  const content = this.readFile(file);
248
250
 
249
251
  if (content.includes('protocol Coordinator') ||
250
- content.includes(': Coordinator') ||
251
- /func\s+start\(\)/.test(content) && /func\s+navigate/.test(content)) {
252
+ content.includes(': Coordinator') ||
253
+ /func\s+start\(\)/.test(content) && /func\s+navigate/.test(content)) {
252
254
  this.patterns.mvvmc += 2;
253
255
  }
254
256
  });
@@ -288,16 +290,16 @@ class iOSArchitectureDetector {
288
290
  const interactorFiles = files.filter(f => /Interactor\.swift$/.test(f));
289
291
 
290
292
  if (viewControllerFiles.length >= 2 &&
291
- viewModelFiles.length === 0 &&
292
- presenterFiles.length === 0 &&
293
- interactorFiles.length === 0) {
293
+ viewModelFiles.length === 0 &&
294
+ presenterFiles.length === 0 &&
295
+ interactorFiles.length === 0) {
294
296
 
295
297
  viewControllerFiles.forEach(file => {
296
298
  const content = this.readFile(file);
297
299
  const lines = content.split('\n').length;
298
300
 
299
301
  if (lines > 300) {
300
- this.patterns.mvc += 3;
302
+ this.patterns.mvc += 3;
301
303
  } else if (lines > 150) {
302
304
  this.patterns.mvc += 2;
303
305
  } else {
@@ -323,7 +325,7 @@ class iOSArchitectureDetector {
323
325
  }
324
326
 
325
327
  if (sorted.length > 1 && sorted[1][1] >= dominantScore * 0.7) {
326
- return 'MIXED';
328
+ return 'MIXED';
327
329
  }
328
330
 
329
331
  return this.normalizePatternName(dominant);
@@ -331,7 +333,7 @@ class iOSArchitectureDetector {
331
333
 
332
334
  normalizePatternName(pattern) {
333
335
  const mapping = {
334
- 'featureFirstClean': 'FEATURE_FIRST_CLEAN_DDD',
336
+ 'featureFirstClean': 'FEATURE_FIRST_CLEAN_DDD',
335
337
  'mvvm': 'MVVM',
336
338
  'mvvmc': 'MVVM-C',
337
339
  'mvp': 'MVP',
@@ -1,9 +1,11 @@
1
1
  const { pushFinding } = require('../../ast-core');
2
+ const AuditLogger = require('../../application/services/logging/AuditLogger');
2
3
 
3
4
  class iOSArchitectureRules {
4
5
  constructor(findings, detectedPattern) {
5
6
  this.findings = findings;
6
7
  this.pattern = detectedPattern;
8
+ this.auditLogger = new AuditLogger({ repoRoot: process.cwd() });
7
9
  }
8
10
 
9
11
  runRules(files) {
@@ -12,11 +12,13 @@ const { pushFinding } = require('../../ast-core');
12
12
  const fs = require('fs');
13
13
  const path = require('path');
14
14
  const glob = require('glob');
15
+ const AuditLogger = require('../../application/services/logging/AuditLogger');
15
16
 
16
17
  class iOSCICDRules {
17
18
  constructor(findings, projectRoot) {
18
19
  this.findings = findings;
19
20
  this.projectRoot = projectRoot;
21
+ this.auditLogger = new AuditLogger({ repoRoot: projectRoot });
20
22
  }
21
23
 
22
24
  analyze() {
@@ -2,11 +2,13 @@ const path = require('path');
2
2
  const fs = require('fs').promises;
3
3
  const { SourceKittenParser } = require('../parsers/SourceKittenParser');
4
4
  const { pushFinding, mapToLevel } = require(path.join(__dirname, '../../ast-core'));
5
+ const AuditLogger = require('../../application/services/logging/AuditLogger');
5
6
 
6
7
  class iOSEnterpriseAnalyzer {
7
8
  constructor() {
8
9
  this.parser = new SourceKittenParser();
9
10
  this.findings = [];
11
+ this.auditLogger = new AuditLogger({ repoRoot: process.cwd() });
10
12
  }
11
13
 
12
14
  async analyzeFile(filePath, findings) {
@@ -1,4 +1,5 @@
1
1
  const { SyntaxKind } = require('../../ast-core');
2
+ const AuditLogger = require('../../application/services/logging/AuditLogger');
2
3
 
3
4
  const FORBIDDEN_STRING_LITERALS = [
4
5
  'unknown',
@@ -9,10 +9,12 @@
9
9
  const { pushFinding } = require('../../ast-core');
10
10
  const fs = require('fs');
11
11
  const glob = require('glob');
12
+ const AuditLogger = require('../../application/services/logging/AuditLogger');
12
13
 
13
14
  class iOSNetworkingAdvancedRules {
14
15
  constructor(findings, projectRoot) {
15
16
  this.findings = findings;
17
+ this.auditLogger = new AuditLogger({ repoRoot: projectRoot });
16
18
  this.projectRoot = projectRoot;
17
19
  }
18
20
 
@@ -1,6 +1,9 @@
1
+ const AuditLogger = require('../../application/services/logging/AuditLogger');
2
+
1
3
  class iOSPerformanceRules {
2
4
  constructor(findings) {
3
5
  this.findings = findings;
6
+ this.auditLogger = new AuditLogger({ repoRoot: process.cwd() });
4
7
  }
5
8
 
6
9
  analyzeFile(filePath, content) {
@@ -13,11 +13,13 @@
13
13
  const { pushFinding } = require('../../ast-core');
14
14
  const fs = require('fs');
15
15
  const path = require('path');
16
+ const AuditLogger = require('../../application/services/logging/AuditLogger');
16
17
 
17
18
  class iOSSPMRules {
18
19
  constructor(findings, projectRoot) {
19
20
  this.findings = findings;
20
21
  this.projectRoot = projectRoot;
22
+ this.auditLogger = new AuditLogger({ repoRoot: projectRoot });
21
23
  }
22
24
 
23
25
  analyze() {
@@ -12,10 +12,12 @@
12
12
 
13
13
  const { pushFinding } = require('../../ast-core');
14
14
  const fs = require('fs');
15
+ const AuditLogger = require('../../application/services/logging/AuditLogger');
15
16
 
16
17
  class iOSSwiftUIAdvancedRules {
17
18
  constructor(findings) {
18
19
  this.findings = findings;
20
+ this.auditLogger = new AuditLogger({ repoRoot: process.cwd() });
19
21
  }
20
22
 
21
23
  analyzeFile(filePath, ast) {
@@ -10,10 +10,12 @@ const { pushFinding } = require('../../ast-core');
10
10
  const fs = require('fs');
11
11
  const glob = require('glob');
12
12
  const path = require('path');
13
+ const AuditLogger = require('../../application/services/logging/AuditLogger');
13
14
 
14
15
  class iOSTestingAdvancedRules {
15
16
  constructor(findings, projectRoot) {
16
17
  this.findings = findings;
18
+ this.auditLogger = new AuditLogger({ repoRoot: projectRoot });
17
19
  this.projectRoot = projectRoot;
18
20
  }
19
21
 
@@ -3,6 +3,7 @@ const path = require('path');
3
3
  const fs = require('fs');
4
4
  const { pushFileFinding } = require('../ast-core');
5
5
  const env = require(path.join(__dirname, '../../../config/env'));
6
+ const AuditLogger = require('../../application/services/logging/AuditLogger');
6
7
 
7
8
  function getStagedSwiftFiles(repoRoot) {
8
9
  try {
@@ -5,6 +5,7 @@ const util = require('util');
5
5
  const fs = require('fs').promises;
6
6
  const path = require('path');
7
7
  const { DomainError } = require('../../../../domain/errors');
8
+ const AuditLogger = require('../../../../application/services/logging/AuditLogger');
8
9
 
9
10
  const execPromise = util.promisify(exec);
10
11
 
@@ -20,6 +21,7 @@ class SourceKittenParser {
20
21
  constructor() {
21
22
  this.sourceKittenPath = '/opt/homebrew/bin/sourcekitten';
22
23
  this.timeout = 30000;
24
+ this.auditLogger = new AuditLogger({ repoRoot: process.cwd() });
23
25
  }
24
26
 
25
27
  /**
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ const env = require('../../config/env');
3
4
  const fs = require('fs');
4
5
  const path = require('path');
5
6
  const readline = require('readline');
@@ -18,6 +18,7 @@
18
18
  const fs = require('fs');
19
19
  const path = require('path');
20
20
  const { execSync } = require('child_process');
21
+ const env = require('../../config/env');
21
22
 
22
23
  // Removed global requires for performance (Lazy Loading)
23
24
  // const AutonomousOrchestrator = require('../../application/services/AutonomousOrchestrator');
@@ -43,7 +44,7 @@ function safeGitRoot(startDir) {
43
44
  }
44
45
 
45
46
  function resolveRepoRoot() {
46
- const envRoot = (process.env.REPO_ROOT || '').trim() || null;
47
+ const envRoot = (env.get('REPO_ROOT') || '').trim() || null;
47
48
  const cwdRoot = safeGitRoot(process.cwd());
48
49
  // Prefer explicit REPO_ROOT to avoid cross-repo bleed when MCP server is launched from another workspace
49
50
  if (envRoot) return envRoot;
@@ -57,14 +58,25 @@ const MCP_LOCK_DIR = path.join(REPO_ROOT, '.audit_tmp', 'mcp-singleton.lock');
57
58
  const MCP_LOCK_PID = path.join(MCP_LOCK_DIR, 'pid');
58
59
 
59
60
  let MCP_IS_PRIMARY = true;
60
- let MCP_PRIMARY_PID = null;
61
+
62
+ function logMcpError(context, error) {
63
+ const msg = error instanceof Error ? error.message : String(error);
64
+ process.stderr.write(`[MCP][ERROR] ${context}: ${msg}\n`);
65
+ }
66
+
67
+ function logMcpDebug(message) {
68
+ if (env.getBool('DEBUG', false)) {
69
+ process.stderr.write(`[MCP][DEBUG] ${message}\n`);
70
+ }
71
+ }
61
72
 
62
73
  function isPidRunning(pid) {
63
74
  if (!pid || !Number.isFinite(pid) || pid <= 0) return false;
64
75
  try {
65
76
  process.kill(pid, 0);
66
77
  return true;
67
- } catch {
78
+ } catch (error) {
79
+ logMcpDebug(`isPidRunning(${pid}) = false: ${error.code || error.message}`);
68
80
  return false;
69
81
  }
70
82
  }
@@ -76,7 +88,8 @@ function safeReadPid(filePath) {
76
88
  const pid = Number(raw);
77
89
  if (!Number.isFinite(pid) || pid <= 0) return null;
78
90
  return pid;
79
- } catch {
91
+ } catch (error) {
92
+ logMcpError('safeReadPid', error);
80
93
  return null;
81
94
  }
82
95
  }
@@ -85,68 +98,122 @@ function removeLockDir() {
85
98
  try {
86
99
  if (fs.existsSync(MCP_LOCK_PID)) {
87
100
  fs.unlinkSync(MCP_LOCK_PID);
101
+ logMcpDebug('Removed lock PID file');
88
102
  }
89
- } catch {
90
- // ignore
103
+ } catch (error) {
104
+ logMcpError('removeLockDir (pid file)', error);
91
105
  }
92
106
  try {
93
107
  if (fs.existsSync(MCP_LOCK_DIR)) {
94
108
  fs.rmdirSync(MCP_LOCK_DIR);
109
+ logMcpDebug('Removed lock directory');
95
110
  }
96
- } catch {
97
- // ignore
111
+ } catch (error) {
112
+ logMcpError('removeLockDir (directory)', error);
113
+ }
114
+ }
115
+
116
+ function cleanupAndExit(code = 0) {
117
+ const myPid = process.pid;
118
+ const lockPid = safeReadPid(MCP_LOCK_PID);
119
+
120
+ if (lockPid === myPid) {
121
+ logMcpDebug(`Cleaning up lock (my pid=${myPid})`);
122
+ removeLockDir();
123
+ } else {
124
+ logMcpDebug(`Not cleaning lock (lockPid=${lockPid}, myPid=${myPid})`);
125
+ }
126
+
127
+ process.exit(code);
128
+ }
129
+
130
+ function installStdioExitHandlers() {
131
+ const handleStdioTermination = (source) => (error) => {
132
+ if (error) {
133
+ const code = String(error.code || '').toUpperCase();
134
+ if (code === 'EPIPE' || code === 'ERR_STREAM_DESTROYED' || code === 'ECONNRESET') {
135
+ logMcpDebug(`STDIO ${source} closed (${code}), exiting cleanly`);
136
+ cleanupAndExit(0);
137
+ return;
138
+ }
139
+ logMcpError(`STDIO ${source} error`, error);
140
+ } else {
141
+ logMcpDebug(`STDIO ${source} ended, exiting cleanly`);
142
+ }
143
+ cleanupAndExit(0);
144
+ };
145
+
146
+ try {
147
+ process.stdin.on('end', handleStdioTermination('stdin'));
148
+ process.stdin.on('close', handleStdioTermination('stdin'));
149
+ process.stdin.on('error', handleStdioTermination('stdin'));
150
+ } catch (error) {
151
+ logMcpError('installStdioExitHandlers (stdin)', error);
152
+ }
153
+
154
+ try {
155
+ process.stdout.on('error', handleStdioTermination('stdout'));
156
+ process.stderr.on('error', handleStdioTermination('stderr'));
157
+ } catch (error) {
158
+ logMcpError('installStdioExitHandlers (stdout/stderr)', error);
98
159
  }
99
160
  }
100
161
 
101
162
  function acquireSingletonLock() {
102
163
  try {
103
164
  fs.mkdirSync(path.join(REPO_ROOT, '.audit_tmp'), { recursive: true });
104
- } catch {
105
- // ignore
165
+ } catch (error) {
166
+ logMcpError('acquireSingletonLock (create .audit_tmp)', error);
106
167
  }
107
168
 
108
169
  try {
109
170
  fs.mkdirSync(MCP_LOCK_DIR);
110
171
  } catch (error) {
111
172
  const existingPid = safeReadPid(MCP_LOCK_PID);
173
+
112
174
  if (existingPid && isPidRunning(existingPid)) {
113
- MCP_IS_PRIMARY = false;
114
- MCP_PRIMARY_PID = existingPid;
115
- process.stderr.write(`[MCP] Another instance is already running (pid ${existingPid}). Secondary mode enabled.\n`);
116
- return { acquired: false, pid: existingPid };
175
+ process.stderr.write(`[MCP] Another instance is already running (pid ${existingPid}). Exiting.\n`);
176
+ process.exit(0);
117
177
  }
118
178
 
179
+ logMcpDebug(`Lock exists but PID ${existingPid || 'unknown'} is not running, cleaning up`);
119
180
  removeLockDir();
120
- fs.mkdirSync(MCP_LOCK_DIR);
181
+
182
+ try {
183
+ fs.mkdirSync(MCP_LOCK_DIR);
184
+ } catch (retryError) {
185
+ logMcpError('acquireSingletonLock (retry mkdir)', retryError);
186
+ process.stderr.write(`[MCP] Failed to acquire lock after cleanup. Exiting.\n`);
187
+ process.exit(1);
188
+ }
121
189
  }
122
190
 
123
191
  try {
124
192
  fs.writeFileSync(MCP_LOCK_PID, String(process.pid), { encoding: 'utf8' });
125
- } catch {
126
- // ignore
193
+ logMcpDebug(`Lock acquired, PID ${process.pid} written`);
194
+ } catch (error) {
195
+ logMcpError('acquireSingletonLock (write pid)', error);
127
196
  }
128
197
 
129
- const cleanup = () => {
130
- const pid = safeReadPid(MCP_LOCK_PID);
131
- if (pid === process.pid) {
198
+ process.on('exit', () => {
199
+ const lockPid = safeReadPid(MCP_LOCK_PID);
200
+ if (lockPid === process.pid) {
132
201
  removeLockDir();
133
202
  }
134
- };
135
-
136
- process.on('exit', cleanup);
137
- process.on('SIGINT', () => {
138
- cleanup();
139
- process.exit(0);
140
- });
141
- process.on('SIGTERM', () => {
142
- cleanup();
143
- process.exit(0);
144
203
  });
145
204
 
205
+ process.on('SIGINT', () => cleanupAndExit(0));
206
+ process.on('SIGTERM', () => cleanupAndExit(0));
207
+ process.on('SIGHUP', () => cleanupAndExit(0));
208
+
146
209
  return { acquired: true, pid: process.pid };
147
210
  }
148
211
 
149
- acquireSingletonLock();
212
+ const singleton = acquireSingletonLock();
213
+ if (!singleton.acquired) {
214
+ process.exit(0);
215
+ }
216
+ installStdioExitHandlers();
150
217
 
151
218
  // Lazy-loaded CompositionRoot - only initialized when first needed
152
219
  let _compositionRoot = null;
@@ -767,17 +834,6 @@ async function handleMcpMessage(message) {
767
834
  try {
768
835
  const request = JSON.parse(message);
769
836
 
770
- if (!MCP_IS_PRIMARY && request.method !== 'initialize' && request.method !== 'resources/list' && request.method !== 'resources/read' && request.method !== 'tools/list') {
771
- return {
772
- jsonrpc: '2.0',
773
- id: request.id,
774
- error: {
775
- code: -32603,
776
- message: `MCP instance already running (pid ${MCP_PRIMARY_PID || 'unknown'}). Please restart the IDE or kill the running instance.`
777
- }
778
- };
779
- }
780
-
781
837
  if ((typeof request.id === 'undefined' || request.id === null) && request.method?.startsWith('notifications/')) {
782
838
  return null;
783
839
  }
@@ -6,6 +6,7 @@
6
6
  * The AI can automatically check if evidence is stale and update it
7
7
  */
8
8
 
9
+ const env = require('../../config/env');
9
10
  const path = require('path');
10
11
  const McpProtocolHandler = require('./services/McpProtocolHandler');
11
12
  const EvidenceService = require('./services/EvidenceService');
@@ -1,3 +1,6 @@
1
+ const env = require('../../../config/env');
2
+ const AuditLogger = require('../../../application/services/logging/AuditLogger');
3
+
1
4
  const fs = require('fs');
2
5
  const path = require('path');
3
6
  const { execSync } = require('child_process');
@@ -5,6 +8,7 @@ const { execSync } = require('child_process');
5
8
  class EvidenceService {
6
9
  constructor(repoRoot, logger) {
7
10
  this.repoRoot = repoRoot || process.env.REPO_ROOT || process.cwd();
11
+ this.auditLogger = new AuditLogger({ repoRoot: this.repoRoot, logger });
8
12
  this.evidenceFile = path.join(this.repoRoot, '.AI_EVIDENCE.json');
9
13
  this.maxEvidenceAge = 180; // 3 minutes
10
14
  this.logger = logger;
@@ -1,10 +1,12 @@
1
1
  const MCP_VERSION = '2024-11-05';
2
+ const AuditLogger = require('../../../application/services/logging/AuditLogger');
2
3
 
3
4
  class McpProtocolHandler {
4
5
  constructor(inputStream, outputStream, logger) {
5
6
  this.inputStream = inputStream;
6
7
  this.outputStream = outputStream;
7
8
  this.logger = logger;
9
+ this.auditLogger = new AuditLogger({ repoRoot: process.cwd(), logger });
8
10
  this.buffer = Buffer.alloc(0);
9
11
  }
10
12
 
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ const env = require('../../config/env');
3
4
  const { evaluateViolations } = require('../severity/severity-evaluator');
4
5
  const { GatePolicies } = require('../severity/policies/gate-policies');
5
6
  const { ReportGenerator } = require('../reporting/report-generator');
@@ -8,7 +9,6 @@ const { TokenManager } = require('../utils/token-manager');
8
9
  const { toErrorMessage } = require('../utils/error-utils');
9
10
  const fs = require('fs');
10
11
  const path = require('path');
11
- const env = require('../../../config/env.js');
12
12
 
13
13
  function resolveAuditTmpDir() {
14
14
  const configured = (env.get('AUDIT_TMP', '') || '').trim();
@@ -1,14 +1,18 @@
1
+ const env = require('../../config/env');
2
+
1
3
  const fs = require('fs');
2
4
  const path = require('path');
3
5
  const ReportPresenter = require('./ReportPresenter');
4
6
  const ReportMetricsCalculator = require('./ReportMetricsCalculator');
5
7
  const ReportImpactAnalyzer = require('./ReportImpactAnalyzer');
8
+ const AuditLogger = require('../../application/services/logging/AuditLogger');
6
9
 
7
10
  class ReportGenerator {
8
11
  constructor() {
9
12
  this.presenter = new ReportPresenter();
10
13
  this.metricsCalculator = new ReportMetricsCalculator();
11
14
  this.impactAnalyzer = new ReportImpactAnalyzer(this.metricsCalculator);
15
+ this.auditLogger = new AuditLogger({ repoRoot: process.cwd() });
12
16
  }
13
17
 
14
18
  /**