pumuki-ast-hooks 5.5.65 → 5.6.2
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 +157 -11
- package/bin/__tests__/check-version.spec.js +32 -57
- package/package.json +1 -1
- package/scripts/hooks-system/.audit_tmp/hook-metrics.jsonl +8 -0
- package/scripts/hooks-system/bin/__tests__/check-version.spec.js +37 -57
- package/scripts/hooks-system/bin/cli.js +109 -0
- package/scripts/hooks-system/infrastructure/ast/ast-core.js +124 -0
- package/scripts/hooks-system/infrastructure/ast/backend/ast-backend.js +3 -1
- package/scripts/hooks-system/infrastructure/ast/frontend/analyzers/__tests__/FrontendArchitectureDetector.spec.js +4 -1
- package/scripts/hooks-system/infrastructure/ast/ios/analyzers/__tests__/iOSASTIntelligentAnalyzer.spec.js +3 -1
- package/scripts/hooks-system/infrastructure/ast/ios/detectors/ios-ast-intelligent-strategies.js +1 -1
- package/scripts/hooks-system/infrastructure/cascade-hooks/README.md +114 -0
- package/scripts/hooks-system/infrastructure/cascade-hooks/cascade-hooks-config.json +20 -0
- package/scripts/hooks-system/infrastructure/cascade-hooks/claude-code-hook.sh +127 -0
- package/scripts/hooks-system/infrastructure/cascade-hooks/post-write-code-hook.js +72 -0
- package/scripts/hooks-system/infrastructure/cascade-hooks/pre-write-code-hook.js +167 -0
- package/scripts/hooks-system/infrastructure/cascade-hooks/universal-hook-adapter.js +186 -0
- package/scripts/hooks-system/infrastructure/mcp/ast-intelligence-automation.js +739 -24
- package/scripts/hooks-system/infrastructure/observability/MetricsCollector.js +221 -0
- package/scripts/hooks-system/infrastructure/observability/index.js +23 -0
- package/scripts/hooks-system/infrastructure/orchestration/__tests__/intelligent-audit.spec.js +177 -0
- package/scripts/hooks-system/infrastructure/resilience/CircuitBreaker.js +229 -0
- package/scripts/hooks-system/infrastructure/resilience/RetryPolicy.js +141 -0
- package/scripts/hooks-system/infrastructure/resilience/index.js +34 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* =============================================================================
|
|
3
|
+
* RetryPolicy - Enterprise Resilience for AST Intelligence
|
|
4
|
+
* =============================================================================
|
|
5
|
+
* Configurable retry strategies with exponential backoff, jitter, and hooks
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
class RetryPolicy {
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
this.maxRetries = options.maxRetries ?? 3;
|
|
11
|
+
this.baseDelay = options.baseDelay ?? 1000;
|
|
12
|
+
this.maxDelay = options.maxDelay ?? 30000;
|
|
13
|
+
this.backoffMultiplier = options.backoffMultiplier ?? 2;
|
|
14
|
+
this.jitter = options.jitter ?? true;
|
|
15
|
+
this.retryOn = options.retryOn || this._defaultRetryOn;
|
|
16
|
+
this.onRetry = options.onRetry || (() => { });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
_defaultRetryOn(error) {
|
|
20
|
+
if (error.name === 'CircuitBreakerError') return false;
|
|
21
|
+
if (error.code === 'ECONNREFUSED') return true;
|
|
22
|
+
if (error.code === 'ETIMEDOUT') return true;
|
|
23
|
+
if (error.code === 'ENOTFOUND') return true;
|
|
24
|
+
if (error.message?.includes('timeout')) return true;
|
|
25
|
+
if (error.message?.includes('rate limit')) return true;
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
_calculateDelay(attempt) {
|
|
30
|
+
let delay = this.baseDelay * Math.pow(this.backoffMultiplier, attempt);
|
|
31
|
+
delay = Math.min(delay, this.maxDelay);
|
|
32
|
+
|
|
33
|
+
if (this.jitter) {
|
|
34
|
+
const jitterRange = delay * 0.2;
|
|
35
|
+
delay = delay - jitterRange + (Math.random() * jitterRange * 2);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return Math.round(delay);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async execute(fn) {
|
|
42
|
+
let lastError;
|
|
43
|
+
|
|
44
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
45
|
+
try {
|
|
46
|
+
return await fn();
|
|
47
|
+
} catch (error) {
|
|
48
|
+
lastError = error;
|
|
49
|
+
|
|
50
|
+
if (attempt === this.maxRetries) {
|
|
51
|
+
throw new RetryExhaustedError(
|
|
52
|
+
`All ${this.maxRetries + 1} attempts failed`,
|
|
53
|
+
lastError,
|
|
54
|
+
attempt + 1
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const shouldRetry = typeof this.retryOn === 'function'
|
|
59
|
+
? this.retryOn(error, attempt)
|
|
60
|
+
: true;
|
|
61
|
+
|
|
62
|
+
if (!shouldRetry) {
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const delay = this._calculateDelay(attempt);
|
|
67
|
+
|
|
68
|
+
this.onRetry({
|
|
69
|
+
attempt: attempt + 1,
|
|
70
|
+
maxRetries: this.maxRetries,
|
|
71
|
+
delay,
|
|
72
|
+
error: error.message
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
await this._sleep(delay);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
throw lastError;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
_sleep(ms) {
|
|
83
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
static immediate(maxRetries = 3) {
|
|
87
|
+
return new RetryPolicy({
|
|
88
|
+
maxRetries,
|
|
89
|
+
baseDelay: 0,
|
|
90
|
+
jitter: false
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
static linear(maxRetries = 3, delay = 1000) {
|
|
95
|
+
return new RetryPolicy({
|
|
96
|
+
maxRetries,
|
|
97
|
+
baseDelay: delay,
|
|
98
|
+
backoffMultiplier: 1,
|
|
99
|
+
jitter: false
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static exponential(maxRetries = 3, baseDelay = 1000) {
|
|
104
|
+
return new RetryPolicy({
|
|
105
|
+
maxRetries,
|
|
106
|
+
baseDelay,
|
|
107
|
+
backoffMultiplier: 2,
|
|
108
|
+
jitter: true
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
static aggressive(maxRetries = 5, baseDelay = 500) {
|
|
113
|
+
return new RetryPolicy({
|
|
114
|
+
maxRetries,
|
|
115
|
+
baseDelay,
|
|
116
|
+
backoffMultiplier: 1.5,
|
|
117
|
+
maxDelay: 10000,
|
|
118
|
+
jitter: true
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
class RetryExhaustedError extends Error {
|
|
124
|
+
constructor(message, lastError, attempts) {
|
|
125
|
+
super(message);
|
|
126
|
+
this.name = 'RetryExhaustedError';
|
|
127
|
+
this.lastError = lastError;
|
|
128
|
+
this.attempts = attempts;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async function withRetry(fn, options = {}) {
|
|
133
|
+
const policy = new RetryPolicy(options);
|
|
134
|
+
return policy.execute(fn);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
module.exports = {
|
|
138
|
+
RetryPolicy,
|
|
139
|
+
RetryExhaustedError,
|
|
140
|
+
withRetry
|
|
141
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resilience Module - Circuit Breaker & Retry Policies
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
CircuitBreaker,
|
|
7
|
+
CircuitBreakerError,
|
|
8
|
+
CircuitBreakerRegistry,
|
|
9
|
+
globalRegistry,
|
|
10
|
+
mcpCircuit,
|
|
11
|
+
gitCircuit,
|
|
12
|
+
astCircuit,
|
|
13
|
+
STATES
|
|
14
|
+
} = require('./CircuitBreaker');
|
|
15
|
+
|
|
16
|
+
const {
|
|
17
|
+
RetryPolicy,
|
|
18
|
+
RetryExhaustedError,
|
|
19
|
+
withRetry
|
|
20
|
+
} = require('./RetryPolicy');
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
CircuitBreaker,
|
|
24
|
+
CircuitBreakerError,
|
|
25
|
+
CircuitBreakerRegistry,
|
|
26
|
+
globalRegistry,
|
|
27
|
+
mcpCircuit,
|
|
28
|
+
gitCircuit,
|
|
29
|
+
astCircuit,
|
|
30
|
+
STATES,
|
|
31
|
+
RetryPolicy,
|
|
32
|
+
RetryExhaustedError,
|
|
33
|
+
withRetry
|
|
34
|
+
};
|