pumuki-ast-hooks 5.3.19 → 5.3.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/RELEASE_NOTES.md +35 -0
- package/docs/VIOLATIONS_RESOLUTION_PLAN.md +64 -60
- package/package.json +9 -3
- package/scripts/hooks-system/.AI_TOKEN_STATUS.txt +1 -1
- package/scripts/hooks-system/.audit-reports/notifications.log +935 -0
- package/scripts/hooks-system/.audit-reports/token-monitor.log +2809 -0
- package/scripts/hooks-system/application/CompositionRoot.js +38 -22
- package/scripts/hooks-system/application/services/DynamicRulesLoader.js +2 -1
- package/scripts/hooks-system/application/services/GitTreeState.js +2 -1
- package/scripts/hooks-system/application/services/PlaybookRunner.js +1 -1
- package/scripts/hooks-system/application/services/RealtimeGuardService.js +71 -14
- package/scripts/hooks-system/application/services/guard/GuardAutoManagerService.js +31 -2
- package/scripts/hooks-system/application/services/guard/GuardConfig.js +17 -9
- package/scripts/hooks-system/application/services/guard/GuardHeartbeatMonitor.js +6 -9
- package/scripts/hooks-system/application/services/guard/GuardProcessManager.js +23 -0
- package/scripts/hooks-system/application/services/installation/GitEnvironmentService.js +1 -1
- package/scripts/hooks-system/application/services/installation/HookInstaller.js +62 -5
- package/scripts/hooks-system/application/services/installation/McpConfigurator.js +2 -1
- package/scripts/hooks-system/application/services/logging/AuditLogger.js +0 -4
- package/scripts/hooks-system/application/services/logging/UnifiedLogger.js +13 -4
- package/scripts/hooks-system/application/services/monitoring/EvidenceMonitorService.js +4 -3
- package/scripts/hooks-system/application/services/token/TokenMetricsService.js +2 -1
- package/scripts/hooks-system/bin/cli.js +15 -1
- package/scripts/hooks-system/bin/guard-env.sh +18 -38
- package/scripts/hooks-system/bin/guard-supervisor.js +5 -515
- package/scripts/hooks-system/bin/session-loader.sh +3 -262
- package/scripts/hooks-system/bin/start-guards.sh +21 -184
- package/scripts/hooks-system/bin/update-evidence.sh +10 -1161
- package/scripts/hooks-system/config/project.config.json +1 -1
- package/scripts/hooks-system/domain/events/index.js +32 -6
- package/scripts/hooks-system/domain/exceptions/index.js +87 -0
- package/scripts/hooks-system/infrastructure/ast/android/analyzers/AndroidAnalysisOrchestrator.js +3 -2
- package/scripts/hooks-system/infrastructure/ast/ast-core.js +12 -20
- package/scripts/hooks-system/infrastructure/ast/ast-intelligence.js +8 -18
- package/scripts/hooks-system/infrastructure/ast/backend/analyzers/BackendPatternDetector.js +2 -1
- package/scripts/hooks-system/infrastructure/ast/backend/ast-backend.js +10 -8
- package/scripts/hooks-system/infrastructure/ast/frontend/ast-frontend.js +196 -196
- package/scripts/hooks-system/infrastructure/ast/ios/analyzers/iOSASTIntelligentAnalyzer.js +3 -2
- package/scripts/hooks-system/infrastructure/config/config.js +5 -0
- package/scripts/hooks-system/infrastructure/hooks/skill-activation-prompt.js +3 -2
- package/scripts/hooks-system/infrastructure/logging/UnifiedLoggerFactory.js +5 -4
- package/scripts/hooks-system/infrastructure/mcp/ast-intelligence-automation.js +88 -0
- package/scripts/hooks-system/infrastructure/orchestration/intelligent-audit.js +17 -16
- package/scripts/hooks-system/infrastructure/telemetry/metric-scope.js +98 -0
- package/scripts/hooks-system/infrastructure/telemetry/metrics-server.js +3 -2
- package/scripts/hooks-system/infrastructure/validators/enforce-english-literals.js +6 -8
|
@@ -14,6 +14,50 @@ class HookInstaller {
|
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
getPackageRoot() {
|
|
18
|
+
let dir = this.hookSystemRoot;
|
|
19
|
+
for (let i = 0; i < 8; i++) {
|
|
20
|
+
const pkgJson = path.join(dir, 'package.json');
|
|
21
|
+
try {
|
|
22
|
+
if (fs.existsSync(pkgJson) && fs.statSync(pkgJson).isFile()) {
|
|
23
|
+
return dir;
|
|
24
|
+
}
|
|
25
|
+
} catch (error) {
|
|
26
|
+
const msg = error && error.message ? error.message : String(error);
|
|
27
|
+
this.logger?.debug?.('HOOK_INSTALLER_PACKAGE_ROOT_PROBE_ERROR', {
|
|
28
|
+
pkgJson,
|
|
29
|
+
error: msg
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const parent = path.dirname(dir);
|
|
34
|
+
if (parent === dir) {
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
dir = parent;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return path.resolve(this.hookSystemRoot, '..', '..', '..');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
resolveFirstExistingDir(candidates) {
|
|
44
|
+
for (const candidate of candidates) {
|
|
45
|
+
if (!candidate) continue;
|
|
46
|
+
try {
|
|
47
|
+
if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {
|
|
48
|
+
return candidate;
|
|
49
|
+
}
|
|
50
|
+
} catch (error) {
|
|
51
|
+
const msg = error && error.message ? error.message : String(error);
|
|
52
|
+
this.logger?.debug?.('HOOK_INSTALLER_DIR_PROBE_ERROR', {
|
|
53
|
+
candidate,
|
|
54
|
+
error: msg
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
17
61
|
install(platforms) {
|
|
18
62
|
const claudeDir = path.join(this.targetRoot, '.ast-intelligence');
|
|
19
63
|
const claudeSkillsDir = path.join(claudeDir, 'skills');
|
|
@@ -31,12 +75,20 @@ class HookInstaller {
|
|
|
31
75
|
}
|
|
32
76
|
|
|
33
77
|
installSkills(claudeSkillsDir, platforms) {
|
|
34
|
-
const
|
|
78
|
+
const packageRoot = this.getPackageRoot();
|
|
79
|
+
const librarySkillsDir = this.resolveFirstExistingDir([
|
|
80
|
+
path.join(this.hookSystemRoot, 'skills'),
|
|
81
|
+
path.join(packageRoot, 'skills')
|
|
82
|
+
]);
|
|
35
83
|
|
|
36
|
-
if (!
|
|
84
|
+
if (!librarySkillsDir) {
|
|
37
85
|
return;
|
|
38
86
|
}
|
|
39
87
|
|
|
88
|
+
if (!fs.existsSync(claudeSkillsDir)) {
|
|
89
|
+
fs.mkdirSync(claudeSkillsDir, { recursive: true });
|
|
90
|
+
}
|
|
91
|
+
|
|
40
92
|
const relevantSkills = this.getRelevantSkills(platforms);
|
|
41
93
|
|
|
42
94
|
relevantSkills.forEach(skillName => {
|
|
@@ -58,9 +110,13 @@ class HookInstaller {
|
|
|
58
110
|
}
|
|
59
111
|
|
|
60
112
|
installHooks(claudeHooksDir) {
|
|
61
|
-
const
|
|
113
|
+
const packageRoot = this.getPackageRoot();
|
|
114
|
+
const libraryHooksDir = this.resolveFirstExistingDir([
|
|
115
|
+
path.join(this.hookSystemRoot, 'hooks'),
|
|
116
|
+
path.join(packageRoot, 'hooks')
|
|
117
|
+
]);
|
|
62
118
|
|
|
63
|
-
if (!
|
|
119
|
+
if (!libraryHooksDir) {
|
|
64
120
|
return;
|
|
65
121
|
}
|
|
66
122
|
|
|
@@ -100,7 +156,8 @@ class HookInstaller {
|
|
|
100
156
|
}
|
|
101
157
|
|
|
102
158
|
copyIDERules() {
|
|
103
|
-
const
|
|
159
|
+
const packageRoot = this.getPackageRoot();
|
|
160
|
+
const sourceRulesDir = path.join(packageRoot, '.cursor', 'rules');
|
|
104
161
|
|
|
105
162
|
if (!fs.existsSync(sourceRulesDir)) {
|
|
106
163
|
return;
|
|
@@ -3,6 +3,7 @@ const path = require('path');
|
|
|
3
3
|
const { execSync } = require('child_process');
|
|
4
4
|
const crypto = require('crypto');
|
|
5
5
|
const os = require('os');
|
|
6
|
+
const env = require('../../config/env');
|
|
6
7
|
|
|
7
8
|
const COLORS = {
|
|
8
9
|
reset: '\x1b[0m',
|
|
@@ -31,7 +32,7 @@ function computeRepoFingerprint(repoRoot) {
|
|
|
31
32
|
|
|
32
33
|
function computeServerIdForRepo(repoRoot) {
|
|
33
34
|
const legacyServerId = 'ast-intelligence-automation';
|
|
34
|
-
const forced = (
|
|
35
|
+
const forced = (env.get('MCP_SERVER_ID', '') || '').trim();
|
|
35
36
|
if (forced.length > 0) return forced;
|
|
36
37
|
|
|
37
38
|
const repoName = path.basename(repoRoot || process.cwd());
|
|
@@ -3,7 +3,6 @@ const path = require('path');
|
|
|
3
3
|
|
|
4
4
|
// Import recordMetric for prometheus metrics
|
|
5
5
|
const { recordMetric } = require('../../../infrastructure/telemetry/metrics-logger');
|
|
6
|
-
|
|
7
6
|
class AuditLogger {
|
|
8
7
|
/**
|
|
9
8
|
* @param {Object} options
|
|
@@ -18,7 +17,6 @@ class AuditLogger {
|
|
|
18
17
|
status: 'started',
|
|
19
18
|
repoRoot: repoRoot.substring(0, 100)
|
|
20
19
|
});
|
|
21
|
-
|
|
22
20
|
this.repoRoot = repoRoot;
|
|
23
21
|
this.logger = logger;
|
|
24
22
|
this.logPath = filename
|
|
@@ -147,7 +145,6 @@ class AuditLogger {
|
|
|
147
145
|
status: 'started',
|
|
148
146
|
metaKeys: Object.keys(meta || {}).length
|
|
149
147
|
});
|
|
150
|
-
|
|
151
148
|
const forbidden = ['token', 'password', 'secret', 'authorization', 'auth', 'apiKey'];
|
|
152
149
|
const clone = {};
|
|
153
150
|
Object.entries(meta).forEach(([k, v]) => {
|
|
@@ -165,7 +162,6 @@ class AuditLogger {
|
|
|
165
162
|
status: 'success',
|
|
166
163
|
metaKeys: Object.keys(clone).length
|
|
167
164
|
});
|
|
168
|
-
|
|
169
165
|
return clone;
|
|
170
166
|
}
|
|
171
167
|
}
|
|
@@ -97,10 +97,19 @@ class UnifiedLogger {
|
|
|
97
97
|
this.rotateFileIfNeeded();
|
|
98
98
|
fs.appendFileSync(this.fileConfig.path, `${JSON.stringify(entry)}\n`, 'utf8');
|
|
99
99
|
} catch (error) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
error
|
|
100
|
+
try {
|
|
101
|
+
const env = require('../../../config/env');
|
|
102
|
+
if (env.getBool('DEBUG', false)) {
|
|
103
|
+
console.error('[UnifiedLogger] Failed to write log file', {
|
|
104
|
+
path: this.fileConfig.path,
|
|
105
|
+
error: error.message
|
|
106
|
+
});
|
|
107
|
+
} else {
|
|
108
|
+
console.warn('[UnifiedLogger] File logging skipped due to error');
|
|
109
|
+
}
|
|
110
|
+
} catch (secondaryError) {
|
|
111
|
+
console.error('[UnifiedLogger] Secondary logging failure', {
|
|
112
|
+
error: secondaryError.message
|
|
104
113
|
});
|
|
105
114
|
}
|
|
106
115
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { execSync } = require('child_process');
|
|
4
|
+
const env = require('../../config/env');
|
|
4
5
|
|
|
5
6
|
function resolveUpdateEvidenceScript(repoRoot) {
|
|
6
7
|
const candidates = [
|
|
@@ -25,9 +26,9 @@ class EvidenceMonitorService {
|
|
|
25
26
|
updateScriptPath = resolveUpdateEvidenceScript(repoRoot) || path.join(process.cwd(), 'scripts', 'hooks-system', 'bin', 'update-evidence.sh'),
|
|
26
27
|
notifier = () => { },
|
|
27
28
|
logger = console,
|
|
28
|
-
autoRefreshEnabled =
|
|
29
|
-
autoRefreshCooldownMs =
|
|
30
|
-
staleThresholdMs =
|
|
29
|
+
autoRefreshEnabled = env.getBool('HOOK_GUARD_AUTO_REFRESH', true),
|
|
30
|
+
autoRefreshCooldownMs = env.getNumber('HOOK_GUARD_AUTO_REFRESH_COOLDOWN', 180000),
|
|
31
|
+
staleThresholdMs = env.getNumber('HOOK_GUARD_EVIDENCE_STALE_THRESHOLD', 10 * 60 * 1000),
|
|
31
32
|
fsModule = fs,
|
|
32
33
|
execFn = execSync
|
|
33
34
|
} = {}) {
|
|
@@ -54,7 +54,8 @@ class TokenMetricsService {
|
|
|
54
54
|
if (untrusted) {
|
|
55
55
|
level = 'ok';
|
|
56
56
|
}
|
|
57
|
-
const
|
|
57
|
+
const env = require('../../config/env');
|
|
58
|
+
const forceLevel = (env.get('TOKEN_MONITOR_FORCE_LEVEL', '') || '').toLowerCase();
|
|
58
59
|
if (forceLevel === 'warning' || forceLevel === 'critical' || forceLevel === 'ok') {
|
|
59
60
|
level = forceLevel;
|
|
60
61
|
}
|
|
@@ -121,7 +121,21 @@ const commands = {
|
|
|
121
121
|
},
|
|
122
122
|
|
|
123
123
|
ast: () => {
|
|
124
|
-
|
|
124
|
+
const env = { ...process.env };
|
|
125
|
+
const filteredArgs = [];
|
|
126
|
+
|
|
127
|
+
for (const arg of args) {
|
|
128
|
+
if (arg === '--staged') {
|
|
129
|
+
env.STAGING_ONLY_MODE = '1';
|
|
130
|
+
} else {
|
|
131
|
+
filteredArgs.push(arg);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
execSync(
|
|
136
|
+
`node ${path.join(HOOKS_ROOT, 'infrastructure/ast/ast-intelligence.js')} ${filteredArgs.join(' ')}`,
|
|
137
|
+
{ stdio: 'inherit', env }
|
|
138
|
+
);
|
|
125
139
|
},
|
|
126
140
|
|
|
127
141
|
install: () => {
|
|
@@ -1,40 +1,20 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
|
|
2
|
+
# Script Wrapper
|
|
3
|
+
# Redirects to the centralized implementation in scripts/hooks-system
|
|
4
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo ".")
|
|
5
|
+
IMPL="$REPO_ROOT/node_modules/@pumuki/ast-intelligence-hooks/scripts/hooks-system/bin/guard-env.sh"
|
|
6
|
+
if [[ -f "$IMPL" ]]; then
|
|
7
|
+
# shellcheck disable=SC1090
|
|
8
|
+
source "$IMPL"
|
|
9
|
+
return 0 2>/dev/null || exit 0
|
|
10
|
+
fi
|
|
5
11
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export HOOK_GUARD_AUTORELOAD_FORCE=${HOOK_GUARD_AUTORELOAD_FORCE:-5000}
|
|
16
|
-
export HOOK_GUARD_DIRTY_TREE_LIMIT=${HOOK_GUARD_DIRTY_TREE_LIMIT:-24}
|
|
17
|
-
export HOOK_GUARD_DIRTY_TREE_WARNING=${HOOK_GUARD_DIRTY_TREE_WARNING:-12}
|
|
18
|
-
export HOOK_GUARD_DIRTY_TREE_INTERVAL=${HOOK_GUARD_DIRTY_TREE_INTERVAL:-60000}
|
|
19
|
-
export HOOK_GUARD_DIRTY_TREE_REMINDER=${HOOK_GUARD_DIRTY_TREE_REMINDER:-300000}
|
|
20
|
-
export TOKEN_MONITOR_INTERVAL=${TOKEN_MONITOR_INTERVAL:-180}
|
|
21
|
-
export TOKEN_MONITOR_REMINDER_SECONDS=${TOKEN_MONITOR_REMINDER_SECONDS:-180}
|
|
22
|
-
export TOKEN_MONITOR_MIN_DELTA=${TOKEN_MONITOR_MIN_DELTA:-25000}
|
|
23
|
-
export HOOK_GUARD_GITFLOW_AUTOSYNC=${HOOK_GUARD_GITFLOW_AUTOSYNC:-true}
|
|
24
|
-
export HOOK_GUARD_GITFLOW_AUTOSYNC_INTERVAL=${HOOK_GUARD_GITFLOW_AUTOSYNC_INTERVAL:-300000}
|
|
25
|
-
export HOOK_GUARD_GITFLOW_AUTOSYNC_COOLDOWN=${HOOK_GUARD_GITFLOW_AUTOSYNC_COOLDOWN:-900000}
|
|
26
|
-
export HOOK_GUARD_GITFLOW_AUTOCLEAN=${HOOK_GUARD_GITFLOW_AUTOCLEAN:-true}
|
|
27
|
-
export HOOK_GUARD_GITFLOW_MAIN_BRANCH=${HOOK_GUARD_GITFLOW_MAIN_BRANCH:-main}
|
|
28
|
-
export HOOK_GUARD_GITFLOW_DEVELOP_BRANCH=${HOOK_GUARD_GITFLOW_DEVELOP_BRANCH:-develop}
|
|
29
|
-
export HOOK_GUARD_GITFLOW_REQUIRE_CLEAN=${HOOK_GUARD_GITFLOW_REQUIRE_CLEAN:-true}
|
|
30
|
-
export GUARD_AUTOSTART_HEALTHY_INTERVAL=${GUARD_AUTOSTART_HEALTHY_INTERVAL:-0}
|
|
31
|
-
export GUARD_AUTOSTART_HEALTHY_COOLDOWN=${GUARD_AUTOSTART_HEALTHY_COOLDOWN:-900000}
|
|
32
|
-
export HOOK_GUARD_HEARTBEAT_PATH="${HOOK_GUARD_HEARTBEAT_PATH:-.audit_tmp/guard-heartbeat.json}"
|
|
33
|
-
export HOOK_GUARD_HEARTBEAT_INTERVAL=${HOOK_GUARD_HEARTBEAT_INTERVAL:-15000}
|
|
34
|
-
export HOOK_GUARD_HEARTBEAT_MAX_AGE=${HOOK_GUARD_HEARTBEAT_MAX_AGE:-45000}
|
|
35
|
-
export HOOK_GUARD_HEARTBEAT_CHECK_INTERVAL=${HOOK_GUARD_HEARTBEAT_CHECK_INTERVAL:-15000}
|
|
36
|
-
export HOOK_GUARD_HEARTBEAT_NOTIFY_COOLDOWN=${HOOK_GUARD_HEARTBEAT_NOTIFY_COOLDOWN:-180000}
|
|
37
|
-
export HOOK_GUARD_GITFLOW_MONITOR=${HOOK_GUARD_GITFLOW_MONITOR:-true}
|
|
38
|
-
export HOOK_GUARD_GITFLOW_MONITOR_INTERVAL=${HOOK_GUARD_GITFLOW_MONITOR_INTERVAL:-300000}
|
|
39
|
-
export HOOK_GUARD_GITFLOW_BRANCH_COOLDOWN=${HOOK_GUARD_GITFLOW_BRANCH_COOLDOWN:-900000}
|
|
40
|
-
export HOOK_GUARD_DEV_DOCS_AUTO_REFRESH=${HOOK_GUARD_DEV_DOCS_AUTO_REFRESH:-true}
|
|
12
|
+
IMPL="$REPO_ROOT/node_modules/pumuki-ast-hooks/scripts/hooks-system/bin/guard-env.sh"
|
|
13
|
+
if [[ -f "$IMPL" ]]; then
|
|
14
|
+
# shellcheck disable=SC1090
|
|
15
|
+
source "$IMPL"
|
|
16
|
+
return 0 2>/dev/null || exit 0
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
echo "guard-env.sh implementation not found. Please reinstall dependencies." >&2
|
|
20
|
+
return 1 2>/dev/null || exit 1
|