@dotsetlabs/tollgate 0.2.2 → 0.3.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/README.md +138 -0
- package/dist/analyzers/filesystem.d.ts +5 -0
- package/dist/analyzers/filesystem.d.ts.map +1 -1
- package/dist/analyzers/filesystem.js +61 -7
- package/dist/analyzers/filesystem.js.map +1 -1
- package/dist/analyzers/loader.d.ts +5 -0
- package/dist/analyzers/loader.d.ts.map +1 -1
- package/dist/analyzers/loader.js +112 -6
- package/dist/analyzers/loader.js.map +1 -1
- package/dist/analyzers/prompt-injection.d.ts +1 -0
- package/dist/analyzers/prompt-injection.d.ts.map +1 -1
- package/dist/analyzers/prompt-injection.js +48 -2
- package/dist/analyzers/prompt-injection.js.map +1 -1
- package/dist/analyzers/shell.d.ts +8 -0
- package/dist/analyzers/shell.d.ts.map +1 -1
- package/dist/analyzers/shell.js +109 -8
- package/dist/analyzers/shell.js.map +1 -1
- package/dist/analyzers/sql.d.ts.map +1 -1
- package/dist/analyzers/sql.js +8 -7
- package/dist/analyzers/sql.js.map +1 -1
- package/dist/approval/interactive.d.ts +1 -1
- package/dist/approval/interactive.d.ts.map +1 -1
- package/dist/approval/interactive.js +13 -1
- package/dist/approval/interactive.js.map +1 -1
- package/dist/approval/rate-limiter.d.ts +115 -0
- package/dist/approval/rate-limiter.d.ts.map +1 -0
- package/dist/approval/rate-limiter.js +200 -0
- package/dist/approval/rate-limiter.js.map +1 -0
- package/dist/approval/url-validator.d.ts +51 -0
- package/dist/approval/url-validator.d.ts.map +1 -0
- package/dist/approval/url-validator.js +184 -0
- package/dist/approval/url-validator.js.map +1 -0
- package/dist/approval/webhook.d.ts +48 -0
- package/dist/approval/webhook.d.ts.map +1 -1
- package/dist/approval/webhook.js +89 -0
- package/dist/approval/webhook.js.map +1 -1
- package/dist/audit/integrity.d.ts +107 -0
- package/dist/audit/integrity.d.ts.map +1 -0
- package/dist/audit/integrity.js +191 -0
- package/dist/audit/integrity.js.map +1 -0
- package/dist/audit/logger.d.ts.map +1 -1
- package/dist/audit/logger.js +6 -5
- package/dist/audit/logger.js.map +1 -1
- package/dist/audit/redaction.js +6 -4
- package/dist/audit/redaction.js.map +1 -1
- package/dist/cli/commands/guard.d.ts +97 -0
- package/dist/cli/commands/guard.d.ts.map +1 -0
- package/dist/cli/commands/guard.js +456 -0
- package/dist/cli/commands/guard.js.map +1 -0
- package/dist/cli/commands/serve.js +1 -1
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/index.js +3 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/input-validation.d.ts +83 -0
- package/dist/cli/input-validation.d.ts.map +1 -0
- package/dist/cli/input-validation.js +237 -0
- package/dist/cli/input-validation.js.map +1 -0
- package/dist/cli/ui.js +2 -2
- package/dist/cli/ui.js.map +1 -1
- package/dist/guard/alternatives/index.d.ts +68 -0
- package/dist/guard/alternatives/index.d.ts.map +1 -0
- package/dist/guard/alternatives/index.js +224 -0
- package/dist/guard/alternatives/index.js.map +1 -0
- package/dist/guard/alternatives/registry.d.ts +16 -0
- package/dist/guard/alternatives/registry.d.ts.map +1 -0
- package/dist/guard/alternatives/registry.js +518 -0
- package/dist/guard/alternatives/registry.js.map +1 -0
- package/dist/guard/alternatives/types.d.ts +86 -0
- package/dist/guard/alternatives/types.d.ts.map +1 -0
- package/dist/guard/alternatives/types.js +5 -0
- package/dist/guard/alternatives/types.js.map +1 -0
- package/dist/guard/approval/enhanced-terminal.d.ts +110 -0
- package/dist/guard/approval/enhanced-terminal.d.ts.map +1 -0
- package/dist/guard/approval/enhanced-terminal.js +387 -0
- package/dist/guard/approval/enhanced-terminal.js.map +1 -0
- package/dist/guard/config.d.ts +80 -0
- package/dist/guard/config.d.ts.map +1 -0
- package/dist/guard/config.js +260 -0
- package/dist/guard/config.js.map +1 -0
- package/dist/guard/context/directory.d.ts +35 -0
- package/dist/guard/context/directory.d.ts.map +1 -0
- package/dist/guard/context/directory.js +243 -0
- package/dist/guard/context/directory.js.map +1 -0
- package/dist/guard/context/environment.d.ts +31 -0
- package/dist/guard/context/environment.d.ts.map +1 -0
- package/dist/guard/context/environment.js +204 -0
- package/dist/guard/context/environment.js.map +1 -0
- package/dist/guard/context/git.d.ts +52 -0
- package/dist/guard/context/git.d.ts.map +1 -0
- package/dist/guard/context/git.js +278 -0
- package/dist/guard/context/git.js.map +1 -0
- package/dist/guard/context/index.d.ts +64 -0
- package/dist/guard/context/index.d.ts.map +1 -0
- package/dist/guard/context/index.js +227 -0
- package/dist/guard/context/index.js.map +1 -0
- package/dist/guard/context/project.d.ts +47 -0
- package/dist/guard/context/project.d.ts.map +1 -0
- package/dist/guard/context/project.js +281 -0
- package/dist/guard/context/project.js.map +1 -0
- package/dist/guard/context/types.d.ts +152 -0
- package/dist/guard/context/types.d.ts.map +1 -0
- package/dist/guard/context/types.js +7 -0
- package/dist/guard/context/types.js.map +1 -0
- package/dist/guard/engine.d.ts +107 -0
- package/dist/guard/engine.d.ts.map +1 -0
- package/dist/guard/engine.js +430 -0
- package/dist/guard/engine.js.map +1 -0
- package/dist/guard/enhanced-engine.d.ts +151 -0
- package/dist/guard/enhanced-engine.d.ts.map +1 -0
- package/dist/guard/enhanced-engine.js +622 -0
- package/dist/guard/enhanced-engine.js.map +1 -0
- package/dist/guard/hooks/index.d.ts +50 -0
- package/dist/guard/hooks/index.d.ts.map +1 -0
- package/dist/guard/hooks/index.js +325 -0
- package/dist/guard/hooks/index.js.map +1 -0
- package/dist/guard/index.d.ts +29 -0
- package/dist/guard/index.d.ts.map +1 -0
- package/dist/guard/index.js +31 -0
- package/dist/guard/index.js.map +1 -0
- package/dist/guard/learning/index.d.ts +136 -0
- package/dist/guard/learning/index.d.ts.map +1 -0
- package/dist/guard/learning/index.js +314 -0
- package/dist/guard/learning/index.js.map +1 -0
- package/dist/guard/learning/pattern-extractor.d.ts +50 -0
- package/dist/guard/learning/pattern-extractor.d.ts.map +1 -0
- package/dist/guard/learning/pattern-extractor.js +372 -0
- package/dist/guard/learning/pattern-extractor.js.map +1 -0
- package/dist/guard/learning/rule-suggester.d.ts +67 -0
- package/dist/guard/learning/rule-suggester.d.ts.map +1 -0
- package/dist/guard/learning/rule-suggester.js +345 -0
- package/dist/guard/learning/rule-suggester.js.map +1 -0
- package/dist/guard/learning/types.d.ts +211 -0
- package/dist/guard/learning/types.d.ts.map +1 -0
- package/dist/guard/learning/types.js +18 -0
- package/dist/guard/learning/types.js.map +1 -0
- package/dist/guard/preview/effects.d.ts +15 -0
- package/dist/guard/preview/effects.d.ts.map +1 -0
- package/dist/guard/preview/effects.js +413 -0
- package/dist/guard/preview/effects.js.map +1 -0
- package/dist/guard/preview/index.d.ts +49 -0
- package/dist/guard/preview/index.d.ts.map +1 -0
- package/dist/guard/preview/index.js +196 -0
- package/dist/guard/preview/index.js.map +1 -0
- package/dist/guard/preview/parser.d.ts +34 -0
- package/dist/guard/preview/parser.d.ts.map +1 -0
- package/dist/guard/preview/parser.js +292 -0
- package/dist/guard/preview/parser.js.map +1 -0
- package/dist/guard/preview/types.d.ts +140 -0
- package/dist/guard/preview/types.d.ts.map +1 -0
- package/dist/guard/preview/types.js +5 -0
- package/dist/guard/preview/types.js.map +1 -0
- package/dist/guard/reversibility/index.d.ts +88 -0
- package/dist/guard/reversibility/index.d.ts.map +1 -0
- package/dist/guard/reversibility/index.js +310 -0
- package/dist/guard/reversibility/index.js.map +1 -0
- package/dist/guard/types.d.ts +192 -0
- package/dist/guard/types.d.ts.map +1 -0
- package/dist/guard/types.js +8 -0
- package/dist/guard/types.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -1
- package/dist/orchestrator/manager.d.ts.map +1 -1
- package/dist/orchestrator/manager.js +6 -1
- package/dist/orchestrator/manager.js.map +1 -1
- package/dist/policy/engine.d.ts.map +1 -1
- package/dist/policy/engine.js +11 -3
- package/dist/policy/engine.js.map +1 -1
- package/dist/policy/parser.d.ts.map +1 -1
- package/dist/policy/parser.js +3 -0
- package/dist/policy/parser.js.map +1 -1
- package/dist/proxy/server.d.ts.map +1 -1
- package/dist/proxy/server.js +8 -6
- package/dist/proxy/server.js.map +1 -1
- package/dist/session/manager.d.ts +2 -2
- package/dist/session/manager.d.ts.map +1 -1
- package/dist/session/manager.js +106 -88
- package/dist/session/manager.js.map +1 -1
- package/dist/session/signing.d.ts +88 -0
- package/dist/session/signing.d.ts.map +1 -0
- package/dist/session/signing.js +166 -0
- package/dist/session/signing.js.map +1 -0
- package/dist/session/types.d.ts +2 -0
- package/dist/session/types.d.ts.map +1 -1
- package/dist/session/types.js.map +1 -1
- package/dist/utils/security-logger.d.ts +146 -0
- package/dist/utils/security-logger.d.ts.map +1 -0
- package/dist/utils/security-logger.js +222 -0
- package/dist/utils/security-logger.js.map +1 -0
- package/dist/wizard.d.ts.map +1 -1
- package/dist/wizard.js +7 -1
- package/dist/wizard.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Module for Shell Guardian
|
|
3
|
+
*
|
|
4
|
+
* Aggregates context from multiple providers to enable
|
|
5
|
+
* intelligent, context-aware command risk assessment.
|
|
6
|
+
*/
|
|
7
|
+
import { resolve } from 'node:path';
|
|
8
|
+
import { detectProject, isRegenerablePath } from './project.js';
|
|
9
|
+
import { getGitContext, wouldAffectUncommittedWork } from './git.js';
|
|
10
|
+
import { scoreSensitivity, getSensitivePathsAffected, getSensitivityRiskModifier } from './directory.js';
|
|
11
|
+
import { detectEnvironment, getEnvironmentRiskModifier } from './environment.js';
|
|
12
|
+
// Re-export utility functions
|
|
13
|
+
export { detectProject, isRegenerablePath, isSourcePath, isInProject, PROJECT_SIGNATURES, } from './project.js';
|
|
14
|
+
export { getGitContext, getAffectedTrackedFiles, wouldAffectUncommittedWork, isTrackedFile, hasUncommittedChangesInPaths, canRecoverFromGit, } from './git.js';
|
|
15
|
+
export { scoreSensitivity, getSensitivePathsAffected, getSensitivityRiskModifier, getSensitivityDescription, requiresExtraConfirmation, } from './directory.js';
|
|
16
|
+
export { detectEnvironment, getEnvironmentRiskModifier, requiresExtraCaution, getEnvironmentWarning, shouldBlockDestructive, } from './environment.js';
|
|
17
|
+
/**
|
|
18
|
+
* Default context provider options.
|
|
19
|
+
*/
|
|
20
|
+
const DEFAULT_OPTIONS = {
|
|
21
|
+
maxProjectSearchDepth: 10,
|
|
22
|
+
includeGit: true,
|
|
23
|
+
includeEnvironment: true,
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Context provider that aggregates information from all sources.
|
|
27
|
+
*/
|
|
28
|
+
export class ContextProvider {
|
|
29
|
+
options;
|
|
30
|
+
environmentCache;
|
|
31
|
+
constructor(options) {
|
|
32
|
+
this.options = { ...DEFAULT_OPTIONS, ...options };
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Enhance a basic guard context with rich contextual information.
|
|
36
|
+
*
|
|
37
|
+
* @param basicContext - The basic command context
|
|
38
|
+
* @returns Enhanced context with project, git, directory, and environment info
|
|
39
|
+
*/
|
|
40
|
+
async enhance(basicContext) {
|
|
41
|
+
const startTime = Date.now();
|
|
42
|
+
const warnings = [];
|
|
43
|
+
const cwd = basicContext.cwd || process.cwd();
|
|
44
|
+
// Gather context from all providers
|
|
45
|
+
const [project, git, directory, environment] = await Promise.all([
|
|
46
|
+
this.getProjectContext(cwd),
|
|
47
|
+
this.options.includeGit ? this.getGitContextSafe(cwd, warnings) : undefined,
|
|
48
|
+
this.getDirectoryContext(cwd, basicContext.command),
|
|
49
|
+
this.options.includeEnvironment ? this.getEnvironmentContext() : undefined,
|
|
50
|
+
]);
|
|
51
|
+
// Enhance directory context with project info
|
|
52
|
+
const enhancedDirectory = project
|
|
53
|
+
? this.enhanceDirectoryWithProject(directory, project)
|
|
54
|
+
: directory;
|
|
55
|
+
const context = {
|
|
56
|
+
command: basicContext.command,
|
|
57
|
+
shell: basicContext.shell,
|
|
58
|
+
cwd,
|
|
59
|
+
dryRun: basicContext.dryRun,
|
|
60
|
+
project,
|
|
61
|
+
git,
|
|
62
|
+
directory: enhancedDirectory,
|
|
63
|
+
environment,
|
|
64
|
+
};
|
|
65
|
+
return {
|
|
66
|
+
context,
|
|
67
|
+
gatherTimeMs: Date.now() - startTime,
|
|
68
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get project context.
|
|
73
|
+
*/
|
|
74
|
+
async getProjectContext(cwd) {
|
|
75
|
+
try {
|
|
76
|
+
return detectProject(cwd, this.options.maxProjectSearchDepth);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get git context with error handling.
|
|
84
|
+
*/
|
|
85
|
+
async getGitContextSafe(cwd, warnings) {
|
|
86
|
+
try {
|
|
87
|
+
return getGitContext(cwd);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
warnings.push(`Failed to get git context: ${error}`);
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get directory context for the command's targets.
|
|
96
|
+
*/
|
|
97
|
+
getDirectoryContext(cwd, command) {
|
|
98
|
+
// Extract target paths from command
|
|
99
|
+
const targets = extractTargetPaths(command, cwd);
|
|
100
|
+
if (targets.length === 0) {
|
|
101
|
+
// Use cwd if no targets found
|
|
102
|
+
return scoreSensitivity(cwd);
|
|
103
|
+
}
|
|
104
|
+
// Score the most sensitive target
|
|
105
|
+
let mostSensitive = scoreSensitivity(targets[0]);
|
|
106
|
+
for (const target of targets.slice(1)) {
|
|
107
|
+
const targetSensitivity = scoreSensitivity(target);
|
|
108
|
+
if (targetSensitivity.sensitivity > mostSensitive.sensitivity) {
|
|
109
|
+
mostSensitive = targetSensitivity;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Add all sensitive paths that would be affected
|
|
113
|
+
const allSensitivePaths = new Set();
|
|
114
|
+
for (const target of targets) {
|
|
115
|
+
const affected = getSensitivePathsAffected(target);
|
|
116
|
+
affected.forEach(p => allSensitivePaths.add(p));
|
|
117
|
+
}
|
|
118
|
+
if (allSensitivePaths.size > 0) {
|
|
119
|
+
mostSensitive.sensitivePaths = Array.from(allSensitivePaths);
|
|
120
|
+
}
|
|
121
|
+
return mostSensitive;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get environment context (cached).
|
|
125
|
+
*/
|
|
126
|
+
getEnvironmentContext() {
|
|
127
|
+
if (!this.environmentCache) {
|
|
128
|
+
this.environmentCache = detectEnvironment();
|
|
129
|
+
}
|
|
130
|
+
return this.environmentCache;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Enhance directory context with project information.
|
|
134
|
+
*/
|
|
135
|
+
enhanceDirectoryWithProject(directory, project) {
|
|
136
|
+
const enhanced = { ...directory };
|
|
137
|
+
// Check if in project
|
|
138
|
+
if (directory.sensitivePaths) {
|
|
139
|
+
for (const path of directory.sensitivePaths) {
|
|
140
|
+
if (isRegenerablePath(path, project)) {
|
|
141
|
+
enhanced.sensitivity = Math.min(enhanced.sensitivity, 10);
|
|
142
|
+
enhanced.sensitivityReasons.push('Path is in regenerable directory');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
enhanced.isInProject = true;
|
|
147
|
+
return enhanced;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Extract target paths from a command.
|
|
152
|
+
* This is a simple extraction - more sophisticated parsing is in the preview module.
|
|
153
|
+
*/
|
|
154
|
+
function extractTargetPaths(command, cwd) {
|
|
155
|
+
const targets = [];
|
|
156
|
+
// Common patterns for commands with file targets
|
|
157
|
+
const patterns = [
|
|
158
|
+
// rm, mv, cp, chmod, chown, etc.
|
|
159
|
+
/(?:rm|mv|cp|chmod|chown|touch|mkdir|rmdir)\s+(?:-[a-zA-Z]+\s+)*(.+)/,
|
|
160
|
+
// git commands with paths
|
|
161
|
+
/git\s+(?:rm|add|checkout|restore)\s+(?:-[a-zA-Z]+\s+)*(.+)/,
|
|
162
|
+
// find with -delete or -exec rm
|
|
163
|
+
/find\s+(\S+)/,
|
|
164
|
+
];
|
|
165
|
+
for (const pattern of patterns) {
|
|
166
|
+
const match = command.match(pattern);
|
|
167
|
+
if (match && match[1]) {
|
|
168
|
+
// Split by spaces, handling quoted strings simply
|
|
169
|
+
const args = match[1].trim().split(/\s+/);
|
|
170
|
+
for (const arg of args) {
|
|
171
|
+
// Skip flags
|
|
172
|
+
if (arg.startsWith('-'))
|
|
173
|
+
continue;
|
|
174
|
+
// Skip common non-path arguments
|
|
175
|
+
if (arg === '.' || arg === '..') {
|
|
176
|
+
targets.push(resolve(cwd, arg));
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
// Resolve relative paths
|
|
180
|
+
const resolved = arg.startsWith('/') ? arg : resolve(cwd, arg);
|
|
181
|
+
targets.push(resolved);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return targets;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Calculate overall risk modifier based on all context.
|
|
189
|
+
*
|
|
190
|
+
* @param context - Enhanced guard context
|
|
191
|
+
* @returns Risk modifier multiplier (1.0 = normal, >1 = higher risk, <1 = lower risk)
|
|
192
|
+
*/
|
|
193
|
+
export function calculateRiskModifier(context) {
|
|
194
|
+
let modifier = 1.0;
|
|
195
|
+
// Directory sensitivity
|
|
196
|
+
if (context.directory) {
|
|
197
|
+
modifier *= getSensitivityRiskModifier(context.directory);
|
|
198
|
+
}
|
|
199
|
+
// Environment risk
|
|
200
|
+
if (context.environment) {
|
|
201
|
+
modifier *= getEnvironmentRiskModifier(context.environment);
|
|
202
|
+
}
|
|
203
|
+
// Reduce risk for regenerable paths in projects
|
|
204
|
+
if (context.project && context.directory) {
|
|
205
|
+
const targets = extractTargetPaths(context.command, context.cwd || process.cwd());
|
|
206
|
+
const allRegenerable = targets.every(t => isRegenerablePath(t, context.project));
|
|
207
|
+
if (allRegenerable && targets.length > 0) {
|
|
208
|
+
modifier *= 0.3; // Significantly reduce risk
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
// Increase risk if uncommitted work would be affected
|
|
212
|
+
if (context.git?.hasUncommittedChanges) {
|
|
213
|
+
const targets = extractTargetPaths(context.command, context.cwd || process.cwd());
|
|
214
|
+
const { affected } = wouldAffectUncommittedWork(targets, context.git);
|
|
215
|
+
if (affected) {
|
|
216
|
+
modifier *= 1.5;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return modifier;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Create a context provider with default options.
|
|
223
|
+
*/
|
|
224
|
+
export function createContextProvider(options) {
|
|
225
|
+
return new ContextProvider(options);
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/guard/context/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Detection for Shell Guardian
|
|
3
|
+
*
|
|
4
|
+
* Detects project type and structure to enable context-aware risk assessment.
|
|
5
|
+
*/
|
|
6
|
+
import type { ProjectContext, ProjectType, ProjectSignature } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Project signatures for detection.
|
|
9
|
+
*/
|
|
10
|
+
export declare const PROJECT_SIGNATURES: Record<ProjectType, ProjectSignature>;
|
|
11
|
+
/**
|
|
12
|
+
* Detect project type and context from a directory.
|
|
13
|
+
*
|
|
14
|
+
* @param cwd - Current working directory
|
|
15
|
+
* @param maxDepth - Maximum depth to search upward for project root
|
|
16
|
+
* @returns Project context if detected, undefined otherwise
|
|
17
|
+
*/
|
|
18
|
+
export declare function detectProject(cwd: string, maxDepth?: number): ProjectContext | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Check if a path is within a regenerable directory.
|
|
21
|
+
*
|
|
22
|
+
* @param targetPath - Path to check
|
|
23
|
+
* @param project - Project context
|
|
24
|
+
* @returns Whether the path can be regenerated
|
|
25
|
+
*/
|
|
26
|
+
export declare function isRegenerablePath(targetPath: string, project: ProjectContext): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Check if a path is within a source directory.
|
|
29
|
+
*
|
|
30
|
+
* @param targetPath - Path to check
|
|
31
|
+
* @param project - Project context
|
|
32
|
+
* @returns Whether the path is source code
|
|
33
|
+
*/
|
|
34
|
+
export declare function isSourcePath(targetPath: string, project: ProjectContext): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Get the regenerate command for a project.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getRegenerateCommand(project: ProjectContext): string | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Check if a path is within the project.
|
|
41
|
+
*/
|
|
42
|
+
export declare function isInProject(targetPath: string, project: ProjectContext): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Get relative path from project root.
|
|
45
|
+
*/
|
|
46
|
+
export declare function getProjectRelativePath(targetPath: string, project: ProjectContext): string;
|
|
47
|
+
//# sourceMappingURL=project.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../src/guard/context/project.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEhF;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,WAAW,EAAE,gBAAgB,CA+DpE,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,SAAK,GAAG,cAAc,GAAG,SAAS,CA4CpF;AA8GD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAwBtF;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAcjF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS,CAEhF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAOhF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAE1F"}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Detection for Shell Guardian
|
|
3
|
+
*
|
|
4
|
+
* Detects project type and structure to enable context-aware risk assessment.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
7
|
+
import { join, dirname, basename, resolve, relative } from 'node:path';
|
|
8
|
+
/**
|
|
9
|
+
* Project signatures for detection.
|
|
10
|
+
*/
|
|
11
|
+
export const PROJECT_SIGNATURES = {
|
|
12
|
+
nodejs: {
|
|
13
|
+
manifestFiles: ['package.json'],
|
|
14
|
+
lockFiles: ['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb'],
|
|
15
|
+
regenerableDirs: ['node_modules', '.npm', '.yarn', '.pnpm-store'],
|
|
16
|
+
sourceDirs: ['src', 'lib', 'app', 'pages', 'components'],
|
|
17
|
+
regenerateCommand: 'npm install',
|
|
18
|
+
},
|
|
19
|
+
python: {
|
|
20
|
+
manifestFiles: ['pyproject.toml', 'setup.py', 'setup.cfg'],
|
|
21
|
+
lockFiles: ['poetry.lock', 'Pipfile.lock', 'requirements.txt'],
|
|
22
|
+
regenerableDirs: ['.venv', 'venv', 'env', '__pycache__', '.pytest_cache', '*.egg-info', '.mypy_cache', '.ruff_cache'],
|
|
23
|
+
sourceDirs: ['src', 'lib'],
|
|
24
|
+
regenerateCommand: 'pip install -e .',
|
|
25
|
+
},
|
|
26
|
+
go: {
|
|
27
|
+
manifestFiles: ['go.mod'],
|
|
28
|
+
lockFiles: ['go.sum'],
|
|
29
|
+
regenerableDirs: ['vendor'],
|
|
30
|
+
sourceDirs: ['cmd', 'pkg', 'internal'],
|
|
31
|
+
regenerateCommand: 'go mod download',
|
|
32
|
+
},
|
|
33
|
+
rust: {
|
|
34
|
+
manifestFiles: ['Cargo.toml'],
|
|
35
|
+
lockFiles: ['Cargo.lock'],
|
|
36
|
+
regenerableDirs: ['target'],
|
|
37
|
+
sourceDirs: ['src'],
|
|
38
|
+
regenerateCommand: 'cargo build',
|
|
39
|
+
},
|
|
40
|
+
ruby: {
|
|
41
|
+
manifestFiles: ['Gemfile'],
|
|
42
|
+
lockFiles: ['Gemfile.lock'],
|
|
43
|
+
regenerableDirs: ['vendor/bundle', '.bundle'],
|
|
44
|
+
sourceDirs: ['lib', 'app'],
|
|
45
|
+
regenerateCommand: 'bundle install',
|
|
46
|
+
},
|
|
47
|
+
java: {
|
|
48
|
+
manifestFiles: ['pom.xml', 'build.gradle', 'build.gradle.kts'],
|
|
49
|
+
lockFiles: ['gradle.lockfile'],
|
|
50
|
+
regenerableDirs: ['target', 'build', '.gradle'],
|
|
51
|
+
sourceDirs: ['src/main/java', 'src/main/kotlin'],
|
|
52
|
+
regenerateCommand: 'mvn install',
|
|
53
|
+
},
|
|
54
|
+
dotnet: {
|
|
55
|
+
manifestFiles: ['*.csproj', '*.fsproj', '*.sln'],
|
|
56
|
+
lockFiles: ['packages.lock.json'],
|
|
57
|
+
regenerableDirs: ['bin', 'obj', 'packages'],
|
|
58
|
+
sourceDirs: ['src'],
|
|
59
|
+
regenerateCommand: 'dotnet restore',
|
|
60
|
+
},
|
|
61
|
+
php: {
|
|
62
|
+
manifestFiles: ['composer.json'],
|
|
63
|
+
lockFiles: ['composer.lock'],
|
|
64
|
+
regenerableDirs: ['vendor'],
|
|
65
|
+
sourceDirs: ['src', 'app'],
|
|
66
|
+
regenerateCommand: 'composer install',
|
|
67
|
+
},
|
|
68
|
+
unknown: {
|
|
69
|
+
manifestFiles: [],
|
|
70
|
+
lockFiles: [],
|
|
71
|
+
regenerableDirs: [],
|
|
72
|
+
sourceDirs: [],
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Detect project type and context from a directory.
|
|
77
|
+
*
|
|
78
|
+
* @param cwd - Current working directory
|
|
79
|
+
* @param maxDepth - Maximum depth to search upward for project root
|
|
80
|
+
* @returns Project context if detected, undefined otherwise
|
|
81
|
+
*/
|
|
82
|
+
export function detectProject(cwd, maxDepth = 10) {
|
|
83
|
+
const resolvedCwd = resolve(cwd);
|
|
84
|
+
let currentDir = resolvedCwd;
|
|
85
|
+
let depth = 0;
|
|
86
|
+
while (depth < maxDepth) {
|
|
87
|
+
// Check each project type
|
|
88
|
+
for (const [type, signature] of Object.entries(PROJECT_SIGNATURES)) {
|
|
89
|
+
if (type === 'unknown')
|
|
90
|
+
continue;
|
|
91
|
+
for (const manifest of signature.manifestFiles) {
|
|
92
|
+
// Handle glob patterns like *.csproj
|
|
93
|
+
if (manifest.includes('*')) {
|
|
94
|
+
const files = findMatchingFiles(currentDir, manifest);
|
|
95
|
+
if (files.length > 0) {
|
|
96
|
+
return createProjectContext(type, currentDir, files[0], signature);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
const manifestPath = join(currentDir, manifest);
|
|
101
|
+
if (existsSync(manifestPath)) {
|
|
102
|
+
return createProjectContext(type, currentDir, manifestPath, signature);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Move up one directory
|
|
108
|
+
const parent = dirname(currentDir);
|
|
109
|
+
if (parent === currentDir)
|
|
110
|
+
break; // Reached root
|
|
111
|
+
currentDir = parent;
|
|
112
|
+
depth++;
|
|
113
|
+
}
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Create a project context from detected information.
|
|
118
|
+
*/
|
|
119
|
+
function createProjectContext(type, root, manifestPath, signature) {
|
|
120
|
+
// Find lock file
|
|
121
|
+
let lockfilePath;
|
|
122
|
+
for (const lockFile of signature.lockFiles) {
|
|
123
|
+
const path = join(root, lockFile);
|
|
124
|
+
if (existsSync(path)) {
|
|
125
|
+
lockfilePath = path;
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Get project name from manifest
|
|
130
|
+
const name = extractProjectName(manifestPath, type);
|
|
131
|
+
// Resolve regenerable directories relative to project root
|
|
132
|
+
const regenerableDirs = signature.regenerableDirs.map(dir => {
|
|
133
|
+
// Handle glob patterns
|
|
134
|
+
if (dir.includes('*')) {
|
|
135
|
+
return dir; // Keep as pattern for later matching
|
|
136
|
+
}
|
|
137
|
+
return join(root, dir);
|
|
138
|
+
});
|
|
139
|
+
// Resolve source directories
|
|
140
|
+
const sourceDirs = signature.sourceDirs
|
|
141
|
+
.map(dir => join(root, dir))
|
|
142
|
+
.filter(dir => existsSync(dir));
|
|
143
|
+
return {
|
|
144
|
+
type,
|
|
145
|
+
root,
|
|
146
|
+
manifestPath,
|
|
147
|
+
lockfilePath,
|
|
148
|
+
regenerableDirs,
|
|
149
|
+
sourceDirs,
|
|
150
|
+
name,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Extract project name from manifest file.
|
|
155
|
+
*/
|
|
156
|
+
function extractProjectName(manifestPath, type) {
|
|
157
|
+
try {
|
|
158
|
+
const content = readFileSync(manifestPath, 'utf8');
|
|
159
|
+
switch (type) {
|
|
160
|
+
case 'nodejs': {
|
|
161
|
+
const pkg = JSON.parse(content);
|
|
162
|
+
return pkg.name;
|
|
163
|
+
}
|
|
164
|
+
case 'python': {
|
|
165
|
+
// Try pyproject.toml format
|
|
166
|
+
const nameMatch = content.match(/^name\s*=\s*["']([^"']+)["']/m);
|
|
167
|
+
return nameMatch?.[1];
|
|
168
|
+
}
|
|
169
|
+
case 'go': {
|
|
170
|
+
const moduleMatch = content.match(/^module\s+(\S+)/m);
|
|
171
|
+
if (moduleMatch) {
|
|
172
|
+
// Return last part of module path
|
|
173
|
+
return moduleMatch[1].split('/').pop();
|
|
174
|
+
}
|
|
175
|
+
return undefined;
|
|
176
|
+
}
|
|
177
|
+
case 'rust': {
|
|
178
|
+
const nameMatch = content.match(/^name\s*=\s*["']([^"']+)["']/m);
|
|
179
|
+
return nameMatch?.[1];
|
|
180
|
+
}
|
|
181
|
+
case 'ruby': {
|
|
182
|
+
// Gemfile doesn't typically have a name
|
|
183
|
+
return basename(dirname(manifestPath));
|
|
184
|
+
}
|
|
185
|
+
case 'php': {
|
|
186
|
+
const composer = JSON.parse(content);
|
|
187
|
+
return composer.name;
|
|
188
|
+
}
|
|
189
|
+
default:
|
|
190
|
+
return basename(dirname(manifestPath));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Find files matching a glob pattern in a directory.
|
|
199
|
+
*/
|
|
200
|
+
function findMatchingFiles(dir, pattern) {
|
|
201
|
+
try {
|
|
202
|
+
const { readdirSync } = require('node:fs');
|
|
203
|
+
const files = readdirSync(dir);
|
|
204
|
+
const regex = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$');
|
|
205
|
+
return files
|
|
206
|
+
.filter(f => regex.test(f))
|
|
207
|
+
.map(f => join(dir, f));
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
return [];
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Check if a path is within a regenerable directory.
|
|
215
|
+
*
|
|
216
|
+
* @param targetPath - Path to check
|
|
217
|
+
* @param project - Project context
|
|
218
|
+
* @returns Whether the path can be regenerated
|
|
219
|
+
*/
|
|
220
|
+
export function isRegenerablePath(targetPath, project) {
|
|
221
|
+
const resolvedTarget = resolve(targetPath);
|
|
222
|
+
for (const regenerableDir of project.regenerableDirs) {
|
|
223
|
+
// Handle glob patterns
|
|
224
|
+
if (regenerableDir.includes('*')) {
|
|
225
|
+
const pattern = regenerableDir.replace(/\*/g, '.*');
|
|
226
|
+
const regex = new RegExp(pattern);
|
|
227
|
+
if (regex.test(basename(resolvedTarget)) || regex.test(resolvedTarget)) {
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
const resolvedRegenerable = resolve(regenerableDir);
|
|
233
|
+
// Check if target is the regenerable dir or inside it
|
|
234
|
+
if (resolvedTarget === resolvedRegenerable ||
|
|
235
|
+
resolvedTarget.startsWith(resolvedRegenerable + '/')) {
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Check if a path is within a source directory.
|
|
244
|
+
*
|
|
245
|
+
* @param targetPath - Path to check
|
|
246
|
+
* @param project - Project context
|
|
247
|
+
* @returns Whether the path is source code
|
|
248
|
+
*/
|
|
249
|
+
export function isSourcePath(targetPath, project) {
|
|
250
|
+
const resolvedTarget = resolve(targetPath);
|
|
251
|
+
for (const sourceDir of project.sourceDirs) {
|
|
252
|
+
const resolvedSource = resolve(sourceDir);
|
|
253
|
+
if (resolvedTarget === resolvedSource ||
|
|
254
|
+
resolvedTarget.startsWith(resolvedSource + '/')) {
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Get the regenerate command for a project.
|
|
262
|
+
*/
|
|
263
|
+
export function getRegenerateCommand(project) {
|
|
264
|
+
return PROJECT_SIGNATURES[project.type]?.regenerateCommand;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Check if a path is within the project.
|
|
268
|
+
*/
|
|
269
|
+
export function isInProject(targetPath, project) {
|
|
270
|
+
const resolvedTarget = resolve(targetPath);
|
|
271
|
+
const resolvedRoot = resolve(project.root);
|
|
272
|
+
return (resolvedTarget === resolvedRoot ||
|
|
273
|
+
resolvedTarget.startsWith(resolvedRoot + '/'));
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Get relative path from project root.
|
|
277
|
+
*/
|
|
278
|
+
export function getProjectRelativePath(targetPath, project) {
|
|
279
|
+
return relative(project.root, resolve(targetPath));
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/guard/context/project.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGvE;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA0C;IACvE,MAAM,EAAE;QACN,aAAa,EAAE,CAAC,cAAc,CAAC;QAC/B,SAAS,EAAE,CAAC,mBAAmB,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,CAAC;QAC5E,eAAe,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC;QACjE,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,CAAC;QACxD,iBAAiB,EAAE,aAAa;KACjC;IACD,MAAM,EAAE;QACN,aAAa,EAAE,CAAC,gBAAgB,EAAE,UAAU,EAAE,WAAW,CAAC;QAC1D,SAAS,EAAE,CAAC,aAAa,EAAE,cAAc,EAAE,kBAAkB,CAAC;QAC9D,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,CAAC;QACrH,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;QAC1B,iBAAiB,EAAE,kBAAkB;KACtC;IACD,EAAE,EAAE;QACF,aAAa,EAAE,CAAC,QAAQ,CAAC;QACzB,SAAS,EAAE,CAAC,QAAQ,CAAC;QACrB,eAAe,EAAE,CAAC,QAAQ,CAAC;QAC3B,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC;QACtC,iBAAiB,EAAE,iBAAiB;KACrC;IACD,IAAI,EAAE;QACJ,aAAa,EAAE,CAAC,YAAY,CAAC;QAC7B,SAAS,EAAE,CAAC,YAAY,CAAC;QACzB,eAAe,EAAE,CAAC,QAAQ,CAAC;QAC3B,UAAU,EAAE,CAAC,KAAK,CAAC;QACnB,iBAAiB,EAAE,aAAa;KACjC;IACD,IAAI,EAAE;QACJ,aAAa,EAAE,CAAC,SAAS,CAAC;QAC1B,SAAS,EAAE,CAAC,cAAc,CAAC;QAC3B,eAAe,EAAE,CAAC,eAAe,EAAE,SAAS,CAAC;QAC7C,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;QAC1B,iBAAiB,EAAE,gBAAgB;KACpC;IACD,IAAI,EAAE;QACJ,aAAa,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,kBAAkB,CAAC;QAC9D,SAAS,EAAE,CAAC,iBAAiB,CAAC;QAC9B,eAAe,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC;QAC/C,UAAU,EAAE,CAAC,eAAe,EAAE,iBAAiB,CAAC;QAChD,iBAAiB,EAAE,aAAa;KACjC;IACD,MAAM,EAAE;QACN,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC;QAChD,SAAS,EAAE,CAAC,oBAAoB,CAAC;QACjC,eAAe,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC;QAC3C,UAAU,EAAE,CAAC,KAAK,CAAC;QACnB,iBAAiB,EAAE,gBAAgB;KACpC;IACD,GAAG,EAAE;QACH,aAAa,EAAE,CAAC,eAAe,CAAC;QAChC,SAAS,EAAE,CAAC,eAAe,CAAC;QAC5B,eAAe,EAAE,CAAC,QAAQ,CAAC;QAC3B,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;QAC1B,iBAAiB,EAAE,kBAAkB;KACtC;IACD,OAAO,EAAE;QACP,aAAa,EAAE,EAAE;QACjB,SAAS,EAAE,EAAE;QACb,eAAe,EAAE,EAAE;QACnB,UAAU,EAAE,EAAE;KACf;CACF,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,QAAQ,GAAG,EAAE;IACtD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,UAAU,GAAG,WAAW,CAAC;IAC7B,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,OAAO,KAAK,GAAG,QAAQ,EAAE,CAAC;QACxB,0BAA0B;QAC1B,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACnE,IAAI,IAAI,KAAK,SAAS;gBAAE,SAAS;YAEjC,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,aAAa,EAAE,CAAC;gBAC/C,qCAAqC;gBACrC,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC3B,MAAM,KAAK,GAAG,iBAAiB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;oBACtD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACrB,OAAO,oBAAoB,CACzB,IAAmB,EACnB,UAAU,EACV,KAAK,CAAC,CAAC,CAAE,EACT,SAAS,CACV,CAAC;oBACJ,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;oBAChD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;wBAC7B,OAAO,oBAAoB,CACzB,IAAmB,EACnB,UAAU,EACV,YAAY,EACZ,SAAS,CACV,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,wBAAwB;QACxB,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QACnC,IAAI,MAAM,KAAK,UAAU;YAAE,MAAM,CAAC,eAAe;QACjD,UAAU,GAAG,MAAM,CAAC;QACpB,KAAK,EAAE,CAAC;IACV,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAC3B,IAAiB,EACjB,IAAY,EACZ,YAAoB,EACpB,SAA2B;IAE3B,iBAAiB;IACjB,IAAI,YAAgC,CAAC;IACrC,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAClC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,YAAY,GAAG,IAAI,CAAC;YACpB,MAAM;QACR,CAAC;IACH,CAAC;IAED,iCAAiC;IACjC,MAAM,IAAI,GAAG,kBAAkB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAEpD,2DAA2D;IAC3D,MAAM,eAAe,GAAG,SAAS,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QAC1D,uBAAuB;QACvB,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,GAAG,CAAC,CAAC,qCAAqC;QACnD,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,6BAA6B;IAC7B,MAAM,UAAU,GAAG,SAAS,CAAC,UAAU;SACpC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;SAC3B,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAElC,OAAO;QACL,IAAI;QACJ,IAAI;QACJ,YAAY;QACZ,YAAY;QACZ,eAAe;QACf,UAAU;QACV,IAAI;KACL,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CAAC,YAAoB,EAAE,IAAiB;IACjE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAEnD,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAChC,OAAO,GAAG,CAAC,IAAI,CAAC;YAClB,CAAC;YACD,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,4BAA4B;gBAC5B,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;gBACjE,OAAO,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;YACxB,CAAC;YACD,KAAK,IAAI,CAAC,CAAC,CAAC;gBACV,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;gBACtD,IAAI,WAAW,EAAE,CAAC;oBAChB,kCAAkC;oBAClC,OAAO,WAAW,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;gBAC1C,CAAC;gBACD,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;gBACjE,OAAO,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;YACxB,CAAC;YACD,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,wCAAwC;gBACxC,OAAO,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;YACzC,CAAC;YACD,KAAK,KAAK,CAAC,CAAC,CAAC;gBACX,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACrC,OAAO,QAAQ,CAAC,IAAI,CAAC;YACvB,CAAC;YACD;gBACE,OAAO,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,GAAW,EAAE,OAAe;IACrD,IAAI,CAAC;QACH,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAa,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;QACnE,OAAO,KAAK;aACT,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aAC1B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAAkB,EAAE,OAAuB;IAC3E,MAAM,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAE3C,KAAK,MAAM,cAAc,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QACrD,uBAAuB;QACvB,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACpD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC;YAClC,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;gBACvE,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;YACpD,sDAAsD;YACtD,IACE,cAAc,KAAK,mBAAmB;gBACtC,cAAc,CAAC,UAAU,CAAC,mBAAmB,GAAG,GAAG,CAAC,EACpD,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,UAAkB,EAAE,OAAuB;IACtE,MAAM,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAE3C,KAAK,MAAM,SAAS,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QAC3C,MAAM,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QAC1C,IACE,cAAc,KAAK,cAAc;YACjC,cAAc,CAAC,UAAU,CAAC,cAAc,GAAG,GAAG,CAAC,EAC/C,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAuB;IAC1D,OAAO,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,iBAAiB,CAAC;AAC7D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,UAAkB,EAAE,OAAuB;IACrE,MAAM,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,OAAO,CACL,cAAc,KAAK,YAAY;QAC/B,cAAc,CAAC,UAAU,CAAC,YAAY,GAAG,GAAG,CAAC,CAC9C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,UAAkB,EAAE,OAAuB;IAChF,OAAO,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;AACrD,CAAC"}
|