pumuki-ast-hooks 6.0.16 → 6.1.0
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/package.json +2 -2
- package/scripts/hooks-system/.audit-reports/auto-recovery.log +5 -0
- package/scripts/hooks-system/.audit-reports/install-wizard.log +20 -0
- package/scripts/hooks-system/.audit_tmp/hook-metrics.jsonl +120 -0
- package/scripts/hooks-system/application/services/installation/__tests__/McpConfigurator.mcp.spec.js +74 -0
- package/scripts/hooks-system/application/services/installation/mcp/McpProjectConfigWriter.js +14 -2
- package/scripts/hooks-system/application/services/installation/mcp/McpServerConfigBuilder.js +40 -0
- package/scripts/hooks-system/infrastructure/mcp/evidence-watcher.js +44 -0
- package/scripts/hooks-system/infrastructure/mcp/services/McpProtocolHandler.js +17 -0
- package/scripts/hooks-system/infrastructure/mcp/services/__tests__/McpProtocolHandler.notifications.spec.js +22 -0
- package/scripts/hooks-system/infrastructure/watchdog/__tests__/.audit-reports/token-monitor.log +15 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumuki-ast-hooks",
|
|
3
|
-
"version": "6.0
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"description": "Enterprise-grade AST Intelligence System with multi-platform support (iOS, Android, Backend, Frontend) and Feature-First + DDD + Clean Architecture enforcement. Includes dynamic violations API for intelligent querying.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -135,4 +135,4 @@
|
|
|
135
135
|
"./skills": "./skills/skill-rules.json",
|
|
136
136
|
"./hooks": "./hooks/index.js"
|
|
137
137
|
}
|
|
138
|
-
}
|
|
138
|
+
}
|
|
@@ -23,3 +23,8 @@
|
|
|
23
23
|
{"timestamp":"2026-01-13T11:12:40.853Z","level":"info","component":"AutoRecovery","event":"NotificationCenterService shutdown","data":{"totalEnqueued":0,"totalSent":0,"totalDeduplicated":0,"totalCooldownSkipped":0,"totalFailed":0,"totalRetries":0,"queueSize":0,"deduplication":{"size":0},"cooldowns":{"activeCooldowns":0}},"context":{}}
|
|
24
24
|
{"timestamp":"2026-01-13T11:21:28.037Z","level":"info","component":"AutoRecovery","event":"NotificationCenterService shutdown","data":{"totalEnqueued":0,"totalSent":0,"totalDeduplicated":0,"totalCooldownSkipped":0,"totalFailed":0,"totalRetries":0,"queueSize":0,"deduplication":{"size":0},"cooldowns":{"activeCooldowns":0}},"context":{}}
|
|
25
25
|
{"timestamp":"2026-01-13T11:31:00.351Z","level":"info","component":"AutoRecovery","event":"NotificationCenterService shutdown","data":{"totalEnqueued":0,"totalSent":0,"totalDeduplicated":0,"totalCooldownSkipped":0,"totalFailed":0,"totalRetries":0,"queueSize":0,"deduplication":{"size":0},"cooldowns":{"activeCooldowns":0}},"context":{}}
|
|
26
|
+
{"timestamp":"2026-01-13T13:12:18.872Z","level":"info","component":"AutoRecovery","event":"NotificationCenterService shutdown","data":{"totalEnqueued":0,"totalSent":0,"totalDeduplicated":0,"totalCooldownSkipped":0,"totalFailed":0,"totalRetries":0,"queueSize":0,"deduplication":{"size":0},"cooldowns":{"activeCooldowns":0}},"context":{}}
|
|
27
|
+
{"timestamp":"2026-01-13T13:23:55.165Z","level":"info","component":"AutoRecovery","event":"NotificationCenterService shutdown","data":{"totalEnqueued":0,"totalSent":0,"totalDeduplicated":0,"totalCooldownSkipped":0,"totalFailed":0,"totalRetries":0,"queueSize":0,"deduplication":{"size":0},"cooldowns":{"activeCooldowns":0}},"context":{}}
|
|
28
|
+
{"timestamp":"2026-01-13T13:58:43.218Z","level":"info","component":"AutoRecovery","event":"NotificationCenterService shutdown","data":{"totalEnqueued":0,"totalSent":0,"totalDeduplicated":0,"totalCooldownSkipped":0,"totalFailed":0,"totalRetries":0,"queueSize":0,"deduplication":{"size":0},"cooldowns":{"activeCooldowns":0}},"context":{}}
|
|
29
|
+
{"timestamp":"2026-01-13T17:20:09.962Z","level":"info","component":"AutoRecovery","event":"NotificationCenterService shutdown","data":{"totalEnqueued":0,"totalSent":0,"totalDeduplicated":0,"totalCooldownSkipped":0,"totalFailed":0,"totalRetries":0,"queueSize":0,"deduplication":{"size":0},"cooldowns":{"activeCooldowns":0}},"context":{}}
|
|
30
|
+
{"timestamp":"2026-01-13T17:21:43.217Z","level":"info","component":"AutoRecovery","event":"NotificationCenterService shutdown","data":{"totalEnqueued":0,"totalSent":0,"totalDeduplicated":0,"totalCooldownSkipped":0,"totalFailed":0,"totalRetries":0,"queueSize":0,"deduplication":{"size":0},"cooldowns":{"activeCooldowns":0}},"context":{}}
|
|
@@ -102,3 +102,23 @@
|
|
|
102
102
|
{"timestamp":"2026-01-13T11:31:00.203Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_CONFIG_EXISTS","data":{"configPath":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/.hook-system/config.json"},"context":{}}
|
|
103
103
|
{"timestamp":"2026-01-13T11:31:00.203Z","level":"error","component":"InstallWizard","event":"INSTALL_WIZARD_SYMLINK_FAILED","data":{"error":"EEXIST: file already exists, symlink '/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/scripts/hooks-system/bin/guard-supervisor.js' -> '/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/.git/hooks/guard-supervisor'"},"context":{}}
|
|
104
104
|
{"timestamp":"2026-01-13T11:31:00.203Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
|
|
105
|
+
{"timestamp":"2026-01-13T13:12:18.928Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_START","data":{"repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"},"context":{}}
|
|
106
|
+
{"timestamp":"2026-01-13T13:12:18.936Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_CONFIG_EXISTS","data":{"configPath":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/.hook-system/config.json"},"context":{}}
|
|
107
|
+
{"timestamp":"2026-01-13T13:12:18.937Z","level":"error","component":"InstallWizard","event":"INSTALL_WIZARD_SYMLINK_FAILED","data":{"error":"EEXIST: file already exists, symlink '/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/scripts/hooks-system/bin/guard-supervisor.js' -> '/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/.git/hooks/guard-supervisor'"},"context":{}}
|
|
108
|
+
{"timestamp":"2026-01-13T13:12:18.937Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
|
|
109
|
+
{"timestamp":"2026-01-13T13:23:55.815Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_START","data":{"repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"},"context":{}}
|
|
110
|
+
{"timestamp":"2026-01-13T13:23:55.824Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_CONFIG_EXISTS","data":{"configPath":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/.hook-system/config.json"},"context":{}}
|
|
111
|
+
{"timestamp":"2026-01-13T13:23:55.825Z","level":"error","component":"InstallWizard","event":"INSTALL_WIZARD_SYMLINK_FAILED","data":{"error":"EEXIST: file already exists, symlink '/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/scripts/hooks-system/bin/guard-supervisor.js' -> '/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/.git/hooks/guard-supervisor'"},"context":{}}
|
|
112
|
+
{"timestamp":"2026-01-13T13:23:55.825Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
|
|
113
|
+
{"timestamp":"2026-01-13T13:58:43.281Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_START","data":{"repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"},"context":{}}
|
|
114
|
+
{"timestamp":"2026-01-13T13:58:43.290Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_CONFIG_EXISTS","data":{"configPath":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/.hook-system/config.json"},"context":{}}
|
|
115
|
+
{"timestamp":"2026-01-13T13:58:43.290Z","level":"error","component":"InstallWizard","event":"INSTALL_WIZARD_SYMLINK_FAILED","data":{"error":"EEXIST: file already exists, symlink '/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/scripts/hooks-system/bin/guard-supervisor.js' -> '/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/.git/hooks/guard-supervisor'"},"context":{}}
|
|
116
|
+
{"timestamp":"2026-01-13T13:58:43.290Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
|
|
117
|
+
{"timestamp":"2026-01-13T17:20:10.168Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_START","data":{"repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"},"context":{}}
|
|
118
|
+
{"timestamp":"2026-01-13T17:20:10.177Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_CONFIG_EXISTS","data":{"configPath":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/.hook-system/config.json"},"context":{}}
|
|
119
|
+
{"timestamp":"2026-01-13T17:20:10.177Z","level":"error","component":"InstallWizard","event":"INSTALL_WIZARD_SYMLINK_FAILED","data":{"error":"EEXIST: file already exists, symlink '/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/scripts/hooks-system/bin/guard-supervisor.js' -> '/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/.git/hooks/guard-supervisor'"},"context":{}}
|
|
120
|
+
{"timestamp":"2026-01-13T17:20:10.177Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
|
|
121
|
+
{"timestamp":"2026-01-13T17:21:43.135Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_START","data":{"repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"},"context":{}}
|
|
122
|
+
{"timestamp":"2026-01-13T17:21:43.143Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_CONFIG_EXISTS","data":{"configPath":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/.hook-system/config.json"},"context":{}}
|
|
123
|
+
{"timestamp":"2026-01-13T17:21:43.143Z","level":"error","component":"InstallWizard","event":"INSTALL_WIZARD_SYMLINK_FAILED","data":{"error":"EEXIST: file already exists, symlink '/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/scripts/hooks-system/bin/guard-supervisor.js' -> '/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system/.git/hooks/guard-supervisor'"},"context":{}}
|
|
124
|
+
{"timestamp":"2026-01-13T17:21:43.143Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
|
|
@@ -866,3 +866,123 @@
|
|
|
866
866
|
{"timestamp":1768303860351,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
867
867
|
{"timestamp":1768303860351,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
868
868
|
{"timestamp":1768303860351,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
869
|
+
{"timestamp":1768309938870,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
870
|
+
{"timestamp":1768309938871,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
871
|
+
{"timestamp":1768309938871,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
872
|
+
{"timestamp":1768309938871,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
873
|
+
{"timestamp":1768309938871,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
874
|
+
{"timestamp":1768309938871,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
875
|
+
{"timestamp":1768309938871,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
876
|
+
{"timestamp":1768309938871,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
877
|
+
{"timestamp":1768309938871,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
878
|
+
{"timestamp":1768309938871,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
879
|
+
{"timestamp":1768309938871,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
880
|
+
{"timestamp":1768309938871,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
881
|
+
{"timestamp":1768309938871,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
882
|
+
{"timestamp":1768309938871,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
883
|
+
{"timestamp":1768309938871,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
884
|
+
{"timestamp":1768309938871,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
885
|
+
{"timestamp":1768309938872,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
886
|
+
{"timestamp":1768309938872,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
887
|
+
{"timestamp":1768309938872,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
888
|
+
{"timestamp":1768309938872,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
889
|
+
{"timestamp":1768309938872,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
890
|
+
{"timestamp":1768309938872,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
891
|
+
{"timestamp":1768309938872,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
892
|
+
{"timestamp":1768309938872,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
893
|
+
{"timestamp":1768310635163,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
894
|
+
{"timestamp":1768310635164,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
895
|
+
{"timestamp":1768310635164,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
896
|
+
{"timestamp":1768310635164,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
897
|
+
{"timestamp":1768310635164,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
898
|
+
{"timestamp":1768310635164,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
899
|
+
{"timestamp":1768310635164,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
900
|
+
{"timestamp":1768310635164,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
901
|
+
{"timestamp":1768310635164,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
902
|
+
{"timestamp":1768310635164,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
903
|
+
{"timestamp":1768310635164,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
904
|
+
{"timestamp":1768310635164,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
905
|
+
{"timestamp":1768310635164,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
906
|
+
{"timestamp":1768310635164,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
907
|
+
{"timestamp":1768310635164,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
908
|
+
{"timestamp":1768310635164,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
909
|
+
{"timestamp":1768310635165,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
910
|
+
{"timestamp":1768310635165,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
911
|
+
{"timestamp":1768310635165,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
912
|
+
{"timestamp":1768310635165,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
913
|
+
{"timestamp":1768310635165,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
914
|
+
{"timestamp":1768310635165,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
915
|
+
{"timestamp":1768310635165,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
916
|
+
{"timestamp":1768310635165,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
917
|
+
{"timestamp":1768312723217,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
918
|
+
{"timestamp":1768312723217,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
919
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
920
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
921
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
922
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
923
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
924
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
925
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
926
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
927
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
928
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
929
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
930
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
931
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
932
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
933
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
934
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
935
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
936
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
937
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
938
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
939
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
940
|
+
{"timestamp":1768312723218,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
941
|
+
{"timestamp":1768324809960,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
942
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
943
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
944
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
945
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
946
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
947
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
948
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
949
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
950
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
951
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
952
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
953
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
954
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
955
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
956
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
957
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
958
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
959
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
960
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
961
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
962
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
963
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
964
|
+
{"timestamp":1768324809961,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
965
|
+
{"timestamp":1768324903216,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
966
|
+
{"timestamp":1768324903216,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
967
|
+
{"timestamp":1768324903216,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
968
|
+
{"timestamp":1768324903216,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
969
|
+
{"timestamp":1768324903216,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
970
|
+
{"timestamp":1768324903216,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
971
|
+
{"timestamp":1768324903216,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
972
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
973
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
974
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
975
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
976
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
977
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
978
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
979
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
980
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
981
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
982
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
983
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
984
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
985
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
986
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
987
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
988
|
+
{"timestamp":1768324903217,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
package/scripts/hooks-system/application/services/installation/__tests__/McpConfigurator.mcp.spec.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const os = require('os');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const McpServerConfigBuilder = require('../mcp/McpServerConfigBuilder');
|
|
6
|
+
const McpProjectConfigWriter = require('../mcp/McpProjectConfigWriter');
|
|
7
|
+
|
|
8
|
+
describe('MCP installer (project-scoped)', () => {
|
|
9
|
+
let testRoot;
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
testRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'ast-hooks-mcp-'));
|
|
13
|
+
fs.mkdirSync(path.join(testRoot, 'scripts', 'hooks-system', 'infrastructure', 'mcp'), { recursive: true });
|
|
14
|
+
fs.writeFileSync(
|
|
15
|
+
path.join(testRoot, 'scripts', 'hooks-system', 'infrastructure', 'mcp', 'ast-intelligence-automation.js'),
|
|
16
|
+
'#!/usr/bin/env node\nprocess.stdin.resume();\n'
|
|
17
|
+
);
|
|
18
|
+
fs.writeFileSync(
|
|
19
|
+
path.join(testRoot, 'scripts', 'hooks-system', 'infrastructure', 'mcp', 'evidence-watcher.js'),
|
|
20
|
+
'#!/usr/bin/env node\nprocess.stdin.resume();\n'
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
afterEach(() => {
|
|
25
|
+
if (testRoot && fs.existsSync(testRoot)) {
|
|
26
|
+
fs.rmSync(testRoot, { recursive: true, force: true });
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should write Cursor and Windsurf MCP configs with automation + evidence watcher servers', () => {
|
|
31
|
+
const builder = new McpServerConfigBuilder(testRoot, null, null);
|
|
32
|
+
const { serverId, mcpConfig } = builder.build();
|
|
33
|
+
|
|
34
|
+
const writer = new McpProjectConfigWriter(testRoot, null, null, null, null);
|
|
35
|
+
writer.configureProjectScoped(mcpConfig, serverId);
|
|
36
|
+
|
|
37
|
+
const cursorPath = path.join(testRoot, '.cursor', 'mcp.json');
|
|
38
|
+
const windsurfPath = path.join(testRoot, '.windsurf', 'mcp.json');
|
|
39
|
+
|
|
40
|
+
expect(fs.existsSync(cursorPath)).toBe(true);
|
|
41
|
+
expect(fs.existsSync(windsurfPath)).toBe(true);
|
|
42
|
+
|
|
43
|
+
const cursor = JSON.parse(fs.readFileSync(cursorPath, 'utf8'));
|
|
44
|
+
const windsurf = JSON.parse(fs.readFileSync(windsurfPath, 'utf8'));
|
|
45
|
+
|
|
46
|
+
const cursorServers = Object.keys(cursor.mcpServers || {});
|
|
47
|
+
const windsurfServers = Object.keys(windsurf.mcpServers || {});
|
|
48
|
+
|
|
49
|
+
expect(cursorServers.some(id => id.startsWith('ast-intelligence-automation-'))).toBe(true);
|
|
50
|
+
expect(cursorServers.some(id => id.startsWith('ai-evidence-watcher-'))).toBe(true);
|
|
51
|
+
|
|
52
|
+
expect(windsurfServers.some(id => id.startsWith('ast-intelligence-automation-'))).toBe(true);
|
|
53
|
+
expect(windsurfServers.some(id => id.startsWith('ai-evidence-watcher-'))).toBe(true);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should be idempotent and not duplicate servers across runs', () => {
|
|
57
|
+
const builder = new McpServerConfigBuilder(testRoot, null, null);
|
|
58
|
+
const { serverId, mcpConfig } = builder.build();
|
|
59
|
+
|
|
60
|
+
const writer = new McpProjectConfigWriter(testRoot, null, null, null, null);
|
|
61
|
+
writer.configureProjectScoped(mcpConfig, serverId);
|
|
62
|
+
writer.configureProjectScoped(mcpConfig, serverId);
|
|
63
|
+
|
|
64
|
+
const cursorPath = path.join(testRoot, '.cursor', 'mcp.json');
|
|
65
|
+
const cursor = JSON.parse(fs.readFileSync(cursorPath, 'utf8'));
|
|
66
|
+
|
|
67
|
+
const ids = Object.keys(cursor.mcpServers || {});
|
|
68
|
+
const automation = ids.filter(id => id.startsWith('ast-intelligence-automation-'));
|
|
69
|
+
const evidence = ids.filter(id => id.startsWith('ai-evidence-watcher-'));
|
|
70
|
+
|
|
71
|
+
expect(automation.length).toBe(1);
|
|
72
|
+
expect(evidence.length).toBe(1);
|
|
73
|
+
});
|
|
74
|
+
});
|
package/scripts/hooks-system/application/services/installation/mcp/McpProjectConfigWriter.js
CHANGED
|
@@ -37,12 +37,24 @@ class McpProjectConfigWriter {
|
|
|
37
37
|
if (fs.existsSync(filePath)) {
|
|
38
38
|
const existing = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
39
39
|
if (!existing.mcpServers) existing.mcpServers = {};
|
|
40
|
+
|
|
41
|
+
const newServerIds = Object.keys(mcpConfig.mcpServers || {});
|
|
42
|
+
const prefixesToDedupe = ['ast-intelligence-automation-', 'ai-evidence-watcher-'];
|
|
43
|
+
|
|
40
44
|
Object.keys(existing.mcpServers).forEach(id => {
|
|
41
|
-
|
|
45
|
+
const shouldDedupe = prefixesToDedupe.some(prefix => id.startsWith(prefix));
|
|
46
|
+
if (!shouldDedupe) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!newServerIds.includes(id)) {
|
|
42
51
|
delete existing.mcpServers[id];
|
|
43
52
|
}
|
|
44
53
|
});
|
|
45
|
-
|
|
54
|
+
|
|
55
|
+
newServerIds.forEach(id => {
|
|
56
|
+
existing.mcpServers[id] = mcpConfig.mcpServers[id];
|
|
57
|
+
});
|
|
46
58
|
finalConfig = existing;
|
|
47
59
|
}
|
|
48
60
|
|
package/scripts/hooks-system/application/services/installation/mcp/McpServerConfigBuilder.js
CHANGED
|
@@ -22,7 +22,9 @@ class McpServerConfigBuilder {
|
|
|
22
22
|
|
|
23
23
|
build() {
|
|
24
24
|
const serverId = this.computeServerIdForRepo(this.targetRoot);
|
|
25
|
+
const evidenceWatcherServerId = this.computeEvidenceWatcherServerIdForRepo(this.targetRoot);
|
|
25
26
|
const entrypoint = this.resolveAutomationEntrypoint();
|
|
27
|
+
const evidenceEntrypoint = this.resolveEvidenceWatcherEntrypoint();
|
|
26
28
|
const nodePath = this.resolveNodeBinary();
|
|
27
29
|
|
|
28
30
|
const mcpConfig = {
|
|
@@ -36,6 +38,14 @@ class McpServerConfigBuilder {
|
|
|
36
38
|
AUTO_PUSH_ENABLED: 'false',
|
|
37
39
|
AUTO_PR_ENABLED: 'false'
|
|
38
40
|
}
|
|
41
|
+
},
|
|
42
|
+
[evidenceWatcherServerId]: {
|
|
43
|
+
command: nodePath,
|
|
44
|
+
args: [evidenceEntrypoint],
|
|
45
|
+
env: {
|
|
46
|
+
REPO_ROOT: this.targetRoot,
|
|
47
|
+
MCP_MAC_NOTIFICATIONS: 'true'
|
|
48
|
+
}
|
|
39
49
|
}
|
|
40
50
|
}
|
|
41
51
|
};
|
|
@@ -62,6 +72,25 @@ class McpServerConfigBuilder {
|
|
|
62
72
|
return path.join(this.targetRoot, 'scripts/hooks-system/infrastructure/mcp/ast-intelligence-automation.js');
|
|
63
73
|
}
|
|
64
74
|
|
|
75
|
+
resolveEvidenceWatcherEntrypoint() {
|
|
76
|
+
const candidates = [
|
|
77
|
+
this.hookSystemRoot
|
|
78
|
+
? path.join(this.hookSystemRoot, 'infrastructure', 'mcp', 'evidence-watcher.js')
|
|
79
|
+
: null,
|
|
80
|
+
path.join(this.targetRoot, 'scripts', 'hooks-system', 'infrastructure', 'mcp', 'evidence-watcher.js')
|
|
81
|
+
].filter(Boolean);
|
|
82
|
+
|
|
83
|
+
for (const candidate of candidates) {
|
|
84
|
+
try {
|
|
85
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
86
|
+
} catch (error) {
|
|
87
|
+
this.logger?.warn?.('MCP_EVIDENCE_ENTRYPOINT_CHECK_FAILED', { candidate, error: error.message });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return path.join(this.targetRoot, 'scripts/hooks-system/infrastructure/mcp/evidence-watcher.js');
|
|
92
|
+
}
|
|
93
|
+
|
|
65
94
|
resolveNodeBinary() {
|
|
66
95
|
let nodePath = process.execPath;
|
|
67
96
|
if (nodePath && fs.existsSync(nodePath)) return nodePath;
|
|
@@ -87,6 +116,17 @@ class McpServerConfigBuilder {
|
|
|
87
116
|
return `${legacyServerId}-${slug}-${fp}`;
|
|
88
117
|
}
|
|
89
118
|
|
|
119
|
+
computeEvidenceWatcherServerIdForRepo(repoRoot) {
|
|
120
|
+
const legacyServerId = 'ai-evidence-watcher';
|
|
121
|
+
const forced = (env.get('MCP_EVIDENCE_SERVER_ID', '') || '').trim();
|
|
122
|
+
if (forced.length > 0) return forced;
|
|
123
|
+
|
|
124
|
+
const repoName = path.basename(repoRoot || process.cwd());
|
|
125
|
+
const slug = slugifyId(repoName) || 'repo';
|
|
126
|
+
const fp = this.computeRepoFingerprint(repoRoot);
|
|
127
|
+
return `${legacyServerId}-${slug}-${fp}`;
|
|
128
|
+
}
|
|
129
|
+
|
|
90
130
|
computeRepoFingerprint(repoRoot) {
|
|
91
131
|
try {
|
|
92
132
|
const real = fs.realpathSync(repoRoot);
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
const env = require('../../config/env');
|
|
10
|
+
const fs = require('fs');
|
|
10
11
|
const path = require('path');
|
|
12
|
+
const { exec } = require('child_process');
|
|
11
13
|
const McpProtocolHandler = require('./services/McpProtocolHandler');
|
|
12
14
|
const EvidenceService = require('./services/EvidenceService');
|
|
13
15
|
const UnifiedLogger = require('../../application/services/logging/UnifiedLogger');
|
|
@@ -15,6 +17,9 @@ const UnifiedLogger = require('../../application/services/logging/UnifiedLogger'
|
|
|
15
17
|
const MCP_VERSION = '1.0.0';
|
|
16
18
|
const MAX_EVIDENCE_AGE = 3 * 60 * 1000;
|
|
17
19
|
|
|
20
|
+
const NOTIFICATION_COOLDOWN_MS = 3000;
|
|
21
|
+
let lastNotificationAt = 0;
|
|
22
|
+
|
|
18
23
|
// Initialize Logger
|
|
19
24
|
const repoRoot = process.env.REPO_ROOT || process.cwd();
|
|
20
25
|
const logger = new UnifiedLogger({
|
|
@@ -30,6 +35,45 @@ const logger = new UnifiedLogger({
|
|
|
30
35
|
const evidenceService = new EvidenceService(repoRoot, logger);
|
|
31
36
|
const protocolHandler = new McpProtocolHandler(process.stdin, process.stdout, logger);
|
|
32
37
|
|
|
38
|
+
const evidenceFilePath = path.join(repoRoot, '.AI_EVIDENCE.json');
|
|
39
|
+
|
|
40
|
+
const enableMacNotifications = String(process.env.MCP_MAC_NOTIFICATIONS || '').trim().toLowerCase() === 'true';
|
|
41
|
+
const sendMacNotification = (title, message) => {
|
|
42
|
+
if (!enableMacNotifications) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const safeTitle = String(title).replace(/"/g, '\\"');
|
|
47
|
+
const safeMessage = String(message).replace(/"/g, '\\"');
|
|
48
|
+
exec(`osascript -e "display notification \"${safeMessage}\" with title \"${safeTitle}\""`, {
|
|
49
|
+
env: process.env
|
|
50
|
+
}, () => {
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const notifyEvidenceChanged = () => {
|
|
55
|
+
const now = Date.now();
|
|
56
|
+
if (now - lastNotificationAt < NOTIFICATION_COOLDOWN_MS) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
lastNotificationAt = now;
|
|
61
|
+
const status = evidenceService.checkStatus();
|
|
62
|
+
const message = `🤖 AI Evidence Updated: ${status.status}`;
|
|
63
|
+
protocolHandler.sendNotificationMessage('info', message);
|
|
64
|
+
sendMacNotification('AI Evidence Updated', message);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
fs.watch(evidenceFilePath, { persistent: true }, (eventType) => {
|
|
69
|
+
if (eventType === 'change' || eventType === 'rename') {
|
|
70
|
+
notifyEvidenceChanged();
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
} catch (err) {
|
|
74
|
+
if (logger) logger.warn('EVIDENCE_WATCHER_ERROR', { error: err.message });
|
|
75
|
+
}
|
|
76
|
+
|
|
33
77
|
if (logger) logger.info('MCP_SERVER_STARTED');
|
|
34
78
|
|
|
35
79
|
protocolHandler.start((message) => {
|
|
@@ -12,6 +12,23 @@ class McpProtocolHandler {
|
|
|
12
12
|
this.buffer = Buffer.alloc(0);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
sendNotificationMessage(level, message) {
|
|
16
|
+
const payload = {
|
|
17
|
+
jsonrpc: '2.0',
|
|
18
|
+
method: 'notifications/message',
|
|
19
|
+
params: {
|
|
20
|
+
level,
|
|
21
|
+
message
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
this.outputStream.write(JSON.stringify(payload) + '\n');
|
|
26
|
+
|
|
27
|
+
if (typeof this.outputStream.flush === 'function') {
|
|
28
|
+
this.outputStream.flush();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
15
32
|
start(messageHandler) {
|
|
16
33
|
if (process.env.DEBUG) {
|
|
17
34
|
process.stderr.write('[MCP] Protocol handler starting...\n');
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const { PassThrough } = require('stream');
|
|
2
|
+
|
|
3
|
+
const McpProtocolHandler = require('../McpProtocolHandler');
|
|
4
|
+
|
|
5
|
+
describe('McpProtocolHandler notifications', () => {
|
|
6
|
+
it('should write notifications/message to output stream', async () => {
|
|
7
|
+
const input = new PassThrough();
|
|
8
|
+
const output = new PassThrough();
|
|
9
|
+
|
|
10
|
+
const handler = new McpProtocolHandler(input, output, null);
|
|
11
|
+
|
|
12
|
+
handler.sendNotificationMessage('info', 'Evidence updated');
|
|
13
|
+
|
|
14
|
+
const written = output.read().toString('utf8').trim();
|
|
15
|
+
const parsed = JSON.parse(written);
|
|
16
|
+
|
|
17
|
+
expect(parsed.jsonrpc).toBe('2.0');
|
|
18
|
+
expect(parsed.method).toBe('notifications/message');
|
|
19
|
+
expect(parsed.params.level).toBe('info');
|
|
20
|
+
expect(parsed.params.message).toBe('Evidence updated');
|
|
21
|
+
});
|
|
22
|
+
});
|
package/scripts/hooks-system/infrastructure/watchdog/__tests__/.audit-reports/token-monitor.log
CHANGED
|
@@ -73,3 +73,18 @@
|
|
|
73
73
|
{"timestamp":"2026-01-13T11:31:02.359Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"ok","percentUsed":10,"tokensUsed":100000,"maxTokens":1000000,"source":"realtime","stale":false},"context":{"message":"Result level=ok percent=10% used=100000/1000000 source=realtime"}}
|
|
74
74
|
{"timestamp":"2026-01-13T11:31:02.360Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"warning","percentUsed":91,"tokensUsed":910000,"maxTokens":1000000,"source":"fallback","stale":false},"context":{"message":"Result level=warning percent=91% used=910000/1000000 source=fallback"}}
|
|
75
75
|
{"timestamp":"2026-01-13T11:31:02.360Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"critical","percentUsed":98,"tokensUsed":980000,"maxTokens":1000000,"source":"realtime","stale":true},"context":{"message":"Result level=critical percent=98% used=980000/1000000 source=realtime (stale)"}}
|
|
76
|
+
{"timestamp":"2026-01-13T13:12:20.560Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"ok","percentUsed":10,"tokensUsed":100000,"maxTokens":1000000,"source":"realtime","stale":false},"context":{"message":"Result level=ok percent=10% used=100000/1000000 source=realtime"}}
|
|
77
|
+
{"timestamp":"2026-01-13T13:12:20.561Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"warning","percentUsed":91,"tokensUsed":910000,"maxTokens":1000000,"source":"fallback","stale":false},"context":{"message":"Result level=warning percent=91% used=910000/1000000 source=fallback"}}
|
|
78
|
+
{"timestamp":"2026-01-13T13:12:20.561Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"critical","percentUsed":98,"tokensUsed":980000,"maxTokens":1000000,"source":"realtime","stale":true},"context":{"message":"Result level=critical percent=98% used=980000/1000000 source=realtime (stale)"}}
|
|
79
|
+
{"timestamp":"2026-01-13T13:23:57.658Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"ok","percentUsed":10,"tokensUsed":100000,"maxTokens":1000000,"source":"realtime","stale":false},"context":{"message":"Result level=ok percent=10% used=100000/1000000 source=realtime"}}
|
|
80
|
+
{"timestamp":"2026-01-13T13:23:57.659Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"warning","percentUsed":91,"tokensUsed":910000,"maxTokens":1000000,"source":"fallback","stale":false},"context":{"message":"Result level=warning percent=91% used=910000/1000000 source=fallback"}}
|
|
81
|
+
{"timestamp":"2026-01-13T13:23:57.659Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"critical","percentUsed":98,"tokensUsed":980000,"maxTokens":1000000,"source":"realtime","stale":true},"context":{"message":"Result level=critical percent=98% used=980000/1000000 source=realtime (stale)"}}
|
|
82
|
+
{"timestamp":"2026-01-13T13:58:44.971Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"ok","percentUsed":10,"tokensUsed":100000,"maxTokens":1000000,"source":"realtime","stale":false},"context":{"message":"Result level=ok percent=10% used=100000/1000000 source=realtime"}}
|
|
83
|
+
{"timestamp":"2026-01-13T13:58:44.971Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"warning","percentUsed":91,"tokensUsed":910000,"maxTokens":1000000,"source":"fallback","stale":false},"context":{"message":"Result level=warning percent=91% used=910000/1000000 source=fallback"}}
|
|
84
|
+
{"timestamp":"2026-01-13T13:58:44.971Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"critical","percentUsed":98,"tokensUsed":980000,"maxTokens":1000000,"source":"realtime","stale":true},"context":{"message":"Result level=critical percent=98% used=980000/1000000 source=realtime (stale)"}}
|
|
85
|
+
{"timestamp":"2026-01-13T17:20:11.876Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"ok","percentUsed":10,"tokensUsed":100000,"maxTokens":1000000,"source":"realtime","stale":false},"context":{"message":"Result level=ok percent=10% used=100000/1000000 source=realtime"}}
|
|
86
|
+
{"timestamp":"2026-01-13T17:20:11.877Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"warning","percentUsed":91,"tokensUsed":910000,"maxTokens":1000000,"source":"fallback","stale":false},"context":{"message":"Result level=warning percent=91% used=910000/1000000 source=fallback"}}
|
|
87
|
+
{"timestamp":"2026-01-13T17:20:11.877Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"critical","percentUsed":98,"tokensUsed":980000,"maxTokens":1000000,"source":"realtime","stale":true},"context":{"message":"Result level=critical percent=98% used=980000/1000000 source=realtime (stale)"}}
|
|
88
|
+
{"timestamp":"2026-01-13T17:21:44.693Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"ok","percentUsed":10,"tokensUsed":100000,"maxTokens":1000000,"source":"realtime","stale":false},"context":{"message":"Result level=ok percent=10% used=100000/1000000 source=realtime"}}
|
|
89
|
+
{"timestamp":"2026-01-13T17:21:44.695Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"warning","percentUsed":91,"tokensUsed":910000,"maxTokens":1000000,"source":"fallback","stale":false},"context":{"message":"Result level=warning percent=91% used=910000/1000000 source=fallback"}}
|
|
90
|
+
{"timestamp":"2026-01-13T17:21:44.695Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"critical","percentUsed":98,"tokensUsed":980000,"maxTokens":1000000,"source":"realtime","stale":true},"context":{"message":"Result level=critical percent=98% used=980000/1000000 source=realtime (stale)"}}
|