pumuki-ast-hooks 6.3.2 → 6.3.3
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/README.md +2 -0
- package/docs/RELEASE_NOTES.md +20 -0
- package/package.json +1 -1
- 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 +132 -0
- package/scripts/hooks-system/application/__tests__/CompositionRoot.spec.js +0 -9
- package/scripts/hooks-system/application/services/__tests__/GitTreeState.spec.js +9 -8
- package/scripts/hooks-system/application/services/__tests__/IntelligentGitTreeMonitor.spec.js +64 -73
- package/scripts/hooks-system/application/services/__tests__/PlaybookRunner.spec.js +12 -14
- package/scripts/hooks-system/infrastructure/ast/archive/swift-analyzer.js +4 -1
- package/scripts/hooks-system/infrastructure/ast/backend/ast-backend.js +7 -7
- package/scripts/hooks-system/infrastructure/ast/common/rules/WorkflowRules.js +4 -2
- package/scripts/hooks-system/infrastructure/ast/text/text-scanner.js +4 -2
- package/scripts/hooks-system/infrastructure/core/__tests__/GitOperations.spec.js +29 -28
- package/scripts/hooks-system/infrastructure/orchestration/intelligent-audit.js +5 -3
- package/scripts/hooks-system/infrastructure/watchdog/__tests__/.audit-reports/token-monitor.log +12 -0
package/README.md
CHANGED
|
@@ -11,6 +11,8 @@ Portable, project‑agnostic, multi‑platform enterprise framework to govern AI
|
|
|
11
11
|

|
|
12
12
|

|
|
13
13
|
|
|
14
|
+
Latest release: 6.3.3 (2026-01-28)
|
|
15
|
+
|
|
14
16
|
---
|
|
15
17
|
|
|
16
18
|
## Quick start (30–60s)
|
package/docs/RELEASE_NOTES.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
# Release Notes - v6.3.3
|
|
2
|
+
|
|
3
|
+
**Release Date**: January 28, 2026
|
|
4
|
+
**Type**: Patch Release
|
|
5
|
+
**Compatibility**: Fully backward compatible with 6.3.x
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## ✅ Fixes
|
|
10
|
+
|
|
11
|
+
- **iOS false positives**: `ios.weak_self` ahora detecta capture lists con `weak/unowned self`.
|
|
12
|
+
- **Task cancellation**: `ios.concurrency.task_cancellation` reconoce `Task.isCancelled` y `Task.checkCancellation` (incl. `try?`).
|
|
13
|
+
- **BDD triad**: `workflow.triad.tests_without_implementation` respeta la cabecera `Implementation:` en `.feature`.
|
|
14
|
+
- **Gate evidence**: `ai_gate` no bloquea por violaciones solo MEDIUM/LOW en la evidencia.
|
|
15
|
+
- **Protocol Q2**: la respuesta incluye referencia a commits recientes.
|
|
16
|
+
- **Backend config**: `backend.config.missing_validation` se aplica solo a apps backend reales.
|
|
17
|
+
- **WorkflowRules**: `AUDIT_LIBRARY_SELF` se valida con `env.getBool`.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
1
21
|
# Release Notes - v6.0.16
|
|
2
22
|
|
|
3
23
|
**Release Date**: January 13, 2026
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumuki-ast-hooks",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.3",
|
|
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": {
|
|
@@ -62,3 +62,8 @@
|
|
|
62
62
|
{"timestamp":"2026-01-26T16:02:19.123Z","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":{}}
|
|
63
63
|
{"timestamp":"2026-01-26T16:20:32.268Z","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":{}}
|
|
64
64
|
{"timestamp":"2026-01-26T19:01:57.880Z","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":{}}
|
|
65
|
+
{"timestamp":"2026-01-28T18:12:43.061Z","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":{}}
|
|
66
|
+
{"timestamp":"2026-01-28T18:37:05.469Z","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":{}}
|
|
67
|
+
{"timestamp":"2026-01-28T18:48:21.937Z","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":{}}
|
|
68
|
+
{"timestamp":"2026-01-28T18:51:11.719Z","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":{}}
|
|
69
|
+
{"timestamp":"2026-01-28T18:59:57.949Z","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":{}}
|
|
@@ -258,3 +258,23 @@
|
|
|
258
258
|
{"timestamp":"2026-01-26T19:01:57.651Z","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":{}}
|
|
259
259
|
{"timestamp":"2026-01-26T19:01:57.651Z","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":{}}
|
|
260
260
|
{"timestamp":"2026-01-26T19:01:57.651Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
|
|
261
|
+
{"timestamp":"2026-01-28T18:12:42.463Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_START","data":{"repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"},"context":{}}
|
|
262
|
+
{"timestamp":"2026-01-28T18:12:42.468Z","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":{}}
|
|
263
|
+
{"timestamp":"2026-01-28T18:12:42.468Z","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":{}}
|
|
264
|
+
{"timestamp":"2026-01-28T18:12:42.468Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
|
|
265
|
+
{"timestamp":"2026-01-28T18:37:05.512Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_START","data":{"repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"},"context":{}}
|
|
266
|
+
{"timestamp":"2026-01-28T18:37:05.516Z","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":{}}
|
|
267
|
+
{"timestamp":"2026-01-28T18:37:05.517Z","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":{}}
|
|
268
|
+
{"timestamp":"2026-01-28T18:37:05.517Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
|
|
269
|
+
{"timestamp":"2026-01-28T18:48:22.127Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_START","data":{"repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"},"context":{}}
|
|
270
|
+
{"timestamp":"2026-01-28T18:48:22.132Z","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":{}}
|
|
271
|
+
{"timestamp":"2026-01-28T18:48:22.132Z","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":{}}
|
|
272
|
+
{"timestamp":"2026-01-28T18:48:22.132Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
|
|
273
|
+
{"timestamp":"2026-01-28T18:51:11.902Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_START","data":{"repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"},"context":{}}
|
|
274
|
+
{"timestamp":"2026-01-28T18:51:11.906Z","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":{}}
|
|
275
|
+
{"timestamp":"2026-01-28T18:51:11.907Z","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":{}}
|
|
276
|
+
{"timestamp":"2026-01-28T18:51:11.907Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
|
|
277
|
+
{"timestamp":"2026-01-28T18:59:57.992Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_START","data":{"repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"},"context":{}}
|
|
278
|
+
{"timestamp":"2026-01-28T18:59:57.996Z","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":{}}
|
|
279
|
+
{"timestamp":"2026-01-28T18:59:57.996Z","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":{}}
|
|
280
|
+
{"timestamp":"2026-01-28T18:59:57.996Z","level":"info","component":"InstallWizard","event":"INSTALL_WIZARD_COMPLETED","data":{},"context":{}}
|
|
@@ -1922,3 +1922,135 @@
|
|
|
1922
1922
|
{"timestamp":1769454140085,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1923
1923
|
{"timestamp":1769454140085,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1924
1924
|
{"timestamp":1769454140085,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1925
|
+
{"timestamp":1769622061973,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1926
|
+
{"timestamp":1769622061974,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1927
|
+
{"timestamp":1769622061974,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1928
|
+
{"timestamp":1769622061974,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1929
|
+
{"timestamp":1769623963059,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1930
|
+
{"timestamp":1769623963060,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1931
|
+
{"timestamp":1769623963060,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1932
|
+
{"timestamp":1769623963060,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1933
|
+
{"timestamp":1769623963060,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1934
|
+
{"timestamp":1769623963060,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1935
|
+
{"timestamp":1769623963060,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1936
|
+
{"timestamp":1769623963060,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1937
|
+
{"timestamp":1769623963060,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1938
|
+
{"timestamp":1769623963060,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1939
|
+
{"timestamp":1769623963060,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1940
|
+
{"timestamp":1769623963060,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1941
|
+
{"timestamp":1769623963060,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1942
|
+
{"timestamp":1769623963060,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1943
|
+
{"timestamp":1769623963060,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1944
|
+
{"timestamp":1769623963061,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1945
|
+
{"timestamp":1769623963061,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1946
|
+
{"timestamp":1769623963061,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1947
|
+
{"timestamp":1769623963061,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1948
|
+
{"timestamp":1769623963061,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1949
|
+
{"timestamp":1769623963061,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1950
|
+
{"timestamp":1769623963061,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1951
|
+
{"timestamp":1769623963061,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1952
|
+
{"timestamp":1769623963061,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1953
|
+
{"timestamp":1769625425468,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1954
|
+
{"timestamp":1769625425468,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1955
|
+
{"timestamp":1769625425468,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1956
|
+
{"timestamp":1769625425468,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1957
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1958
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1959
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1960
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1961
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1962
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1963
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1964
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1965
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1966
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1967
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1968
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1969
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1970
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1971
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1972
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1973
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1974
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1975
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1976
|
+
{"timestamp":1769625425469,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1977
|
+
{"timestamp":1769625560836,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1978
|
+
{"timestamp":1769625560836,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1979
|
+
{"timestamp":1769625560836,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1980
|
+
{"timestamp":1769625560836,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1981
|
+
{"timestamp":1769626101936,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1982
|
+
{"timestamp":1769626101936,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1983
|
+
{"timestamp":1769626101936,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1984
|
+
{"timestamp":1769626101936,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1985
|
+
{"timestamp":1769626101936,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1986
|
+
{"timestamp":1769626101936,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1987
|
+
{"timestamp":1769626101936,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1988
|
+
{"timestamp":1769626101936,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1989
|
+
{"timestamp":1769626101936,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1990
|
+
{"timestamp":1769626101936,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1991
|
+
{"timestamp":1769626101936,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1992
|
+
{"timestamp":1769626101936,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1993
|
+
{"timestamp":1769626101936,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1994
|
+
{"timestamp":1769626101936,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1995
|
+
{"timestamp":1769626101936,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
1996
|
+
{"timestamp":1769626101936,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1997
|
+
{"timestamp":1769626101937,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
1998
|
+
{"timestamp":1769626101937,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
1999
|
+
{"timestamp":1769626101937,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
2000
|
+
{"timestamp":1769626101937,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2001
|
+
{"timestamp":1769626101937,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2002
|
+
{"timestamp":1769626101937,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
2003
|
+
{"timestamp":1769626101937,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
2004
|
+
{"timestamp":1769626101937,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2005
|
+
{"timestamp":1769626271718,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2006
|
+
{"timestamp":1769626271718,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
2007
|
+
{"timestamp":1769626271718,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
2008
|
+
{"timestamp":1769626271718,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2009
|
+
{"timestamp":1769626271718,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2010
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
2011
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
2012
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2013
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2014
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
2015
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
2016
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2017
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2018
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
2019
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
2020
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2021
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2022
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
2023
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
2024
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2025
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2026
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
2027
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
2028
|
+
{"timestamp":1769626271719,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2029
|
+
{"timestamp":1769626797948,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2030
|
+
{"timestamp":1769626797948,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
2031
|
+
{"timestamp":1769626797948,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
2032
|
+
{"timestamp":1769626797948,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2033
|
+
{"timestamp":1769626797948,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2034
|
+
{"timestamp":1769626797948,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
2035
|
+
{"timestamp":1769626797948,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
2036
|
+
{"timestamp":1769626797948,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2037
|
+
{"timestamp":1769626797948,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2038
|
+
{"timestamp":1769626797948,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
2039
|
+
{"timestamp":1769626797948,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
2040
|
+
{"timestamp":1769626797948,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2041
|
+
{"timestamp":1769626797948,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2042
|
+
{"timestamp":1769626797949,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
2043
|
+
{"timestamp":1769626797949,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
2044
|
+
{"timestamp":1769626797949,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2045
|
+
{"timestamp":1769626797949,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2046
|
+
{"timestamp":1769626797949,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
2047
|
+
{"timestamp":1769626797949,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
2048
|
+
{"timestamp":1769626797949,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2049
|
+
{"timestamp":1769626797949,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2050
|
+
{"timestamp":1769626797949,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
2051
|
+
{"timestamp":1769626797949,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
2052
|
+
{"timestamp":1769626797949,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2053
|
+
{"timestamp":1769627021261,"hook":"audit_logger","operation":"constructor","status":"started","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
2054
|
+
{"timestamp":1769627021261,"hook":"audit_logger","operation":"ensure_dir","status":"started"}
|
|
2055
|
+
{"timestamp":1769627021261,"hook":"audit_logger","operation":"ensure_dir","status":"success"}
|
|
2056
|
+
{"timestamp":1769627021261,"hook":"audit_logger","operation":"constructor","status":"success","repoRoot":"/Users/juancarlosmerlosalbarracin/Developer/Projects/ast-intelligence-hooks/scripts/hooks-system"}
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
jest.mock('../../infrastructure/adapters/MacOSNotificationAdapter');
|
|
2
|
-
jest.mock('../../infrastructure/adapters/FileEvidenceAdapter');
|
|
3
|
-
jest.mock('../../infrastructure/adapters/GitQueryAdapter');
|
|
4
|
-
jest.mock('../../infrastructure/adapters/GitCommandAdapter');
|
|
5
|
-
jest.mock('../../infrastructure/adapters/GitHubCliAdapter');
|
|
6
|
-
jest.mock('../../infrastructure/adapters/AstAnalyzerAdapter');
|
|
7
|
-
jest.mock('../services/AutonomousOrchestrator');
|
|
8
|
-
jest.mock('../services/ContextDetectionEngine');
|
|
9
|
-
|
|
10
1
|
const CompositionRoot = require('../CompositionRoot');
|
|
11
2
|
|
|
12
3
|
describe('CompositionRoot', () => {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
jest.mock('child_process', () => ({
|
|
2
|
-
execSync: jest.fn(),
|
|
3
|
-
}));
|
|
4
|
-
|
|
5
1
|
const childProcess = require('child_process');
|
|
6
|
-
|
|
2
|
+
let getGitTreeState;
|
|
3
|
+
let isTreeBeyondLimit;
|
|
4
|
+
let summarizeTreeState;
|
|
5
|
+
let execSyncSpy;
|
|
7
6
|
|
|
8
7
|
function makeMockGitStatus(stagedFiles = [], workingFiles = [], untrackedFiles = []) {
|
|
9
8
|
const lines = [];
|
|
@@ -21,11 +20,14 @@ function makeMockGitStatus(stagedFiles = [], workingFiles = [], untrackedFiles =
|
|
|
21
20
|
|
|
22
21
|
describe('GitTreeState', () => {
|
|
23
22
|
beforeEach(() => {
|
|
24
|
-
|
|
23
|
+
jest.resetModules();
|
|
24
|
+
execSyncSpy = jest.spyOn(childProcess, 'execSync');
|
|
25
|
+
execSyncSpy.mockReset();
|
|
26
|
+
({ getGitTreeState, isTreeBeyondLimit, summarizeTreeState } = require('../GitTreeState'));
|
|
25
27
|
});
|
|
26
28
|
|
|
27
29
|
afterEach(() => {
|
|
28
|
-
|
|
30
|
+
execSyncSpy.mockRestore();
|
|
29
31
|
});
|
|
30
32
|
|
|
31
33
|
describe('getGitTreeState', () => {
|
|
@@ -166,4 +168,3 @@ describe('GitTreeState', () => {
|
|
|
166
168
|
});
|
|
167
169
|
});
|
|
168
170
|
});
|
|
169
|
-
|
package/scripts/hooks-system/application/services/__tests__/IntelligentGitTreeMonitor.spec.js
CHANGED
|
@@ -1,21 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
jest.mock('../IntelligentCommitAnalyzer');
|
|
15
|
-
|
|
16
|
-
const IntelligentGitTreeMonitor = require('../IntelligentGitTreeMonitor');
|
|
17
|
-
const IntelligentCommitAnalyzer = require('../IntelligentCommitAnalyzer');
|
|
18
|
-
const { getGitTreeState } = require('../GitTreeState');
|
|
1
|
+
const childProcess = require('child_process');
|
|
2
|
+
|
|
3
|
+
let AuditLogger;
|
|
4
|
+
let IntelligentGitTreeMonitor;
|
|
5
|
+
let IntelligentCommitAnalyzer;
|
|
6
|
+
let execSyncSpy;
|
|
7
|
+
let analyzeAndSuggestCommitsSpy;
|
|
8
|
+
let getReadyCommitsSpy;
|
|
9
|
+
let getNeedsAttentionSpy;
|
|
10
|
+
let ensureDirSpy;
|
|
11
|
+
let recordSpy;
|
|
19
12
|
|
|
20
13
|
function makeSUT(options = {}) {
|
|
21
14
|
const defaultOptions = {
|
|
@@ -28,17 +21,38 @@ function makeSUT(options = {}) {
|
|
|
28
21
|
return new IntelligentGitTreeMonitor(defaultOptions);
|
|
29
22
|
}
|
|
30
23
|
|
|
24
|
+
function buildGitStatusOutput({ staged = [], working = [], untracked = [] } = {}) {
|
|
25
|
+
const stagedLines = staged.map(file => `A ${file}`);
|
|
26
|
+
const workingLines = working.map(file => ` M ${file}`);
|
|
27
|
+
const untrackedLines = untracked.map(file => `?? ${file}`);
|
|
28
|
+
return [...stagedLines, ...workingLines, ...untrackedLines].join('\n');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
31
|
describe('IntelligentGitTreeMonitor', () => {
|
|
32
32
|
beforeEach(() => {
|
|
33
|
-
jest.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
IntelligentCommitAnalyzer
|
|
33
|
+
jest.resetModules();
|
|
34
|
+
execSyncSpy = jest.spyOn(childProcess, 'execSync');
|
|
35
|
+
execSyncSpy.mockReset();
|
|
36
|
+
AuditLogger = require('../logging/AuditLogger');
|
|
37
|
+
IntelligentCommitAnalyzer = require('../IntelligentCommitAnalyzer');
|
|
38
|
+
IntelligentGitTreeMonitor = require('../IntelligentGitTreeMonitor');
|
|
39
|
+
analyzeAndSuggestCommitsSpy = jest.spyOn(IntelligentCommitAnalyzer.prototype, 'analyzeAndSuggestCommits');
|
|
40
|
+
getReadyCommitsSpy = jest.spyOn(IntelligentCommitAnalyzer.prototype, 'getReadyCommits');
|
|
41
|
+
getNeedsAttentionSpy = jest.spyOn(IntelligentCommitAnalyzer.prototype, 'getNeedsAttention');
|
|
42
|
+
ensureDirSpy = jest.spyOn(AuditLogger.prototype, 'ensureDir').mockImplementation(() => {});
|
|
43
|
+
recordSpy = jest.spyOn(AuditLogger.prototype, 'record').mockImplementation(() => {});
|
|
44
|
+
analyzeAndSuggestCommitsSpy.mockResolvedValue([]);
|
|
45
|
+
getReadyCommitsSpy.mockReturnValue([]);
|
|
46
|
+
getNeedsAttentionSpy.mockReturnValue([]);
|
|
38
47
|
});
|
|
39
48
|
|
|
40
49
|
afterEach(() => {
|
|
41
|
-
|
|
50
|
+
execSyncSpy.mockRestore();
|
|
51
|
+
analyzeAndSuggestCommitsSpy.mockRestore();
|
|
52
|
+
getReadyCommitsSpy.mockRestore();
|
|
53
|
+
getNeedsAttentionSpy.mockRestore();
|
|
54
|
+
ensureDirSpy.mockRestore();
|
|
55
|
+
recordSpy.mockRestore();
|
|
42
56
|
});
|
|
43
57
|
|
|
44
58
|
describe('constructor', () => {
|
|
@@ -65,14 +79,7 @@ describe('IntelligentGitTreeMonitor', () => {
|
|
|
65
79
|
|
|
66
80
|
describe('analyze', () => {
|
|
67
81
|
it('should return clean action when git tree is clean', async () => {
|
|
68
|
-
|
|
69
|
-
uniqueCount: 0,
|
|
70
|
-
stagedFiles: [],
|
|
71
|
-
workingFiles: [],
|
|
72
|
-
});
|
|
73
|
-
IntelligentCommitAnalyzer.prototype.analyzeAndSuggestCommits.mockResolvedValue([]);
|
|
74
|
-
IntelligentCommitAnalyzer.prototype.getReadyCommits.mockReturnValue([]);
|
|
75
|
-
IntelligentCommitAnalyzer.prototype.getNeedsAttention.mockReturnValue([]);
|
|
82
|
+
execSyncSpy.mockReturnValue('');
|
|
76
83
|
const monitor = makeSUT();
|
|
77
84
|
const result = await monitor.analyze();
|
|
78
85
|
expect(result.action).toBe('clean');
|
|
@@ -89,15 +96,13 @@ describe('IntelligentGitTreeMonitor', () => {
|
|
|
89
96
|
platform: 'backend',
|
|
90
97
|
},
|
|
91
98
|
];
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
99
|
+
analyzeAndSuggestCommitsSpy.mockResolvedValue([]);
|
|
100
|
+
getReadyCommitsSpy.mockReturnValue(mockReadyCommits);
|
|
101
|
+
getNeedsAttentionSpy.mockReturnValue([]);
|
|
95
102
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
workingFiles: ['file2.ts'],
|
|
100
|
-
});
|
|
103
|
+
execSyncSpy.mockReturnValue(
|
|
104
|
+
buildGitStatusOutput({ staged: ['file1.ts'], working: ['file2.ts'] })
|
|
105
|
+
);
|
|
101
106
|
|
|
102
107
|
const monitor = makeSUT();
|
|
103
108
|
const result = await monitor.analyze();
|
|
@@ -113,15 +118,13 @@ describe('IntelligentGitTreeMonitor', () => {
|
|
|
113
118
|
files: [`file${i}.ts`],
|
|
114
119
|
fileCount: 1,
|
|
115
120
|
}));
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
121
|
+
analyzeAndSuggestCommitsSpy.mockResolvedValue(manySuggestions);
|
|
122
|
+
getReadyCommitsSpy.mockReturnValue([]);
|
|
123
|
+
getNeedsAttentionSpy.mockReturnValue([]);
|
|
119
124
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
workingFiles: Array.from({ length: 15 }, (_, i) => `file${i}.ts`),
|
|
124
|
-
});
|
|
125
|
+
execSyncSpy.mockReturnValue(
|
|
126
|
+
buildGitStatusOutput({ working: Array.from({ length: 15 }, (_, i) => `file${i}.ts`) })
|
|
127
|
+
);
|
|
125
128
|
|
|
126
129
|
const monitor = makeSUT();
|
|
127
130
|
const result = await monitor.analyze();
|
|
@@ -135,15 +138,13 @@ describe('IntelligentGitTreeMonitor', () => {
|
|
|
135
138
|
{ feature: 'feature-a', files: ['file1.ts'], fileCount: 1 },
|
|
136
139
|
{ feature: 'feature-b', files: ['file2.ts'], fileCount: 1 },
|
|
137
140
|
];
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
+
analyzeAndSuggestCommitsSpy.mockResolvedValue(suggestions);
|
|
142
|
+
getReadyCommitsSpy.mockReturnValue([]);
|
|
143
|
+
getNeedsAttentionSpy.mockReturnValue([]);
|
|
141
144
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
workingFiles: ['file2.ts'],
|
|
146
|
-
});
|
|
145
|
+
execSyncSpy.mockReturnValue(
|
|
146
|
+
buildGitStatusOutput({ staged: ['file1.ts'], working: ['file2.ts'] })
|
|
147
|
+
);
|
|
147
148
|
|
|
148
149
|
const monitor = makeSUT();
|
|
149
150
|
const result = await monitor.analyze();
|
|
@@ -155,14 +156,7 @@ describe('IntelligentGitTreeMonitor', () => {
|
|
|
155
156
|
|
|
156
157
|
describe('notify', () => {
|
|
157
158
|
it('should not notify when git tree is clean', async () => {
|
|
158
|
-
|
|
159
|
-
uniqueCount: 0,
|
|
160
|
-
stagedFiles: [],
|
|
161
|
-
workingFiles: [],
|
|
162
|
-
});
|
|
163
|
-
IntelligentCommitAnalyzer.prototype.analyzeAndSuggestCommits.mockResolvedValue([]);
|
|
164
|
-
IntelligentCommitAnalyzer.prototype.getReadyCommits.mockReturnValue([]);
|
|
165
|
-
IntelligentCommitAnalyzer.prototype.getNeedsAttention.mockReturnValue([]);
|
|
159
|
+
execSyncSpy.mockReturnValue('');
|
|
166
160
|
const notifier = jest.fn();
|
|
167
161
|
const monitor = makeSUT({ notifier });
|
|
168
162
|
await monitor.notify();
|
|
@@ -178,15 +172,13 @@ describe('IntelligentGitTreeMonitor', () => {
|
|
|
178
172
|
fileCount: 1,
|
|
179
173
|
},
|
|
180
174
|
];
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
175
|
+
analyzeAndSuggestCommitsSpy.mockResolvedValue([]);
|
|
176
|
+
getReadyCommitsSpy.mockReturnValue(mockReadyCommits);
|
|
177
|
+
getNeedsAttentionSpy.mockReturnValue([]);
|
|
184
178
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
workingFiles: [],
|
|
189
|
-
});
|
|
179
|
+
execSyncSpy.mockReturnValue(
|
|
180
|
+
buildGitStatusOutput({ staged: ['file1.ts'] })
|
|
181
|
+
);
|
|
190
182
|
|
|
191
183
|
const notifier = jest.fn();
|
|
192
184
|
const monitor = makeSUT({ notifier });
|
|
@@ -199,4 +191,3 @@ describe('IntelligentGitTreeMonitor', () => {
|
|
|
199
191
|
});
|
|
200
192
|
});
|
|
201
193
|
});
|
|
202
|
-
|
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
jest.mock('child_process', () => ({
|
|
2
|
-
spawnSync: jest.fn(),
|
|
3
|
-
}));
|
|
4
|
-
|
|
5
1
|
const childProcess = require('child_process');
|
|
6
|
-
const PlaybookRunner = require('../PlaybookRunner');
|
|
7
2
|
const fs = require('fs');
|
|
8
3
|
const path = require('path');
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
let PlaybookRunner;
|
|
5
|
+
let spawnSyncSpy;
|
|
11
6
|
|
|
12
7
|
function makeSUT(options = {}) {
|
|
13
8
|
return new PlaybookRunner(options);
|
|
@@ -32,11 +27,15 @@ function cleanupPlaybooksFile() {
|
|
|
32
27
|
describe('PlaybookRunner', () => {
|
|
33
28
|
beforeEach(() => {
|
|
34
29
|
cleanupPlaybooksFile();
|
|
35
|
-
jest.
|
|
30
|
+
jest.resetModules();
|
|
31
|
+
spawnSyncSpy = jest.spyOn(childProcess, 'spawnSync');
|
|
32
|
+
spawnSyncSpy.mockReset();
|
|
33
|
+
PlaybookRunner = require('../PlaybookRunner');
|
|
36
34
|
});
|
|
37
35
|
|
|
38
36
|
afterEach(() => {
|
|
39
37
|
cleanupPlaybooksFile();
|
|
38
|
+
spawnSyncSpy.mockRestore();
|
|
40
39
|
});
|
|
41
40
|
|
|
42
41
|
describe('constructor', () => {
|
|
@@ -98,10 +97,10 @@ describe('PlaybookRunner', () => {
|
|
|
98
97
|
},
|
|
99
98
|
};
|
|
100
99
|
createMockPlaybooksFile(playbooks);
|
|
101
|
-
|
|
100
|
+
spawnSyncSpy.mockReturnValue({ status: 0 });
|
|
102
101
|
const runner = makeSUT();
|
|
103
102
|
runner.run('test');
|
|
104
|
-
expect(
|
|
103
|
+
expect(spawnSyncSpy).toHaveBeenCalledTimes(2);
|
|
105
104
|
});
|
|
106
105
|
|
|
107
106
|
it('should throw error when playbook not found', () => {
|
|
@@ -119,7 +118,7 @@ describe('PlaybookRunner', () => {
|
|
|
119
118
|
},
|
|
120
119
|
};
|
|
121
120
|
createMockPlaybooksFile(playbooks);
|
|
122
|
-
|
|
121
|
+
spawnSyncSpy.mockReturnValue({ status: 1 });
|
|
123
122
|
const runner = makeSUT();
|
|
124
123
|
expect(() => {
|
|
125
124
|
runner.run('test');
|
|
@@ -134,14 +133,13 @@ describe('PlaybookRunner', () => {
|
|
|
134
133
|
},
|
|
135
134
|
};
|
|
136
135
|
createMockPlaybooksFile(playbooks);
|
|
137
|
-
|
|
136
|
+
spawnSyncSpy.mockReturnValue({ status: 0 });
|
|
138
137
|
const runner = makeSUT({ cwd: customCwd });
|
|
139
138
|
runner.run('test');
|
|
140
|
-
expect(
|
|
139
|
+
expect(spawnSyncSpy).toHaveBeenCalledWith(
|
|
141
140
|
expect.any(String),
|
|
142
141
|
expect.objectContaining({ cwd: customCwd })
|
|
143
142
|
);
|
|
144
143
|
});
|
|
145
144
|
});
|
|
146
145
|
});
|
|
147
|
-
|
|
@@ -301,11 +301,13 @@ class SwiftAnalyzer {
|
|
|
301
301
|
checkWeakSelf(ast, filePath, content) {
|
|
302
302
|
const lines = content.split('\n');
|
|
303
303
|
let inClosure = false;
|
|
304
|
+
let closureHasWeakSelf = false;
|
|
304
305
|
lines.forEach((line, index) => {
|
|
305
306
|
if (line.includes('{') && (line.includes('->') || line.includes('in'))) {
|
|
306
307
|
inClosure = true;
|
|
308
|
+
closureHasWeakSelf = /\b(weak|unowned)\s+self\b/.test(line);
|
|
307
309
|
}
|
|
308
|
-
if (inClosure && line.includes('self.') && !
|
|
310
|
+
if (inClosure && line.includes('self.') && !closureHasWeakSelf) {
|
|
309
311
|
this.addFinding({
|
|
310
312
|
rule: 'ios.weak_self',
|
|
311
313
|
severity: 'medium',
|
|
@@ -316,6 +318,7 @@ class SwiftAnalyzer {
|
|
|
316
318
|
}
|
|
317
319
|
if (line.includes('}')) {
|
|
318
320
|
inClosure = false;
|
|
321
|
+
closureHasWeakSelf = false;
|
|
319
322
|
}
|
|
320
323
|
});
|
|
321
324
|
}
|
|
@@ -303,13 +303,6 @@ function runBackendIntelligence(project, findings, platform) {
|
|
|
303
303
|
pushFinding("backend.config.missing_env_separation", "info", sf, sf, "Missing environment-specific configuration - consider NODE_ENV or ConfigService", findings);
|
|
304
304
|
}
|
|
305
305
|
|
|
306
|
-
const hasConfigValidation = sf.getFullText().includes("joi") ||
|
|
307
|
-
sf.getFullText().includes("class-validator") ||
|
|
308
|
-
sf.getFullText().includes("@nestjs/config");
|
|
309
|
-
if (!hasConfigValidation && sf.getFullText().includes("process.env")) {
|
|
310
|
-
pushFinding("backend.config.missing_validation", "warning", sf, sf, "Environment variables without validation - consider Joi or class-validator", findings);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
306
|
const hardMaxLines = env.getNumber('AST_GODCLASS_HARD_MAX_LINES', 0);
|
|
314
307
|
const softMaxLines = env.getNumber('AST_GODCLASS_SOFT_MAX_LINES', 500);
|
|
315
308
|
const absoluteGodLines = env.getNumber('AST_GODCLASS_ABSOLUTE_LINES', 1000);
|
|
@@ -328,6 +321,13 @@ function runBackendIntelligence(project, findings, platform) {
|
|
|
328
321
|
return;
|
|
329
322
|
}
|
|
330
323
|
|
|
324
|
+
const hasConfigValidation = sf.getFullText().includes("joi") ||
|
|
325
|
+
sf.getFullText().includes("class-validator") ||
|
|
326
|
+
sf.getFullText().includes("@nestjs/config");
|
|
327
|
+
if (!hasConfigValidation && sf.getFullText().includes("process.env")) {
|
|
328
|
+
pushFinding("backend.config.missing_validation", "warning", sf, sf, "Environment variables without validation - consider Joi or class-validator", findings);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
331
|
sf.getDescendantsOfKind(SyntaxKind.ClassDeclaration).forEach((cls) => {
|
|
332
332
|
const name = cls.getName();
|
|
333
333
|
if (name && /Entity|Model|Domain/.test(name)) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const glob = require('glob');
|
|
3
|
+
const env = require('../../../../config/env');
|
|
3
4
|
const { pushFileFinding } = require('../../ast-core');
|
|
4
5
|
|
|
5
6
|
class WorkflowRules {
|
|
@@ -21,7 +22,7 @@ class WorkflowRules {
|
|
|
21
22
|
absolute: true
|
|
22
23
|
});
|
|
23
24
|
|
|
24
|
-
const isLibrarySelfAudit =
|
|
25
|
+
const isLibrarySelfAudit = env.getBool('AUDIT_LIBRARY_SELF', false) ||
|
|
25
26
|
this.projectRoot.includes('ast-intelligence-hooks');
|
|
26
27
|
if (isLibrarySelfAudit) {
|
|
27
28
|
return;
|
|
@@ -74,6 +75,7 @@ class WorkflowRules {
|
|
|
74
75
|
featureFiles.forEach(featureFile => {
|
|
75
76
|
const content = fs.readFileSync(featureFile, 'utf-8');
|
|
76
77
|
const featureName = this.extractFeatureName(content);
|
|
78
|
+
const hasImplementationHint = /^\s*Implementation\s*:/m.test(content);
|
|
77
79
|
|
|
78
80
|
if (featureName) {
|
|
79
81
|
let testFiles = glob.sync(`**/*${featureName}*.{test,spec}.{ts,tsx,swift,kt}`, {
|
|
@@ -112,7 +114,7 @@ class WorkflowRules {
|
|
|
112
114
|
);
|
|
113
115
|
}
|
|
114
116
|
|
|
115
|
-
if (implFiles.length === 0 && testFiles.length > 0) {
|
|
117
|
+
if (implFiles.length === 0 && testFiles.length > 0 && !hasImplementationHint) {
|
|
116
118
|
pushFileFinding(
|
|
117
119
|
'workflow.triad.tests_without_implementation',
|
|
118
120
|
'low',
|
|
@@ -646,7 +646,8 @@ function runTextScanner(root, findings) {
|
|
|
646
646
|
if (hasForceUnwrap && !hasLogicalNegation && !/@IBOutlet\b/.test(content) && !usesModernLocalization) {
|
|
647
647
|
pushFileFinding('ios.force_unwrapping', 'high', file, 1, 1, 'Force unwrapping detected', findings);
|
|
648
648
|
}
|
|
649
|
-
|
|
649
|
+
const hasWeakSelfCapture = /\[[^\]]*\b(weak|unowned)\s+self\b[^\]]*\]/.test(content);
|
|
650
|
+
if (!hasWeakSelfCapture && /self\./.test(content) && /\{[^\n]*in/.test(content)) {
|
|
650
651
|
pushFileFinding('ios.weak_self', 'medium', file, 1, 1, 'Closure referencing self without [weak self]', findings);
|
|
651
652
|
}
|
|
652
653
|
if (/\[\s*unowned\s+self\s*\]/.test(content)) {
|
|
@@ -673,7 +674,8 @@ function runTextScanner(root, findings) {
|
|
|
673
674
|
if (/\.sink\s*\(|\.assign\s*\(/.test(content) && !/store\s*\(in\s*:\s*/.test(content)) {
|
|
674
675
|
pushFileFinding('ios.combine.memory_management', 'medium', file, 1, 1, 'Combine subscription without store(in:)', findings);
|
|
675
676
|
}
|
|
676
|
-
|
|
677
|
+
const hasTaskCancellationHandling = /withTaskCancellationHandler\s*\(|\bTask\.isCancelled\b|\bTask\.checkCancellation\s*\(/.test(content);
|
|
678
|
+
if (/\bTask\s*\{/.test(content) && !hasTaskCancellationHandling) {
|
|
677
679
|
pushFileFinding('ios.concurrency.task_cancellation', 'low', file, 1, 1, 'Task without cancellation handling', findings);
|
|
678
680
|
}
|
|
679
681
|
iosTaskCount += (content.match(/\bTask\s*\{/g) || []).length;
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
jest.mock('child_process', () => ({
|
|
2
|
-
execSync: jest.fn(),
|
|
3
|
-
}));
|
|
4
|
-
|
|
5
1
|
const childProcess = require('child_process');
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const { execSync } = childProcess;
|
|
2
|
+
let GitOperations;
|
|
3
|
+
let execSyncSpy;
|
|
9
4
|
|
|
10
5
|
function makeMockGitOutput(files) {
|
|
11
6
|
return files.join('\n') + (files.length > 0 ? '\n' : '');
|
|
@@ -13,35 +8,42 @@ function makeMockGitOutput(files) {
|
|
|
13
8
|
|
|
14
9
|
describe('GitOperations', () => {
|
|
15
10
|
beforeEach(() => {
|
|
16
|
-
jest.
|
|
11
|
+
jest.resetModules();
|
|
12
|
+
execSyncSpy = jest.spyOn(childProcess, 'execSync');
|
|
13
|
+
execSyncSpy.mockReset();
|
|
14
|
+
({ GitOperations } = require('../GitOperations'));
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
execSyncSpy.mockRestore();
|
|
17
19
|
});
|
|
18
20
|
|
|
19
21
|
describe('getStagedFiles', () => {
|
|
20
22
|
it('should return array of staged files', () => {
|
|
21
23
|
const mockFiles = ['file1.ts', 'file2.ts', 'file3.ts'];
|
|
22
|
-
|
|
24
|
+
execSyncSpy.mockReturnValue(makeMockGitOutput(mockFiles));
|
|
23
25
|
const files = GitOperations.getStagedFiles();
|
|
24
26
|
expect(files).toEqual(mockFiles);
|
|
25
|
-
expect(
|
|
27
|
+
expect(execSyncSpy).toHaveBeenCalledWith(
|
|
26
28
|
'git diff --cached --name-only --diff-filter=ACM',
|
|
27
29
|
{ encoding: 'utf8' }
|
|
28
30
|
);
|
|
29
31
|
});
|
|
30
32
|
|
|
31
33
|
it('should return empty array when no staged files', () => {
|
|
32
|
-
|
|
34
|
+
execSyncSpy.mockReturnValue('');
|
|
33
35
|
const files = GitOperations.getStagedFiles();
|
|
34
36
|
expect(files).toEqual([]);
|
|
35
37
|
});
|
|
36
38
|
|
|
37
39
|
it('should filter out empty lines', () => {
|
|
38
|
-
|
|
40
|
+
execSyncSpy.mockReturnValue('file1.ts\n\nfile2.ts\n');
|
|
39
41
|
const files = GitOperations.getStagedFiles();
|
|
40
42
|
expect(files).toEqual(['file1.ts', 'file2.ts']);
|
|
41
43
|
});
|
|
42
44
|
|
|
43
45
|
it('should return empty array on git error', () => {
|
|
44
|
-
|
|
46
|
+
execSyncSpy.mockImplementation(() => {
|
|
45
47
|
throw new Error('Not a git repository');
|
|
46
48
|
});
|
|
47
49
|
const files = GitOperations.getStagedFiles();
|
|
@@ -52,23 +54,23 @@ describe('GitOperations', () => {
|
|
|
52
54
|
describe('getWorkingDirectoryFiles', () => {
|
|
53
55
|
it('should return array of working directory files', () => {
|
|
54
56
|
const mockFiles = ['file1.ts', 'file2.ts'];
|
|
55
|
-
|
|
57
|
+
execSyncSpy.mockReturnValue(makeMockGitOutput(mockFiles));
|
|
56
58
|
const files = GitOperations.getWorkingDirectoryFiles();
|
|
57
59
|
expect(files).toEqual(mockFiles);
|
|
58
|
-
expect(
|
|
60
|
+
expect(execSyncSpy).toHaveBeenCalledWith(
|
|
59
61
|
'git diff --name-only --diff-filter=ACM',
|
|
60
62
|
{ encoding: 'utf8' }
|
|
61
63
|
);
|
|
62
64
|
});
|
|
63
65
|
|
|
64
66
|
it('should return empty array when no working files', () => {
|
|
65
|
-
|
|
67
|
+
execSyncSpy.mockReturnValue('');
|
|
66
68
|
const files = GitOperations.getWorkingDirectoryFiles();
|
|
67
69
|
expect(files).toEqual([]);
|
|
68
70
|
});
|
|
69
71
|
|
|
70
72
|
it('should return empty array on git error', () => {
|
|
71
|
-
|
|
73
|
+
execSyncSpy.mockImplementation(() => {
|
|
72
74
|
throw new Error('Git error');
|
|
73
75
|
});
|
|
74
76
|
const files = GitOperations.getWorkingDirectoryFiles();
|
|
@@ -79,20 +81,20 @@ describe('GitOperations', () => {
|
|
|
79
81
|
describe('getAllChangedFiles', () => {
|
|
80
82
|
it('should return array of all changed files', () => {
|
|
81
83
|
const mockFiles = ['staged1.ts', 'staged2.ts', 'working1.ts'];
|
|
82
|
-
|
|
84
|
+
execSyncSpy.mockReturnValue(makeMockGitOutput(mockFiles));
|
|
83
85
|
const files = GitOperations.getAllChangedFiles();
|
|
84
86
|
expect(files).toEqual(mockFiles);
|
|
85
87
|
});
|
|
86
88
|
|
|
87
89
|
it('should combine staged and working files', () => {
|
|
88
|
-
|
|
90
|
+
execSyncSpy.mockReturnValue('staged.ts\nworking.ts\n');
|
|
89
91
|
const files = GitOperations.getAllChangedFiles();
|
|
90
92
|
expect(files).toContain('staged.ts');
|
|
91
93
|
expect(files).toContain('working.ts');
|
|
92
94
|
});
|
|
93
95
|
|
|
94
96
|
it('should return empty array on git error', () => {
|
|
95
|
-
|
|
97
|
+
execSyncSpy.mockImplementation(() => {
|
|
96
98
|
throw new Error('Git error');
|
|
97
99
|
});
|
|
98
100
|
const files = GitOperations.getAllChangedFiles();
|
|
@@ -102,17 +104,17 @@ describe('GitOperations', () => {
|
|
|
102
104
|
|
|
103
105
|
describe('isInGitRepository', () => {
|
|
104
106
|
it('should return true when in git repository', () => {
|
|
105
|
-
|
|
107
|
+
execSyncSpy.mockReturnValue('.git');
|
|
106
108
|
const isGit = GitOperations.isInGitRepository();
|
|
107
109
|
expect(isGit).toBe(true);
|
|
108
|
-
expect(
|
|
110
|
+
expect(execSyncSpy).toHaveBeenCalledWith(
|
|
109
111
|
'git rev-parse --git-dir',
|
|
110
112
|
{ stdio: 'ignore' }
|
|
111
113
|
);
|
|
112
114
|
});
|
|
113
115
|
|
|
114
116
|
it('should return false when not in git repository', () => {
|
|
115
|
-
|
|
117
|
+
execSyncSpy.mockImplementation(() => {
|
|
116
118
|
throw new Error('Not a git repository');
|
|
117
119
|
});
|
|
118
120
|
const isGit = GitOperations.isInGitRepository();
|
|
@@ -123,17 +125,17 @@ describe('GitOperations', () => {
|
|
|
123
125
|
describe('getRepositoryRoot', () => {
|
|
124
126
|
it('should return repository root path', () => {
|
|
125
127
|
const mockRoot = '/path/to/repo';
|
|
126
|
-
|
|
128
|
+
execSyncSpy.mockReturnValue(mockRoot + '\n');
|
|
127
129
|
const root = GitOperations.getRepositoryRoot();
|
|
128
130
|
expect(root).toBe(mockRoot);
|
|
129
|
-
expect(
|
|
131
|
+
expect(execSyncSpy).toHaveBeenCalledWith(
|
|
130
132
|
'git rev-parse --show-toplevel',
|
|
131
133
|
{ encoding: 'utf8' }
|
|
132
134
|
);
|
|
133
135
|
});
|
|
134
136
|
|
|
135
137
|
it('should return current working directory on error', () => {
|
|
136
|
-
|
|
138
|
+
execSyncSpy.mockImplementation(() => {
|
|
137
139
|
throw new Error('Not a git repository');
|
|
138
140
|
});
|
|
139
141
|
const root = GitOperations.getRepositoryRoot();
|
|
@@ -141,10 +143,9 @@ describe('GitOperations', () => {
|
|
|
141
143
|
});
|
|
142
144
|
|
|
143
145
|
it('should trim whitespace from root path', () => {
|
|
144
|
-
|
|
146
|
+
execSyncSpy.mockReturnValue(' /path/to/repo \n');
|
|
145
147
|
const root = GitOperations.getRepositoryRoot();
|
|
146
148
|
expect(root).toBe('/path/to/repo');
|
|
147
149
|
});
|
|
148
150
|
});
|
|
149
151
|
});
|
|
150
|
-
|
|
@@ -825,8 +825,10 @@ async function updateAIEvidence(violations, gateResult, tokenUsage) {
|
|
|
825
825
|
}
|
|
826
826
|
}
|
|
827
827
|
|
|
828
|
+
const hasBlockingSeverities = criticalViolations.length > 0 || highViolations.length > 0;
|
|
829
|
+
const evidenceGateStatus = gateResult.passed || !hasBlockingSeverities ? 'ALLOWED' : 'BLOCKED';
|
|
828
830
|
const nextGate = {
|
|
829
|
-
status:
|
|
831
|
+
status: evidenceGateStatus,
|
|
830
832
|
scope: gateScope === 'repo' || gateScope === 'repository' ? 'repo' : 'staging',
|
|
831
833
|
last_check: formatLocalTimestamp(),
|
|
832
834
|
severity_summary: {
|
|
@@ -874,8 +876,8 @@ async function updateAIEvidence(violations, gateResult, tokenUsage) {
|
|
|
874
876
|
? `Staged files analyzed: ${stagedFilesList.length}. Platforms detected: ${detectedPlatformsForQuestions.join(', ') || 'none'}.`
|
|
875
877
|
: 'No staged files detected for analysis.',
|
|
876
878
|
question_2_similar_exists: violations.length > 0
|
|
877
|
-
? `Detected ${violations.length} rule violations; review
|
|
878
|
-
: 'No rule violations detected; no similar patterns flagged.',
|
|
879
|
+
? `Detected ${violations.length} rule violations; review recent commits and similar patterns flagged by rules.`
|
|
880
|
+
: 'No rule violations detected; no similar patterns flagged in recent commits.',
|
|
879
881
|
question_3_clean_architecture: architectureViolations.length > 0
|
|
880
882
|
? `Found ${architectureViolations.length} Clean Architecture/SOLID-related violations that require review.`
|
|
881
883
|
: 'No Clean Architecture or SOLID violations detected.',
|
package/scripts/hooks-system/infrastructure/watchdog/__tests__/.audit-reports/token-monitor.log
CHANGED
|
@@ -190,3 +190,15 @@
|
|
|
190
190
|
{"timestamp":"2026-01-26T19:01:58.968Z","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"}}
|
|
191
191
|
{"timestamp":"2026-01-26T19:01:58.970Z","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"}}
|
|
192
192
|
{"timestamp":"2026-01-26T19:01:58.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)"}}
|
|
193
|
+
{"timestamp":"2026-01-28T18:12:39.899Z","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"}}
|
|
194
|
+
{"timestamp":"2026-01-28T18:12:39.900Z","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"}}
|
|
195
|
+
{"timestamp":"2026-01-28T18:12:39.901Z","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)"}}
|
|
196
|
+
{"timestamp":"2026-01-28T18:37:07.882Z","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"}}
|
|
197
|
+
{"timestamp":"2026-01-28T18:37:07.883Z","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"}}
|
|
198
|
+
{"timestamp":"2026-01-28T18:37:07.884Z","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)"}}
|
|
199
|
+
{"timestamp":"2026-01-28T18:51:14.085Z","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"}}
|
|
200
|
+
{"timestamp":"2026-01-28T18:51:14.087Z","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"}}
|
|
201
|
+
{"timestamp":"2026-01-28T18:51:14.088Z","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)"}}
|
|
202
|
+
{"timestamp":"2026-01-28T18:59:59.378Z","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"}}
|
|
203
|
+
{"timestamp":"2026-01-28T18:59:59.380Z","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"}}
|
|
204
|
+
{"timestamp":"2026-01-28T18:59:59.380Z","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)"}}
|