@pylabmit/agent-cmdb 1.5.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/LICENSE +21 -0
- package/README.md +249 -0
- package/dist/agent-preflight.d.ts +6 -0
- package/dist/agent-preflight.d.ts.map +1 -0
- package/dist/agent-preflight.js +55 -0
- package/dist/agent-preflight.js.map +1 -0
- package/dist/brain.d.ts +12 -0
- package/dist/brain.d.ts.map +1 -0
- package/dist/brain.js +372 -0
- package/dist/brain.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +495 -0
- package/dist/cli.js.map +1 -0
- package/dist/digest.d.ts +14 -0
- package/dist/digest.d.ts.map +1 -0
- package/dist/digest.js +122 -0
- package/dist/digest.js.map +1 -0
- package/dist/doctor.d.ts +9 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +170 -0
- package/dist/doctor.js.map +1 -0
- package/dist/duration.d.ts +2 -0
- package/dist/duration.d.ts.map +1 -0
- package/dist/duration.js +15 -0
- package/dist/duration.js.map +1 -0
- package/dist/engine.d.ts +12 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +12 -0
- package/dist/engine.js.map +1 -0
- package/dist/freshness.d.ts +3 -0
- package/dist/freshness.d.ts.map +1 -0
- package/dist/freshness.js +19 -0
- package/dist/freshness.js.map +1 -0
- package/dist/graph-engine.d.ts +4 -0
- package/dist/graph-engine.d.ts.map +1 -0
- package/dist/graph-engine.js +36 -0
- package/dist/graph-engine.js.map +1 -0
- package/dist/interface.d.ts +34 -0
- package/dist/interface.d.ts.map +1 -0
- package/dist/interface.js +91 -0
- package/dist/interface.js.map +1 -0
- package/dist/loader.d.ts +9 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +199 -0
- package/dist/loader.js.map +1 -0
- package/dist/policy-engine.d.ts +7 -0
- package/dist/policy-engine.d.ts.map +1 -0
- package/dist/policy-engine.js +143 -0
- package/dist/policy-engine.js.map +1 -0
- package/dist/preflight-action.d.ts +3 -0
- package/dist/preflight-action.d.ts.map +1 -0
- package/dist/preflight-action.js +101 -0
- package/dist/preflight-action.js.map +1 -0
- package/dist/preflight.d.ts +4 -0
- package/dist/preflight.d.ts.map +1 -0
- package/dist/preflight.js +36 -0
- package/dist/preflight.js.map +1 -0
- package/dist/route-resolver.d.ts +6 -0
- package/dist/route-resolver.d.ts.map +1 -0
- package/dist/route-resolver.js +130 -0
- package/dist/route-resolver.js.map +1 -0
- package/dist/store.d.ts +15 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +230 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +277 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validator.d.ts +6 -0
- package/dist/validator.d.ts.map +1 -0
- package/dist/validator.js +165 -0
- package/dist/validator.js.map +1 -0
- package/examples/basic/control-plane.yaml +122 -0
- package/examples/multi-agent/control-plane.yaml +352 -0
- package/package.json +79 -0
package/dist/loader.js
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, extname, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { parse as parseYaml } from 'yaml';
|
|
5
|
+
import { validateControlPlane } from './validator.js';
|
|
6
|
+
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
export const defaultControlPlanePath = resolve(moduleDir, '..', 'examples', 'basic', 'control-plane.yaml');
|
|
8
|
+
export const multiAgentExampleControlPlanePath = resolve(moduleDir, '..', 'examples', 'multi-agent', 'control-plane.yaml');
|
|
9
|
+
export class ControlPlaneLoadError extends Error {
|
|
10
|
+
constructor(message) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = 'ControlPlaneLoadError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function loadControlPlane(filePath) {
|
|
16
|
+
const content = readControlPlaneFile(filePath);
|
|
17
|
+
const parsed = parseControlPlaneContent(filePath, content);
|
|
18
|
+
const controlPlane = parseControlPlane(parsed);
|
|
19
|
+
const errors = validateControlPlane(controlPlane).filter((issue) => issue.severity === 'error');
|
|
20
|
+
if (errors.length > 0) {
|
|
21
|
+
const detail = errors.map((issue) => `${issue.code}: ${issue.message}`).join('; ');
|
|
22
|
+
throw new ControlPlaneLoadError(`Control plane validation failed: ${detail}`);
|
|
23
|
+
}
|
|
24
|
+
return controlPlane;
|
|
25
|
+
}
|
|
26
|
+
export function loadDefaultControlPlane() {
|
|
27
|
+
return loadControlPlane(defaultControlPlanePath);
|
|
28
|
+
}
|
|
29
|
+
function readControlPlaneFile(filePath) {
|
|
30
|
+
try {
|
|
31
|
+
return readFileSync(filePath, 'utf8');
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
35
|
+
throw new ControlPlaneLoadError(`Failed to read control plane at ${filePath}: ${detail}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function parseControlPlaneContent(filePath, content) {
|
|
39
|
+
const extension = extname(filePath).toLowerCase();
|
|
40
|
+
try {
|
|
41
|
+
if (extension === '.yaml' || extension === '.yml') {
|
|
42
|
+
return parseYaml(content);
|
|
43
|
+
}
|
|
44
|
+
return JSON.parse(content);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
48
|
+
const format = extension === '.yaml' || extension === '.yml' ? 'YAML' : 'JSON';
|
|
49
|
+
throw new ControlPlaneLoadError(`Failed to parse control plane ${format} at ${filePath}: ${detail}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function parseControlPlane(value) {
|
|
53
|
+
const root = requireRecord(value, 'Control plane');
|
|
54
|
+
return {
|
|
55
|
+
version: readString(root, 'version', 'Control plane version'),
|
|
56
|
+
updatedAt: readString(root, 'updatedAt', 'Control plane updatedAt'),
|
|
57
|
+
sources: readArray(root, 'sources', 'Control plane sources').map(parseSourceRef),
|
|
58
|
+
profiles: readArray(root, 'profiles', 'Control plane profiles').map(parseAgentProfile),
|
|
59
|
+
policies: readArray(root, 'policies', 'Control plane policies').map(parsePolicyRule),
|
|
60
|
+
objects: readArray(root, 'objects', 'Control plane objects').map(parseCmdbObject),
|
|
61
|
+
relationships: readArray(root, 'relationships', 'Control plane relationships').map(parseRelationship)
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function parseSourceRef(value) {
|
|
65
|
+
const record = requireRecord(value, 'Source');
|
|
66
|
+
const kind = readString(record, 'kind', 'Source kind');
|
|
67
|
+
if (!['memory', 'tool', 'oauth', 'wiki', 'web', 'evidence'].includes(kind)) {
|
|
68
|
+
throw new ControlPlaneLoadError(`Source kind has invalid value ${kind}.`);
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
id: readString(record, 'id', 'Source id'),
|
|
72
|
+
label: readString(record, 'label', 'Source label'),
|
|
73
|
+
kind: kind,
|
|
74
|
+
readOnly: readBoolean(record, 'readOnly', 'Source readOnly'),
|
|
75
|
+
notes: optionalString(record, 'notes'),
|
|
76
|
+
freshnessTtl: optionalString(record, 'freshnessTtl'),
|
|
77
|
+
brainEntityId: optionalString(record, 'brainEntityId')
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function parseAgentProfile(value) {
|
|
81
|
+
const record = requireRecord(value, 'Profile');
|
|
82
|
+
return {
|
|
83
|
+
id: readString(record, 'id', 'Profile id'),
|
|
84
|
+
name: readString(record, 'name', 'Profile name'),
|
|
85
|
+
purpose: readString(record, 'purpose', 'Profile purpose'),
|
|
86
|
+
guardrails: readStringArray(record, 'guardrails', 'Profile guardrails'),
|
|
87
|
+
routes: readArray(record, 'routes', 'Profile routes').map(parseSourceRoute)
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function parseSourceRoute(value) {
|
|
91
|
+
const record = requireRecord(value, 'Source route');
|
|
92
|
+
return {
|
|
93
|
+
intent: readString(record, 'intent', 'Source route intent'),
|
|
94
|
+
sources: readStringArray(record, 'sources', 'Source route sources'),
|
|
95
|
+
notes: optionalString(record, 'notes')
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function parsePolicyRule(value) {
|
|
99
|
+
const record = requireRecord(value, 'Policy');
|
|
100
|
+
const effect = readString(record, 'effect', 'Policy effect');
|
|
101
|
+
if (!['allow', 'deny', 'approval_required'].includes(effect)) {
|
|
102
|
+
throw new ControlPlaneLoadError(`Policy effect has invalid value ${effect}.`);
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
id: readString(record, 'id', 'Policy id'),
|
|
106
|
+
effect: effect,
|
|
107
|
+
actions: readStringArray(record, 'actions', 'Policy actions'),
|
|
108
|
+
profiles: optionalStringArray(record, 'profiles', 'Policy profiles'),
|
|
109
|
+
tools: optionalStringArray(record, 'tools', 'Policy tools'),
|
|
110
|
+
reason: readString(record, 'reason', 'Policy reason'),
|
|
111
|
+
code: optionalString(record, 'code'),
|
|
112
|
+
canEscalate: optionalBoolean(record, 'canEscalate'),
|
|
113
|
+
suggestedAlternative: optionalString(record, 'suggestedAlternative')
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function parseCmdbObject(value) {
|
|
117
|
+
const record = requireRecord(value, 'CMDB object');
|
|
118
|
+
const kind = readString(record, 'kind', 'CMDB object kind');
|
|
119
|
+
const status = readString(record, 'status', 'CMDB object status');
|
|
120
|
+
if (!['profile', 'source', 'tool', 'job', 'memory', 'policy', 'workspace'].includes(kind)) {
|
|
121
|
+
throw new ControlPlaneLoadError(`CMDB object kind has invalid value ${kind}.`);
|
|
122
|
+
}
|
|
123
|
+
if (!['active', 'paused', 'blocked', 'planned'].includes(status)) {
|
|
124
|
+
throw new ControlPlaneLoadError(`CMDB object status has invalid value ${status}.`);
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
id: readString(record, 'id', 'CMDB object id'),
|
|
128
|
+
kind: kind,
|
|
129
|
+
label: readString(record, 'label', 'CMDB object label'),
|
|
130
|
+
status: status,
|
|
131
|
+
profile: optionalString(record, 'profile'),
|
|
132
|
+
tags: readStringArray(record, 'tags', 'CMDB object tags'),
|
|
133
|
+
dependsOn: optionalStringArray(record, 'dependsOn', 'CMDB object dependsOn'),
|
|
134
|
+
notes: optionalString(record, 'notes')
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function parseRelationship(value) {
|
|
138
|
+
const record = requireRecord(value, 'Relationship');
|
|
139
|
+
const type = readString(record, 'type', 'Relationship type');
|
|
140
|
+
if (!['uses', 'owns', 'governed_by', 'depends_on', 'blocks', 'writes_to'].includes(type)) {
|
|
141
|
+
throw new ControlPlaneLoadError(`Relationship type has invalid value ${type}.`);
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
from: readString(record, 'from', 'Relationship from'),
|
|
145
|
+
to: readString(record, 'to', 'Relationship to'),
|
|
146
|
+
type: type,
|
|
147
|
+
notes: optionalString(record, 'notes')
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function readArray(record, key, label) {
|
|
151
|
+
const value = record[key];
|
|
152
|
+
if (!Array.isArray(value)) {
|
|
153
|
+
throw new ControlPlaneLoadError(`${label} must be an array.`);
|
|
154
|
+
}
|
|
155
|
+
return value;
|
|
156
|
+
}
|
|
157
|
+
function readStringArray(record, key, label) {
|
|
158
|
+
return readArray(record, key, label).map((value) => requireNonEmptyString(value, label));
|
|
159
|
+
}
|
|
160
|
+
function optionalStringArray(record, key, label) {
|
|
161
|
+
if (record[key] === undefined)
|
|
162
|
+
return undefined;
|
|
163
|
+
return readStringArray(record, key, label);
|
|
164
|
+
}
|
|
165
|
+
function readString(record, key, label) {
|
|
166
|
+
return requireNonEmptyString(record[key], label);
|
|
167
|
+
}
|
|
168
|
+
function optionalString(record, key) {
|
|
169
|
+
if (record[key] === undefined)
|
|
170
|
+
return undefined;
|
|
171
|
+
return requireNonEmptyString(record[key], key);
|
|
172
|
+
}
|
|
173
|
+
function readBoolean(record, key, label) {
|
|
174
|
+
if (typeof record[key] !== 'boolean') {
|
|
175
|
+
throw new ControlPlaneLoadError(`${label} must be a boolean.`);
|
|
176
|
+
}
|
|
177
|
+
return record[key];
|
|
178
|
+
}
|
|
179
|
+
function optionalBoolean(record, key) {
|
|
180
|
+
if (record[key] === undefined)
|
|
181
|
+
return undefined;
|
|
182
|
+
if (typeof record[key] !== 'boolean') {
|
|
183
|
+
throw new ControlPlaneLoadError(`${key} must be a boolean.`);
|
|
184
|
+
}
|
|
185
|
+
return record[key];
|
|
186
|
+
}
|
|
187
|
+
function requireRecord(value, label) {
|
|
188
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
189
|
+
throw new ControlPlaneLoadError(`${label} must be an object.`);
|
|
190
|
+
}
|
|
191
|
+
return value;
|
|
192
|
+
}
|
|
193
|
+
function requireNonEmptyString(value, label) {
|
|
194
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
195
|
+
throw new ControlPlaneLoadError(`${label} must be a non-empty string.`);
|
|
196
|
+
}
|
|
197
|
+
return value;
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ControlPlane, PolicyDecision, PolicyRequest, PolicyRule } from './types.js';
|
|
2
|
+
export declare function evaluatePolicy(controlPlane: ControlPlane, request: PolicyRequest): PolicyDecision;
|
|
3
|
+
export declare function normalizePolicyRequest(request: PolicyRequest): PolicyRequest;
|
|
4
|
+
export declare function policyMatches(rule: PolicyRule, request: PolicyRequest): boolean;
|
|
5
|
+
export declare function policyShadows(candidate: PolicyRule, policy: PolicyRule): boolean;
|
|
6
|
+
export declare function policiesConflict(left: PolicyRule, right: PolicyRule): boolean;
|
|
7
|
+
//# sourceMappingURL=policy-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-engine.d.ts","sourceRoot":"","sources":["../src/policy-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,YAAY,EAAE,cAAc,EAAgB,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAQpH,wBAAgB,cAAc,CAAC,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,GAAG,cAAc,CAmDjG;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAW5E;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAM/E;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAKhF;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAM7E"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
const effectRank = {
|
|
2
|
+
deny: 3,
|
|
3
|
+
approval_required: 2,
|
|
4
|
+
allow: 1
|
|
5
|
+
};
|
|
6
|
+
export function evaluatePolicy(controlPlane, request) {
|
|
7
|
+
const normalizedRequest = normalizePolicyRequest(request);
|
|
8
|
+
ensureProfileExists(controlPlane, normalizedRequest.profile);
|
|
9
|
+
const blockedObject = findUnavailableReferencedObject(controlPlane, normalizedRequest);
|
|
10
|
+
if (blockedObject) {
|
|
11
|
+
return {
|
|
12
|
+
effect: 'deny',
|
|
13
|
+
ruleId: `object-status-${blockedObject.status}`,
|
|
14
|
+
code: `object_${blockedObject.status}`,
|
|
15
|
+
reason: `Object ${blockedObject.id} is ${blockedObject.status}.`,
|
|
16
|
+
profile: normalizedRequest.profile,
|
|
17
|
+
action: normalizedRequest.action,
|
|
18
|
+
tool: normalizedRequest.tool,
|
|
19
|
+
canEscalate: false,
|
|
20
|
+
suggestedAlternative: 'Use an active source or tool.'
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const matchingRules = controlPlane.policies.filter((rule) => policyMatches(rule, normalizedRequest));
|
|
24
|
+
const selectedRule = matchingRules.sort((left, right) => {
|
|
25
|
+
const rankDelta = effectRank[right.effect] - effectRank[left.effect];
|
|
26
|
+
if (rankDelta !== 0)
|
|
27
|
+
return rankDelta;
|
|
28
|
+
return controlPlane.policies.indexOf(left) - controlPlane.policies.indexOf(right);
|
|
29
|
+
})[0];
|
|
30
|
+
if (!selectedRule) {
|
|
31
|
+
return {
|
|
32
|
+
effect: 'approval_required',
|
|
33
|
+
ruleId: 'default-approval-required',
|
|
34
|
+
code: 'no_explicit_policy_match',
|
|
35
|
+
reason: 'No explicit allow rule matched this action, so approval is required.',
|
|
36
|
+
profile: normalizedRequest.profile,
|
|
37
|
+
action: normalizedRequest.action,
|
|
38
|
+
tool: normalizedRequest.tool,
|
|
39
|
+
canEscalate: true,
|
|
40
|
+
suggestedAlternative: 'Ask for explicit approval or add a policy rule.'
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
effect: selectedRule.effect,
|
|
45
|
+
ruleId: selectedRule.id,
|
|
46
|
+
code: selectedRule.code ?? selectedRule.id,
|
|
47
|
+
reason: selectedRule.reason,
|
|
48
|
+
profile: normalizedRequest.profile,
|
|
49
|
+
action: normalizedRequest.action,
|
|
50
|
+
tool: normalizedRequest.tool,
|
|
51
|
+
canEscalate: selectedRule.canEscalate ?? selectedRule.effect === 'approval_required',
|
|
52
|
+
suggestedAlternative: selectedRule.suggestedAlternative
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export function normalizePolicyRequest(request) {
|
|
56
|
+
const record = requireRecord(request, 'Policy request');
|
|
57
|
+
const tool = record.tool === undefined
|
|
58
|
+
? undefined
|
|
59
|
+
: requireNonEmptyString(record.tool, 'Policy request tool', 'when provided');
|
|
60
|
+
return {
|
|
61
|
+
profile: requireNonEmptyString(record.profile, 'Policy request profile'),
|
|
62
|
+
action: requireNonEmptyString(record.action, 'Policy request action'),
|
|
63
|
+
tool
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export function policyMatches(rule, request) {
|
|
67
|
+
if (!matchesList(rule.actions, request.action))
|
|
68
|
+
return false;
|
|
69
|
+
if (rule.profiles && !matchesList(rule.profiles, request.profile))
|
|
70
|
+
return false;
|
|
71
|
+
if (rule.tools && !request.tool)
|
|
72
|
+
return rule.tools.includes('*');
|
|
73
|
+
if (rule.tools && request.tool && !matchesList(rule.tools, request.tool))
|
|
74
|
+
return false;
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
export function policyShadows(candidate, policy) {
|
|
78
|
+
if (candidate.effect !== policy.effect)
|
|
79
|
+
return false;
|
|
80
|
+
return listCovers(candidate.actions, policy.actions)
|
|
81
|
+
&& optionalListCovers(candidate.profiles, policy.profiles)
|
|
82
|
+
&& optionalListCovers(candidate.tools, policy.tools);
|
|
83
|
+
}
|
|
84
|
+
export function policiesConflict(left, right) {
|
|
85
|
+
if (left.effect === right.effect)
|
|
86
|
+
return false;
|
|
87
|
+
if (left.effect !== 'deny' && right.effect !== 'deny')
|
|
88
|
+
return false;
|
|
89
|
+
return listOverlaps(left.actions, right.actions)
|
|
90
|
+
&& optionalListOverlaps(left.profiles, right.profiles)
|
|
91
|
+
&& optionalListOverlaps(left.tools, right.tools);
|
|
92
|
+
}
|
|
93
|
+
function matchesList(values, candidate) {
|
|
94
|
+
return values.includes('*') || values.includes(candidate);
|
|
95
|
+
}
|
|
96
|
+
function optionalListCovers(candidate, policy) {
|
|
97
|
+
if (!candidate)
|
|
98
|
+
return true;
|
|
99
|
+
if (!policy)
|
|
100
|
+
return candidate.includes('*');
|
|
101
|
+
return listCovers(candidate, policy);
|
|
102
|
+
}
|
|
103
|
+
function listCovers(candidate, policy) {
|
|
104
|
+
return candidate.includes('*') || policy.every((value) => candidate.includes(value));
|
|
105
|
+
}
|
|
106
|
+
function optionalListOverlaps(left, right) {
|
|
107
|
+
if (!left || !right)
|
|
108
|
+
return true;
|
|
109
|
+
return listOverlaps(left, right);
|
|
110
|
+
}
|
|
111
|
+
function listOverlaps(left, right) {
|
|
112
|
+
return left.includes('*') || right.includes('*') || left.some((value) => right.includes(value));
|
|
113
|
+
}
|
|
114
|
+
function findUnavailableReferencedObject(controlPlane, request) {
|
|
115
|
+
if (!request.tool)
|
|
116
|
+
return undefined;
|
|
117
|
+
const candidateIds = new Set([
|
|
118
|
+
request.tool,
|
|
119
|
+
`source.${request.tool}`,
|
|
120
|
+
`tool.${request.tool}`
|
|
121
|
+
]);
|
|
122
|
+
return controlPlane.objects.find((object) => (candidateIds.has(object.id)
|
|
123
|
+
&& (object.status === 'blocked' || object.status === 'paused')));
|
|
124
|
+
}
|
|
125
|
+
function ensureProfileExists(controlPlane, profileId) {
|
|
126
|
+
if (!controlPlane.profiles.some((candidate) => candidate.id === profileId)) {
|
|
127
|
+
throw new Error(`Unknown profile: ${profileId}.`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function requireRecord(value, label) {
|
|
131
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
132
|
+
throw new Error(`${label} must be an object.`);
|
|
133
|
+
}
|
|
134
|
+
return value;
|
|
135
|
+
}
|
|
136
|
+
function requireNonEmptyString(value, label, suffix) {
|
|
137
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
138
|
+
const suffixText = suffix ? ` ${suffix}` : '';
|
|
139
|
+
throw new Error(`${label} must be a non-empty string${suffixText}.`);
|
|
140
|
+
}
|
|
141
|
+
return value;
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=policy-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-engine.js","sourceRoot":"","sources":["../src/policy-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight-action.d.ts","sourceRoot":"","sources":["../src/preflight-action.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAkB,gBAAgB,EAAE,eAAe,EAAuB,MAAM,YAAY,CAAC;AAEvH,wBAAgB,eAAe,CAAC,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,gBAAgB,GAAG,eAAe,CA+CtG"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { evaluatePolicy, normalizePolicyRequest } from './policy-engine.js';
|
|
2
|
+
import { inspectProfile, resolveSourceRoute } from './route-resolver.js';
|
|
3
|
+
export function preflightAction(controlPlane, request) {
|
|
4
|
+
const normalizedRequest = normalizePreflightRequest(request);
|
|
5
|
+
const decision = evaluatePolicy(controlPlane, normalizedRequest);
|
|
6
|
+
let finalDecision = decision;
|
|
7
|
+
let route;
|
|
8
|
+
const warnings = [];
|
|
9
|
+
if (normalizedRequest.intent) {
|
|
10
|
+
try {
|
|
11
|
+
route = resolveSourceRoute(controlPlane, {
|
|
12
|
+
profile: normalizedRequest.profile,
|
|
13
|
+
intent: normalizedRequest.intent,
|
|
14
|
+
freshness: normalizedRequest.freshness,
|
|
15
|
+
now: normalizedRequest.now
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
20
|
+
const reason = `Route resolution failed: ${message}`;
|
|
21
|
+
warnings.push(reason);
|
|
22
|
+
if (decision.effect === 'allow') {
|
|
23
|
+
finalDecision = {
|
|
24
|
+
effect: 'deny',
|
|
25
|
+
ruleId: 'route-resolution-failed',
|
|
26
|
+
code: 'route_resolution_failed',
|
|
27
|
+
reason,
|
|
28
|
+
profile: normalizedRequest.profile,
|
|
29
|
+
action: normalizedRequest.action,
|
|
30
|
+
tool: normalizedRequest.tool,
|
|
31
|
+
canEscalate: false,
|
|
32
|
+
suggestedAlternative: 'Fix the source route for this profile and intent before executing.'
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const profile = inspectProfile(controlPlane, normalizedRequest.profile);
|
|
38
|
+
return {
|
|
39
|
+
allowed: finalDecision.effect === 'allow',
|
|
40
|
+
approvalRequired: finalDecision.effect === 'approval_required',
|
|
41
|
+
decision: finalDecision,
|
|
42
|
+
route,
|
|
43
|
+
routeExecutable: finalDecision.effect === 'allow' && Boolean(route),
|
|
44
|
+
guardrails: route?.guardrails ?? profile.guardrails,
|
|
45
|
+
warnings,
|
|
46
|
+
dryRun: Boolean(normalizedRequest.dryRun)
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function normalizePreflightRequest(request) {
|
|
50
|
+
const normalizedPolicy = normalizePolicyRequest(request);
|
|
51
|
+
const record = requireRecord(request, 'Preflight request');
|
|
52
|
+
const intent = record.intent === undefined
|
|
53
|
+
? undefined
|
|
54
|
+
: requireNonEmptyString(record.intent, 'Preflight request intent', 'when provided');
|
|
55
|
+
const dryRun = record.dryRun === undefined ? undefined : requireBoolean(record.dryRun, 'Preflight request dryRun');
|
|
56
|
+
const freshness = normalizeFreshness(record.freshness);
|
|
57
|
+
const now = record.now === undefined
|
|
58
|
+
? undefined
|
|
59
|
+
: requireNonEmptyString(record.now, 'Preflight request now', 'when provided');
|
|
60
|
+
return {
|
|
61
|
+
...normalizedPolicy,
|
|
62
|
+
intent,
|
|
63
|
+
dryRun,
|
|
64
|
+
freshness,
|
|
65
|
+
now
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function normalizeFreshness(value) {
|
|
69
|
+
if (value === undefined)
|
|
70
|
+
return undefined;
|
|
71
|
+
if (!Array.isArray(value)) {
|
|
72
|
+
throw new Error('Preflight request freshness must be an array.');
|
|
73
|
+
}
|
|
74
|
+
return value.map((entry) => {
|
|
75
|
+
const record = requireRecord(entry, 'Preflight freshness input');
|
|
76
|
+
return {
|
|
77
|
+
sourceId: requireNonEmptyString(record.sourceId, 'Preflight freshness sourceId'),
|
|
78
|
+
lastUpdated: requireNonEmptyString(record.lastUpdated, 'Preflight freshness lastUpdated')
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function requireBoolean(value, label) {
|
|
83
|
+
if (typeof value !== 'boolean') {
|
|
84
|
+
throw new Error(`${label} must be a boolean.`);
|
|
85
|
+
}
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
88
|
+
function requireRecord(value, label) {
|
|
89
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
90
|
+
throw new Error(`${label} must be an object.`);
|
|
91
|
+
}
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
function requireNonEmptyString(value, label, suffix) {
|
|
95
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
96
|
+
const suffixText = suffix ? ` ${suffix}` : '';
|
|
97
|
+
throw new Error(`${label} must be a non-empty string${suffixText}.`);
|
|
98
|
+
}
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=preflight-action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight-action.js","sourceRoot":"","sources":["../src/preflight-action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzE,MAAM,UAAU,eAAe,CAAC,YAA0B,EAAE,OAAyB;IACnF,MAAM,iBAAiB,GAAG,yBAAyB,CAAC,OAAO,CAAC,CAAC;IAC7D,MAAM,QAAQ,GAAG,cAAc,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;IACjE,IAAI,aAAa,GAAmB,QAAQ,CAAC;IAC7C,IAAI,KAAsC,CAAC;IAC3C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,iBAAiB,CAAC,MAAM,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,KAAK,GAAG,kBAAkB,CAAC,YAAY,EAAE;gBACvC,OAAO,EAAE,iBAAiB,CAAC,OAAO;gBAClC,MAAM,EAAE,iBAAiB,CAAC,MAAM;gBAChC,SAAS,EAAE,iBAAiB,CAAC,SAAS;gBACtC,GAAG,EAAE,iBAAiB,CAAC,GAAG;aAC3B,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,MAAM,MAAM,GAAG,4BAA4B,OAAO,EAAE,CAAC;YACrD,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACtB,IAAI,QAAQ,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;gBAChC,aAAa,GAAG;oBACd,MAAM,EAAE,MAAM;oBACd,MAAM,EAAE,yBAAyB;oBACjC,IAAI,EAAE,yBAAyB;oBAC/B,MAAM;oBACN,OAAO,EAAE,iBAAiB,CAAC,OAAO;oBAClC,MAAM,EAAE,iBAAiB,CAAC,MAAM;oBAChC,IAAI,EAAE,iBAAiB,CAAC,IAAI;oBAC5B,WAAW,EAAE,KAAK;oBAClB,oBAAoB,EAAE,oEAAoE;iBAC3F,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,cAAc,CAAC,YAAY,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAExE,OAAO;QACL,OAAO,EAAE,aAAa,CAAC,MAAM,KAAK,OAAO;QACzC,gBAAgB,EAAE,aAAa,CAAC,MAAM,KAAK,mBAAmB;QAC9D,QAAQ,EAAE,aAAa;QACvB,KAAK;QACL,eAAe,EAAE,aAAa,CAAC,MAAM,KAAK,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC;QACnE,UAAU,EAAE,KAAK,EAAE,UAAU,IAAI,OAAO,CAAC,UAAU;QACnD,QAAQ;QACR,MAAM,EAAE,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC;KAC1C,CAAC;AACJ,CAAC;AAED,SAAS,yBAAyB,CAAC,OAAyB;IAC1D,MAAM,gBAAgB,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,KAAK,SAAS;QACxC,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,EAAE,0BAA0B,EAAE,eAAe,CAAC,CAAC;IACtF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC;IACnH,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,KAAK,SAAS;QAClC,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,qBAAqB,CAAC,MAAM,CAAC,GAAG,EAAE,uBAAuB,EAAE,eAAe,CAAC,CAAC;IAEhF,OAAO;QACL,GAAG,gBAAgB;QACnB,MAAM;QACN,MAAM;QACN,SAAS;QACT,GAAG;KACJ,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACzB,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,2BAA2B,CAAC,CAAC;QACjE,OAAO;YACL,QAAQ,EAAE,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,8BAA8B,CAAC;YAChF,WAAW,EAAE,qBAAqB,CAAC,MAAM,CAAC,WAAW,EAAE,iCAAiC,CAAC;SAC1F,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,cAAc,CAAC,KAAc,EAAE,KAAa;IACnD,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,qBAAqB,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,aAAa,CAAC,KAAc,EAAE,KAAa;IAClD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,qBAAqB,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,KAAgC,CAAC;AAC1C,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc,EAAE,KAAa,EAAE,MAAe;IAC3E,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,8BAA8B,UAAU,GAAG,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type AgentCmdbOptions } from './interface.js';
|
|
2
|
+
import type { PreflightRequest, PreflightResult } from './types.js';
|
|
3
|
+
export declare function agentPreflight(request: PreflightRequest, options?: AgentCmdbOptions): Promise<PreflightResult>;
|
|
4
|
+
//# sourceMappingURL=preflight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight.d.ts","sourceRoot":"","sources":["../src/preflight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEpE,wBAAsB,cAAc,CAClC,OAAO,EAAE,gBAAgB,EACzB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC,CAqC1B"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createAgentCmdb } from './interface.js';
|
|
2
|
+
export async function agentPreflight(request, options = {}) {
|
|
3
|
+
const cmdb = createAgentCmdb(options);
|
|
4
|
+
const result = cmdb.preflight(request);
|
|
5
|
+
const now = new Date().toISOString();
|
|
6
|
+
if (result.dryRun) {
|
|
7
|
+
return result;
|
|
8
|
+
}
|
|
9
|
+
if (result.decision.effect === 'deny') {
|
|
10
|
+
await cmdb.logEvidence({
|
|
11
|
+
profile: result.decision.profile,
|
|
12
|
+
source: 'agent-cmdb-preflight',
|
|
13
|
+
intent: request.intent ?? result.decision.action,
|
|
14
|
+
summary: `Denied: ${result.decision.reason}`,
|
|
15
|
+
trust: 'high',
|
|
16
|
+
capturedAt: now,
|
|
17
|
+
tags: ['agent-cmdb', 'preflight', 'deny', result.decision.ruleId]
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
await cmdb.logChange({
|
|
21
|
+
target: result.decision.ruleId,
|
|
22
|
+
targetType: 'policy',
|
|
23
|
+
action: 'verify',
|
|
24
|
+
actor: 'agent-cmdb-preflight',
|
|
25
|
+
reason: `Preflight ${result.decision.effect} for ${result.decision.profile}/${result.decision.action}.`,
|
|
26
|
+
changedAt: now,
|
|
27
|
+
after: {
|
|
28
|
+
allowed: result.allowed,
|
|
29
|
+
approvalRequired: result.approvalRequired,
|
|
30
|
+
routeExecutable: result.routeExecutable,
|
|
31
|
+
decision: result.decision
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=preflight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight.js","sourceRoot":"","sources":["../src/preflight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAyB,MAAM,gBAAgB,CAAC;AAGxE,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAyB,EACzB,UAA4B,EAAE;IAE9B,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QACtC,MAAM,IAAI,CAAC,WAAW,CAAC;YACrB,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO;YAChC,MAAM,EAAE,sBAAsB;YAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM;YAChD,OAAO,EAAE,WAAW,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE;YAC5C,KAAK,EAAE,MAAM;YACb,UAAU,EAAE,GAAG;YACf,IAAI,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;SAClE,CAAC,CAAC;IACL,CAAC;IAED,MAAM,IAAI,CAAC,SAAS,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM;QAC9B,UAAU,EAAE,QAAQ;QACpB,MAAM,EAAE,QAAQ;QAChB,KAAK,EAAE,sBAAsB;QAC7B,MAAM,EAAE,aAAa,MAAM,CAAC,QAAQ,CAAC,MAAM,QAAQ,MAAM,CAAC,QAAQ,CAAC,OAAO,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG;QACvG,SAAS,EAAE,GAAG;QACd,KAAK,EAAE;YACL,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;YACzC,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,QAAQ,EAAE,MAAM,CAAC,QAAQ;SAC1B;KACF,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AgentProfile, ControlPlane, ProfileInspection, ResolvedSourceRoute, SourceRef, SourceRouteRequest } from './types.js';
|
|
2
|
+
export declare function resolveSourceRoute(controlPlane: ControlPlane, request: SourceRouteRequest): ResolvedSourceRoute;
|
|
3
|
+
export declare function inspectProfile(controlPlane: ControlPlane, profileId: string): ProfileInspection;
|
|
4
|
+
export declare function ensureProfile(controlPlane: ControlPlane, profileId: string): AgentProfile;
|
|
5
|
+
export declare function ensureSource(controlPlane: ControlPlane, sourceId: string): SourceRef;
|
|
6
|
+
//# sourceMappingURL=route-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-resolver.d.ts","sourceRoot":"","sources":["../src/route-resolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EAGnB,SAAS,EACT,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,kBAAkB,GAC1B,mBAAmB,CAuBrB;AAED,wBAAgB,cAAc,CAAC,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAc/F;AAED,wBAAgB,aAAa,CAAC,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAMzF;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAMpF"}
|