agentlock-shared 0.2.0 → 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/dist/__tests__/billing.test.d.ts +2 -0
- package/dist/__tests__/billing.test.d.ts.map +1 -0
- package/dist/__tests__/billing.test.js +31 -0
- package/dist/__tests__/billing.test.js.map +1 -0
- package/dist/__tests__/dns-pinning.test.d.ts +2 -0
- package/dist/__tests__/dns-pinning.test.d.ts.map +1 -0
- package/dist/__tests__/dns-pinning.test.js +33 -0
- package/dist/__tests__/dns-pinning.test.js.map +1 -0
- package/dist/__tests__/llm-classifier-cache-store.test.d.ts +2 -0
- package/dist/__tests__/llm-classifier-cache-store.test.d.ts.map +1 -0
- package/dist/__tests__/llm-classifier-cache-store.test.js +65 -0
- package/dist/__tests__/llm-classifier-cache-store.test.js.map +1 -0
- package/dist/__tests__/llm-classifier-cache.test.d.ts +2 -0
- package/dist/__tests__/llm-classifier-cache.test.d.ts.map +1 -0
- package/dist/__tests__/llm-classifier-cache.test.js +44 -0
- package/dist/__tests__/llm-classifier-cache.test.js.map +1 -0
- package/dist/__tests__/llm-classifier.test.d.ts +2 -0
- package/dist/__tests__/llm-classifier.test.d.ts.map +1 -0
- package/dist/__tests__/llm-classifier.test.js +167 -0
- package/dist/__tests__/llm-classifier.test.js.map +1 -0
- package/dist/__tests__/plans-classifier-limits.test.d.ts +2 -0
- package/dist/__tests__/plans-classifier-limits.test.d.ts.map +1 -0
- package/dist/__tests__/plans-classifier-limits.test.js +22 -0
- package/dist/__tests__/plans-classifier-limits.test.js.map +1 -0
- package/dist/__tests__/policy-category-floor.test.d.ts +2 -0
- package/dist/__tests__/policy-category-floor.test.d.ts.map +1 -0
- package/dist/__tests__/policy-category-floor.test.js +46 -0
- package/dist/__tests__/policy-category-floor.test.js.map +1 -0
- package/dist/__tests__/policy-claude-bash.test.d.ts +2 -0
- package/dist/__tests__/policy-claude-bash.test.d.ts.map +1 -0
- package/dist/__tests__/policy-claude-bash.test.js +401 -0
- package/dist/__tests__/policy-claude-bash.test.js.map +1 -0
- package/dist/__tests__/policy-llm-floor.test.d.ts +2 -0
- package/dist/__tests__/policy-llm-floor.test.d.ts.map +1 -0
- package/dist/__tests__/policy-llm-floor.test.js +107 -0
- package/dist/__tests__/policy-llm-floor.test.js.map +1 -0
- package/dist/__tests__/policy-ssh-e2e.test.d.ts +2 -0
- package/dist/__tests__/policy-ssh-e2e.test.d.ts.map +1 -0
- package/dist/__tests__/policy-ssh-e2e.test.js +89 -0
- package/dist/__tests__/policy-ssh-e2e.test.js.map +1 -0
- package/dist/__tests__/policy-ssh-sessions.test.d.ts +2 -0
- package/dist/__tests__/policy-ssh-sessions.test.d.ts.map +1 -0
- package/dist/__tests__/policy-ssh-sessions.test.js +139 -0
- package/dist/__tests__/policy-ssh-sessions.test.js.map +1 -0
- package/dist/__tests__/policy-ssh.test.d.ts +2 -0
- package/dist/__tests__/policy-ssh.test.d.ts.map +1 -0
- package/dist/__tests__/policy-ssh.test.js +180 -0
- package/dist/__tests__/policy-ssh.test.js.map +1 -0
- package/dist/__tests__/policy.test.js +400 -2
- package/dist/__tests__/policy.test.js.map +1 -1
- package/dist/__tests__/redact.test.js +76 -0
- package/dist/__tests__/redact.test.js.map +1 -1
- package/dist/__tests__/signing.test.js +89 -0
- package/dist/__tests__/signing.test.js.map +1 -1
- package/dist/__tests__/ssh-fingerprint.test.d.ts +2 -0
- package/dist/__tests__/ssh-fingerprint.test.d.ts.map +1 -0
- package/dist/__tests__/ssh-fingerprint.test.js +19 -0
- package/dist/__tests__/ssh-fingerprint.test.js.map +1 -0
- package/dist/__tests__/vpn-route.test.d.ts +2 -0
- package/dist/__tests__/vpn-route.test.d.ts.map +1 -0
- package/dist/__tests__/vpn-route.test.js +72 -0
- package/dist/__tests__/vpn-route.test.js.map +1 -0
- package/dist/__tests__/wireguard.test.d.ts +2 -0
- package/dist/__tests__/wireguard.test.d.ts.map +1 -0
- package/dist/__tests__/wireguard.test.js +114 -0
- package/dist/__tests__/wireguard.test.js.map +1 -0
- package/dist/billing.d.ts +12 -0
- package/dist/billing.d.ts.map +1 -0
- package/dist/billing.js +41 -0
- package/dist/billing.js.map +1 -0
- package/dist/crypto.d.ts +5 -0
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +80 -23
- package/dist/crypto.js.map +1 -1
- package/dist/dns-pinning.d.ts +28 -0
- package/dist/dns-pinning.d.ts.map +1 -0
- package/dist/dns-pinning.js +113 -0
- package/dist/dns-pinning.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/llm-classifier-cache-store.d.ts +49 -0
- package/dist/llm-classifier-cache-store.d.ts.map +1 -0
- package/dist/llm-classifier-cache-store.js +63 -0
- package/dist/llm-classifier-cache-store.js.map +1 -0
- package/dist/llm-classifier-cache.d.ts +6 -0
- package/dist/llm-classifier-cache.d.ts.map +1 -0
- package/dist/llm-classifier-cache.js +52 -0
- package/dist/llm-classifier-cache.js.map +1 -0
- package/dist/llm-classifier.d.ts +29 -0
- package/dist/llm-classifier.d.ts.map +1 -0
- package/dist/llm-classifier.js +191 -0
- package/dist/llm-classifier.js.map +1 -0
- package/dist/observability.d.ts +36 -0
- package/dist/observability.d.ts.map +1 -0
- package/dist/observability.js +75 -0
- package/dist/observability.js.map +1 -0
- package/dist/plans.d.ts +17 -0
- package/dist/plans.d.ts.map +1 -1
- package/dist/plans.js +36 -14
- package/dist/plans.js.map +1 -1
- package/dist/policy.d.ts +173 -3
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +910 -42
- package/dist/policy.js.map +1 -1
- package/dist/redact.d.ts.map +1 -1
- package/dist/redact.js +83 -3
- package/dist/redact.js.map +1 -1
- package/dist/regex-safety.d.ts +21 -0
- package/dist/regex-safety.d.ts.map +1 -0
- package/dist/regex-safety.js +49 -0
- package/dist/regex-safety.js.map +1 -0
- package/dist/sanitize.d.ts +31 -0
- package/dist/sanitize.d.ts.map +1 -0
- package/dist/sanitize.js +54 -0
- package/dist/sanitize.js.map +1 -0
- package/dist/schemas.d.ts +202 -10
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +91 -1
- package/dist/schemas.js.map +1 -1
- package/dist/signing.d.ts +15 -0
- package/dist/signing.d.ts.map +1 -1
- package/dist/signing.js +53 -4
- package/dist/signing.js.map +1 -1
- package/dist/ssh-fingerprint.d.ts +10 -0
- package/dist/ssh-fingerprint.d.ts.map +1 -0
- package/dist/ssh-fingerprint.js +52 -0
- package/dist/ssh-fingerprint.js.map +1 -0
- package/dist/ssrf.d.ts +36 -0
- package/dist/ssrf.d.ts.map +1 -0
- package/dist/ssrf.js +140 -0
- package/dist/ssrf.js.map +1 -0
- package/dist/types.d.ts +130 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/wireguard.d.ts +63 -0
- package/dist/wireguard.d.ts.map +1 -0
- package/dist/wireguard.js +226 -0
- package/dist/wireguard.js.map +1 -0
- package/package.json +42 -29
- package/.turbo/turbo-build.log +0 -4
- package/.turbo/turbo-test.log +0 -76
- package/dist/__tests__/content-crypto.test.d.ts +0 -2
- package/dist/__tests__/content-crypto.test.d.ts.map +0 -1
- package/dist/__tests__/content-crypto.test.js +0 -117
- package/dist/__tests__/content-crypto.test.js.map +0 -1
- package/dist/__tests__/signing.test (# Edit conflict 2026-04-01 z3etfmC #).js +0 -51
- package/dist/__tests__/signing.test.js (# Edit conflict 2026-04-01 4rndy9C #).map +0 -1
- package/dist/content-crypto.d.ts +0 -24
- package/dist/content-crypto.d.ts.map +0 -1
- package/dist/content-crypto.js +0 -58
- package/dist/content-crypto.js.map +0 -1
- package/src/__tests__/crypto.test.ts +0 -169
- package/src/__tests__/messaging.test.ts +0 -83
- package/src/__tests__/policy.test.ts +0 -222
- package/src/__tests__/redact.test.ts +0 -41
- package/src/__tests__/signing.test.ts +0 -55
- package/src/crypto.ts +0 -235
- package/src/index.ts +0 -8
- package/src/mcp-catalog.ts +0 -181
- package/src/plans.ts +0 -116
- package/src/policy.ts +0 -216
- package/src/redact.ts +0 -131
- package/src/schemas.ts +0 -121
- package/src/signing.ts +0 -120
- package/src/types.ts +0 -213
- package/test-gateway.mjs +0 -47
- package/tsconfig.json +0 -10
- package/vitest.config.ts +0 -8
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.__setClassifierForTest = __setClassifierForTest;
|
|
4
|
+
exports.shapeOnly = shapeOnly;
|
|
5
|
+
exports.classifyWithLLM = classifyWithLLM;
|
|
6
|
+
const zod_1 = require("zod");
|
|
7
|
+
const llm_classifier_cache_js_1 = require("./llm-classifier-cache.js");
|
|
8
|
+
const llm_classifier_cache_store_js_1 = require("./llm-classifier-cache-store.js");
|
|
9
|
+
/**
|
|
10
|
+
* LLM-based risk classifier. Called by the gateway when the server-side
|
|
11
|
+
* static category floor (`getCategoryFloor`) returns `read` — i.e. the tool
|
|
12
|
+
* name and payload don't match any of the hardcoded financial/admin
|
|
13
|
+
* patterns. The LLM provides a second opinion on what the tool is doing
|
|
14
|
+
* based on its name and payload shape.
|
|
15
|
+
*
|
|
16
|
+
* Security & privacy:
|
|
17
|
+
* - Only the TOOL NAME and PAYLOAD SHAPE (keys, types, nested structure) are
|
|
18
|
+
* sent to the LLM. Actual payload values never leave the server.
|
|
19
|
+
* - The LLM's output is advisory. The policy layer applies
|
|
20
|
+
* `max(declared, staticFloor, llmFloor)` — the LLM can only UPGRADE a
|
|
21
|
+
* classification, never downgrade.
|
|
22
|
+
* - All calls are hard-capped at 800ms. If the LLM is slow, unreachable, or
|
|
23
|
+
* errors for any reason, this function returns `null` and the gateway
|
|
24
|
+
* falls back to the static floor alone.
|
|
25
|
+
* - Caching is by shape, so identical tool-call patterns resolve to the same
|
|
26
|
+
* entry regardless of actual values. Cache is in-memory (per-process) in
|
|
27
|
+
* this slice; a persistent store follows in a later phase.
|
|
28
|
+
*/
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Classifier I/O schema
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
const ClassificationSchema = zod_1.z.object({
|
|
33
|
+
category: zod_1.z.enum(['read', 'write', 'financial', 'admin']),
|
|
34
|
+
reason: zod_1.z.string().min(1).max(200),
|
|
35
|
+
confidence: zod_1.z.number().min(0).max(1),
|
|
36
|
+
});
|
|
37
|
+
let testClassifier = null;
|
|
38
|
+
/** Test-only: replace the classifier implementation. Pass null to reset. */
|
|
39
|
+
function __setClassifierForTest(fn) {
|
|
40
|
+
testClassifier = fn;
|
|
41
|
+
}
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// Default classifier — OpenRouter via Vercel AI SDK
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
const MODEL_ID = 'google/gemini-2.5-flash-lite';
|
|
46
|
+
const SYSTEM_PROMPT = `You are a security classifier for an AI agent proxy. Your job is to look at a tool name and payload shape and classify the action into one of four risk categories:
|
|
47
|
+
|
|
48
|
+
- "read": retrieves or inspects data without modifying anything (lookups, lists, snapshots, queries)
|
|
49
|
+
- "write": creates, updates, or deletes data in a standard application context (create_page, update_record, delete_item, post_message)
|
|
50
|
+
- "financial": moves money or handles payment/billing (charges, refunds, invoices, subscriptions, payouts, wire transfers)
|
|
51
|
+
- "admin": privileged administrative actions (user management, permission changes, key rotation, database drops, MFA resets, workspace deletion)
|
|
52
|
+
|
|
53
|
+
Rules:
|
|
54
|
+
1. When in doubt between two categories, pick the MORE restrictive one. Security over convenience.
|
|
55
|
+
2. Base your decision primarily on the TOOL NAME — it is the strongest signal.
|
|
56
|
+
3. The payload shape is provided as a hint, but contains no actual values (only type descriptors).
|
|
57
|
+
4. If the tool name clearly suggests a read (list_*, get_*, fetch_*, search_*, show_*, describe_*), return "read".
|
|
58
|
+
5. If the tool name mentions money, payments, billing, or financial verbs (charge, refund, transfer, payout), return "financial".
|
|
59
|
+
6. If the tool name mentions user management, permissions, keys, or destructive schema changes, return "admin".
|
|
60
|
+
7. Otherwise, if the tool name suggests any mutation (create, update, delete, send, post, modify), return "write".
|
|
61
|
+
8. Keep "reason" under 200 characters. Be terse and specific.
|
|
62
|
+
|
|
63
|
+
Return a JSON object with fields: category, reason, and confidence (a number between 0.0 and 1.0).`;
|
|
64
|
+
async function defaultClassifier(tool, payload) {
|
|
65
|
+
const apiKey = process.env.OPENROUTER_API_KEY;
|
|
66
|
+
if (!apiKey)
|
|
67
|
+
return null;
|
|
68
|
+
// Dynamic import so packages/shared doesn't force-load the AI SDK at module
|
|
69
|
+
// init time — keeps startup fast when the classifier is disabled.
|
|
70
|
+
// v6 structured-output pattern: generateText + Output.object({ schema }).
|
|
71
|
+
const [{ createOpenRouter }, { generateText, Output }] = await Promise.all([
|
|
72
|
+
import('@openrouter/ai-sdk-provider'),
|
|
73
|
+
import('ai'),
|
|
74
|
+
]);
|
|
75
|
+
const openrouter = createOpenRouter({ apiKey });
|
|
76
|
+
// Send ONLY the tool name and payload shape — values are stripped in the
|
|
77
|
+
// prompt construction below.
|
|
78
|
+
const payloadShape = shapeOnly(payload);
|
|
79
|
+
const userPrompt = `Tool: ${tool}\nPayload shape: ${JSON.stringify(payloadShape)}`;
|
|
80
|
+
// v6 structured output: pass the Zod schema via `output: Output.object({ schema })`.
|
|
81
|
+
// The parsed + validated value is returned on the `output` property of the result.
|
|
82
|
+
const { output } = await generateText({
|
|
83
|
+
model: openrouter(MODEL_ID),
|
|
84
|
+
output: Output.object({ schema: ClassificationSchema }),
|
|
85
|
+
system: SYSTEM_PROMPT,
|
|
86
|
+
prompt: userPrompt,
|
|
87
|
+
});
|
|
88
|
+
return {
|
|
89
|
+
category: output.category,
|
|
90
|
+
reason: output.reason,
|
|
91
|
+
confidence: output.confidence,
|
|
92
|
+
model: MODEL_ID,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Strip values from a payload, keeping only keys and type descriptors.
|
|
97
|
+
* Separate from the cache-key version because we want slightly more detail
|
|
98
|
+
* for the LLM (it sees type names, not just `<string>`).
|
|
99
|
+
*/
|
|
100
|
+
// TODO: `shapeOnly` here and `extractShape` in llm-classifier-cache.ts share
|
|
101
|
+
// ~95% of their logic (recursive walk, depth cap, key sorting, array
|
|
102
|
+
// handling). The only meaningful difference is the leaf format: this one
|
|
103
|
+
// uses `<${typeof value}>` for the LLM, the cache version uses `<value>`
|
|
104
|
+
// for dedup. Consolidate into a shared `walkShape(value, leafFormatter)`
|
|
105
|
+
// helper when adding support for `Map`/`Set`/`Date` so both stay in sync.
|
|
106
|
+
/**
|
|
107
|
+
* Exported for unit-test verification of the privacy guarantee. Not part of
|
|
108
|
+
* the stable public API — treat as internal.
|
|
109
|
+
* @internal
|
|
110
|
+
*/
|
|
111
|
+
function shapeOnly(value, depth = 0) {
|
|
112
|
+
if (depth > 3)
|
|
113
|
+
return '<deep>';
|
|
114
|
+
if (value === null)
|
|
115
|
+
return null;
|
|
116
|
+
if (value === undefined)
|
|
117
|
+
return undefined;
|
|
118
|
+
if (Array.isArray(value)) {
|
|
119
|
+
return value.length > 0 ? [shapeOnly(value[0], depth + 1)] : [];
|
|
120
|
+
}
|
|
121
|
+
if (typeof value === 'object') {
|
|
122
|
+
const obj = value;
|
|
123
|
+
const sorted = Object.keys(obj).sort();
|
|
124
|
+
const out = {};
|
|
125
|
+
for (const k of sorted) {
|
|
126
|
+
out[k] = shapeOnly(obj[k], depth + 1);
|
|
127
|
+
}
|
|
128
|
+
return out;
|
|
129
|
+
}
|
|
130
|
+
return `<${typeof value}>`;
|
|
131
|
+
}
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// Public API
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
/**
|
|
136
|
+
* Classify a tool call using the LLM. Returns null if the classifier is
|
|
137
|
+
* disabled (no API key), fails, or times out. Results are cached by
|
|
138
|
+
* tool + payload shape for the default TTL (24h).
|
|
139
|
+
*
|
|
140
|
+
* This function NEVER throws — all errors are caught and turned into null.
|
|
141
|
+
*/
|
|
142
|
+
async function classifyWithLLM(tool, payload, options = {}) {
|
|
143
|
+
const timeoutMs = options.timeoutMs ?? 800;
|
|
144
|
+
// Cache check — the store is async but has its own internal timeout +
|
|
145
|
+
// error handling and will resolve to null on any failure.
|
|
146
|
+
const cacheKey = (0, llm_classifier_cache_js_1.buildCacheKey)(tool, payload);
|
|
147
|
+
const store = (0, llm_classifier_cache_store_js_1.getClassifierCacheStore)();
|
|
148
|
+
const cached = await store.get(cacheKey);
|
|
149
|
+
if (cached) {
|
|
150
|
+
return cached;
|
|
151
|
+
}
|
|
152
|
+
// Select classifier impl
|
|
153
|
+
const impl = testClassifier ?? defaultClassifier;
|
|
154
|
+
// Race the classifier against a hard timeout.
|
|
155
|
+
// We track the timer so we can clear it when the classifier wins, and we
|
|
156
|
+
// attach a noop catch to the classifier promise so an eventual rejection
|
|
157
|
+
// after the race doesn't become an unhandled rejection.
|
|
158
|
+
let timer;
|
|
159
|
+
try {
|
|
160
|
+
const classifierPromise = impl(tool, payload);
|
|
161
|
+
// Swallow any post-race rejection from the losing side.
|
|
162
|
+
classifierPromise.catch(() => { });
|
|
163
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
164
|
+
timer = setTimeout(() => resolve(null), timeoutMs);
|
|
165
|
+
});
|
|
166
|
+
const result = await Promise.race([classifierPromise, timeoutPromise]);
|
|
167
|
+
if (!result)
|
|
168
|
+
return null;
|
|
169
|
+
// Cache and return. We fire-and-forget the set so a slow persistent
|
|
170
|
+
// store never blocks the gateway response. The store swallows errors
|
|
171
|
+
// internally; the `.catch` here is a belt-and-braces guard against
|
|
172
|
+
// an unhandled rejection if a future implementation throws.
|
|
173
|
+
store.set(cacheKey, result).catch(() => { });
|
|
174
|
+
return { ...result, cached: false };
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
// Log but never throw — graceful fallback to static-floor-only behavior.
|
|
178
|
+
// Bugs (Zod parse failures, typos) still surface here instead of being
|
|
179
|
+
// invisibly dropped.
|
|
180
|
+
console.warn('[llm-classifier] error, falling back to static floor', {
|
|
181
|
+
tool,
|
|
182
|
+
error: err instanceof Error ? err.message : String(err),
|
|
183
|
+
});
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
finally {
|
|
187
|
+
if (timer)
|
|
188
|
+
clearTimeout(timer);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=llm-classifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-classifier.js","sourceRoot":"","sources":["../src/llm-classifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Light-weight structured logging + tracing helpers shared by web & runner.
|
|
3
|
+
*
|
|
4
|
+
* This is deliberately NOT a full observability stack (no Sentry SDK, no
|
|
5
|
+
* OTEL exporter). It gives us JSON-per-line output that downstream log
|
|
6
|
+
* aggregators (Vercel, Fly.io, Datadog, Axiom…) can parse and index. Drop
|
|
7
|
+
* a real tracer/exporter in later by replacing these functions — every
|
|
8
|
+
* call site uses the exported names, no `console.*` sprinkled around.
|
|
9
|
+
*
|
|
10
|
+
* Design rules:
|
|
11
|
+
* - Never throw. A logger that can crash your request path is worse than
|
|
12
|
+
* a logger that silently no-ops when env is weird.
|
|
13
|
+
* - Never include secrets. Callers should `sanitizeError()` first when the
|
|
14
|
+
* payload comes from an Error object or external service response.
|
|
15
|
+
* - One line per event, minified JSON, stable field names.
|
|
16
|
+
*/
|
|
17
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
18
|
+
/**
|
|
19
|
+
* Emit a structured log line. Meant for server-side JS (Runner + Next.js
|
|
20
|
+
* route handlers). Browser code should use the console directly.
|
|
21
|
+
*
|
|
22
|
+
* The `ctx` object should contain scalar identifiers (workspace_id,
|
|
23
|
+
* request_id, agent_id, job_id) — anything else gets JSON.stringified
|
|
24
|
+
* verbatim, so don't pass objects with potential secrets.
|
|
25
|
+
*/
|
|
26
|
+
export declare function log(level: LogLevel, message: string, ctx?: Record<string, unknown>): void;
|
|
27
|
+
export declare const logInfo: (msg: string, ctx?: Record<string, unknown>) => void;
|
|
28
|
+
export declare const logWarn: (msg: string, ctx?: Record<string, unknown>) => void;
|
|
29
|
+
export declare const logDebug: (msg: string, ctx?: Record<string, unknown>) => void;
|
|
30
|
+
/**
|
|
31
|
+
* Log an Error (or unknown) under the `error` level with a sanitized
|
|
32
|
+
* message and optional context. Stack traces and connection strings are
|
|
33
|
+
* stripped by `sanitizeError()` before emit.
|
|
34
|
+
*/
|
|
35
|
+
export declare function logError(msg: string, err: unknown, ctx?: Record<string, unknown>): void;
|
|
36
|
+
//# sourceMappingURL=observability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../src/observability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAW3D;;;;;;;GAOG;AACH,wBAAgB,GAAG,CACjB,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAChC,IAAI,CAmBN;AAED,eAAO,MAAM,OAAO,GAAK,KAAK,MAAM,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SAA2B,CAAC;AAC/F,eAAO,MAAM,OAAO,GAAK,KAAK,MAAM,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SAA2B,CAAC;AAC/F,eAAO,MAAM,QAAQ,GAAI,KAAK,MAAM,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SAA2B,CAAC;AAE/F;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,OAAO,EACZ,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAChC,IAAI,CAEN"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Light-weight structured logging + tracing helpers shared by web & runner.
|
|
4
|
+
*
|
|
5
|
+
* This is deliberately NOT a full observability stack (no Sentry SDK, no
|
|
6
|
+
* OTEL exporter). It gives us JSON-per-line output that downstream log
|
|
7
|
+
* aggregators (Vercel, Fly.io, Datadog, Axiom…) can parse and index. Drop
|
|
8
|
+
* a real tracer/exporter in later by replacing these functions — every
|
|
9
|
+
* call site uses the exported names, no `console.*` sprinkled around.
|
|
10
|
+
*
|
|
11
|
+
* Design rules:
|
|
12
|
+
* - Never throw. A logger that can crash your request path is worse than
|
|
13
|
+
* a logger that silently no-ops when env is weird.
|
|
14
|
+
* - Never include secrets. Callers should `sanitizeError()` first when the
|
|
15
|
+
* payload comes from an Error object or external service response.
|
|
16
|
+
* - One line per event, minified JSON, stable field names.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.logDebug = exports.logWarn = exports.logInfo = void 0;
|
|
20
|
+
exports.log = log;
|
|
21
|
+
exports.logError = logError;
|
|
22
|
+
const sanitize_js_1 = require("./sanitize.js");
|
|
23
|
+
const LOG_LEVEL_ORDER = {
|
|
24
|
+
debug: 10, info: 20, warn: 30, error: 40,
|
|
25
|
+
};
|
|
26
|
+
function resolveMinLevel() {
|
|
27
|
+
const raw = (typeof process !== 'undefined' && process.env?.LOG_LEVEL) || 'info';
|
|
28
|
+
return LOG_LEVEL_ORDER[raw] ?? LOG_LEVEL_ORDER.info;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Emit a structured log line. Meant for server-side JS (Runner + Next.js
|
|
32
|
+
* route handlers). Browser code should use the console directly.
|
|
33
|
+
*
|
|
34
|
+
* The `ctx` object should contain scalar identifiers (workspace_id,
|
|
35
|
+
* request_id, agent_id, job_id) — anything else gets JSON.stringified
|
|
36
|
+
* verbatim, so don't pass objects with potential secrets.
|
|
37
|
+
*/
|
|
38
|
+
function log(level, message, ctx = {}) {
|
|
39
|
+
try {
|
|
40
|
+
if (LOG_LEVEL_ORDER[level] < resolveMinLevel())
|
|
41
|
+
return;
|
|
42
|
+
const line = JSON.stringify({
|
|
43
|
+
ts: new Date().toISOString(),
|
|
44
|
+
level,
|
|
45
|
+
msg: message,
|
|
46
|
+
...ctx,
|
|
47
|
+
});
|
|
48
|
+
// stderr for warn/error so error aggregators pick them up separately
|
|
49
|
+
// from info/debug; matches Fastify+pino convention.
|
|
50
|
+
if (level === 'warn' || level === 'error') {
|
|
51
|
+
process.stderr.write(line + '\n');
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
process.stdout.write(line + '\n');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
/* swallow — logging must never throw */
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const logInfo = (msg, ctx) => log('info', msg, ctx);
|
|
62
|
+
exports.logInfo = logInfo;
|
|
63
|
+
const logWarn = (msg, ctx) => log('warn', msg, ctx);
|
|
64
|
+
exports.logWarn = logWarn;
|
|
65
|
+
const logDebug = (msg, ctx) => log('debug', msg, ctx);
|
|
66
|
+
exports.logDebug = logDebug;
|
|
67
|
+
/**
|
|
68
|
+
* Log an Error (or unknown) under the `error` level with a sanitized
|
|
69
|
+
* message and optional context. Stack traces and connection strings are
|
|
70
|
+
* stripped by `sanitizeError()` before emit.
|
|
71
|
+
*/
|
|
72
|
+
function logError(msg, err, ctx = {}) {
|
|
73
|
+
log('error', msg, { ...ctx, error: (0, sanitize_js_1.sanitizeError)(err) });
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=observability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observability.js","sourceRoot":"","sources":["../src/observability.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAuBH,kBAuBC;AAWD,4BAMC;AA7DD,+CAA8C;AAI9C,MAAM,eAAe,GAA6B;IAChD,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE;CACzC,CAAC;AAEF,SAAS,eAAe;IACtB,MAAM,GAAG,GAAG,CAAC,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC;IACjF,OAAO,eAAe,CAAC,GAAe,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC;AAClE,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,GAAG,CACjB,KAAe,EACf,OAAe,EACf,MAA+B,EAAE;IAEjC,IAAI,CAAC;QACH,IAAI,eAAe,CAAC,KAAK,CAAC,GAAG,eAAe,EAAE;YAAE,OAAO;QACvD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;YAC1B,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,KAAK;YACL,GAAG,EAAE,OAAO;YACZ,GAAG,GAAG;SACP,CAAC,CAAC;QACH,qEAAqE;QACrE,oDAAoD;QACpD,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,wCAAwC;IAC1C,CAAC;AACH,CAAC;AAEM,MAAM,OAAO,GAAI,CAAC,GAAW,EAAE,GAA6B,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAG,GAAG,EAAE,GAAG,CAAC,CAAC;AAAlF,QAAA,OAAO,WAA2E;AACxF,MAAM,OAAO,GAAI,CAAC,GAAW,EAAE,GAA6B,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAG,GAAG,EAAE,GAAG,CAAC,CAAC;AAAlF,QAAA,OAAO,WAA2E;AACxF,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,GAA6B,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAAlF,QAAA,QAAQ,YAA0E;AAE/F;;;;GAIG;AACH,SAAgB,QAAQ,CACtB,GAAW,EACX,GAAY,EACZ,MAA+B,EAAE;IAEjC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,IAAA,2BAAa,EAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC"}
|
package/dist/plans.d.ts
CHANGED
|
@@ -8,6 +8,13 @@ export interface PlanLimits {
|
|
|
8
8
|
timelineHistoryDays: number;
|
|
9
9
|
undoEnabled: boolean;
|
|
10
10
|
browserSessions: number;
|
|
11
|
+
/**
|
|
12
|
+
* Maximum number of concurrent persistent SSH sessions (`ssh.open`).
|
|
13
|
+
* Free is held to 0 — those plans use one-shot `ssh.run` only. Pro and
|
|
14
|
+
* Team get a small concurrency budget. The TTL per session is enforced
|
|
15
|
+
* separately via {@link sshMaxTtlMinutes}.
|
|
16
|
+
*/
|
|
17
|
+
sshSessions: number;
|
|
11
18
|
messagesPerMonth: number;
|
|
12
19
|
messageHistoryDays: number;
|
|
13
20
|
threadsPerAgent: number;
|
|
@@ -23,6 +30,16 @@ export interface PlanDefinition extends PlanLimits {
|
|
|
23
30
|
export declare const PLANS: Record<PlanId, PlanDefinition>;
|
|
24
31
|
export declare function getPlanLimits(plan: string): PlanLimits;
|
|
25
32
|
export declare function canUndo(plan: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Maximum SSH session TTL (minutes) allowed per plan.
|
|
35
|
+
*
|
|
36
|
+
* Longer TTLs widen the blast radius if a session is hijacked or forgotten,
|
|
37
|
+
* so we cap conservatively. Team gets the industry-standard "up to one
|
|
38
|
+
* hour" window; Free/Pro are held to the shorter 20-minute cap —
|
|
39
|
+
* agents that need longer operations should re-open a session via
|
|
40
|
+
* approval rather than keep one idling.
|
|
41
|
+
*/
|
|
42
|
+
export declare function sshMaxTtlMinutes(plan: string): number;
|
|
26
43
|
/** Map a Stripe price ID back to a plan ID */
|
|
27
44
|
export declare function planFromPriceId(priceId: string): PlanId | null;
|
|
28
45
|
//# sourceMappingURL=plans.d.ts.map
|
package/dist/plans.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plans.d.ts","sourceRoot":"","sources":["../src/plans.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAE7C,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAe,SAAQ,UAAU;IAChD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"plans.d.ts","sourceRoot":"","sources":["../src/plans.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAE7C,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAe,SAAQ,UAAU;IAChD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CA6DvC,CAAC;AAEX,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAgBtD;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7C;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASrD;AAED,8CAA8C;AAC9C,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO9D"}
|
package/dist/plans.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.PLANS = void 0;
|
|
4
4
|
exports.getPlanLimits = getPlanLimits;
|
|
5
5
|
exports.canUndo = canUndo;
|
|
6
|
+
exports.sshMaxTtlMinutes = sshMaxTtlMinutes;
|
|
6
7
|
exports.planFromPriceId = planFromPriceId;
|
|
7
8
|
exports.PLANS = {
|
|
8
9
|
free: {
|
|
@@ -12,14 +13,15 @@ exports.PLANS = {
|
|
|
12
13
|
yearlyPrice: 0,
|
|
13
14
|
stripePriceMonthly: '',
|
|
14
15
|
stripePriceYearly: '',
|
|
15
|
-
actionsPerMonth:
|
|
16
|
-
agents:
|
|
16
|
+
actionsPerMonth: 100,
|
|
17
|
+
agents: 1,
|
|
17
18
|
credentials: 2,
|
|
18
19
|
members: 1,
|
|
19
20
|
policies: 3,
|
|
20
21
|
timelineHistoryDays: 14,
|
|
21
22
|
undoEnabled: false,
|
|
22
23
|
browserSessions: 0,
|
|
24
|
+
sshSessions: 0,
|
|
23
25
|
messagesPerMonth: 100,
|
|
24
26
|
messageHistoryDays: 7,
|
|
25
27
|
threadsPerAgent: 5,
|
|
@@ -28,17 +30,18 @@ exports.PLANS = {
|
|
|
28
30
|
id: 'pro',
|
|
29
31
|
name: 'Pro',
|
|
30
32
|
monthlyPrice: 900,
|
|
31
|
-
yearlyPrice:
|
|
33
|
+
yearlyPrice: 7550,
|
|
32
34
|
stripePriceMonthly: 'price_1T6b3m2NRlIkxMrBZ9bmEDYE',
|
|
33
|
-
stripePriceYearly: '
|
|
34
|
-
actionsPerMonth:
|
|
35
|
-
agents:
|
|
36
|
-
credentials:
|
|
37
|
-
members:
|
|
35
|
+
stripePriceYearly: 'price_1TQTJy2NRlIkxMrBhcSh8E8i',
|
|
36
|
+
actionsPerMonth: 2000,
|
|
37
|
+
agents: 5,
|
|
38
|
+
credentials: 15,
|
|
39
|
+
members: 3,
|
|
38
40
|
policies: 10,
|
|
39
41
|
timelineHistoryDays: 90,
|
|
40
42
|
undoEnabled: true,
|
|
41
43
|
browserSessions: 2,
|
|
44
|
+
sshSessions: 2,
|
|
42
45
|
messagesPerMonth: 5000,
|
|
43
46
|
messageHistoryDays: 30,
|
|
44
47
|
threadsPerAgent: 50,
|
|
@@ -50,23 +53,22 @@ exports.PLANS = {
|
|
|
50
53
|
yearlyPrice: 41000,
|
|
51
54
|
stripePriceMonthly: 'price_1T6b3n2NRlIkxMrBstkfVECC',
|
|
52
55
|
stripePriceYearly: 'price_1T6b3o2NRlIkxMrBzHoQKPjz',
|
|
53
|
-
actionsPerMonth:
|
|
54
|
-
agents:
|
|
56
|
+
actionsPerMonth: 10000,
|
|
57
|
+
agents: 20,
|
|
55
58
|
credentials: Infinity,
|
|
56
|
-
members:
|
|
59
|
+
members: 10,
|
|
57
60
|
policies: 50,
|
|
58
61
|
timelineHistoryDays: 365,
|
|
59
62
|
undoEnabled: true,
|
|
60
63
|
browserSessions: 5,
|
|
64
|
+
sshSessions: 5,
|
|
61
65
|
messagesPerMonth: Infinity,
|
|
62
66
|
messageHistoryDays: 90,
|
|
63
67
|
threadsPerAgent: Infinity,
|
|
64
68
|
},
|
|
65
69
|
};
|
|
66
70
|
function getPlanLimits(plan) {
|
|
67
|
-
const def = exports.PLANS[plan];
|
|
68
|
-
if (!def)
|
|
69
|
-
return exports.PLANS.free;
|
|
71
|
+
const def = exports.PLANS[plan] ?? exports.PLANS.free;
|
|
70
72
|
return {
|
|
71
73
|
actionsPerMonth: def.actionsPerMonth,
|
|
72
74
|
agents: def.agents,
|
|
@@ -76,6 +78,7 @@ function getPlanLimits(plan) {
|
|
|
76
78
|
timelineHistoryDays: def.timelineHistoryDays,
|
|
77
79
|
undoEnabled: def.undoEnabled,
|
|
78
80
|
browserSessions: def.browserSessions,
|
|
81
|
+
sshSessions: def.sshSessions,
|
|
79
82
|
messagesPerMonth: def.messagesPerMonth,
|
|
80
83
|
messageHistoryDays: def.messageHistoryDays,
|
|
81
84
|
threadsPerAgent: def.threadsPerAgent,
|
|
@@ -84,6 +87,25 @@ function getPlanLimits(plan) {
|
|
|
84
87
|
function canUndo(plan) {
|
|
85
88
|
return getPlanLimits(plan).undoEnabled;
|
|
86
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Maximum SSH session TTL (minutes) allowed per plan.
|
|
92
|
+
*
|
|
93
|
+
* Longer TTLs widen the blast radius if a session is hijacked or forgotten,
|
|
94
|
+
* so we cap conservatively. Team gets the industry-standard "up to one
|
|
95
|
+
* hour" window; Free/Pro are held to the shorter 20-minute cap —
|
|
96
|
+
* agents that need longer operations should re-open a session via
|
|
97
|
+
* approval rather than keep one idling.
|
|
98
|
+
*/
|
|
99
|
+
function sshMaxTtlMinutes(plan) {
|
|
100
|
+
switch (plan) {
|
|
101
|
+
case 'team':
|
|
102
|
+
return 60;
|
|
103
|
+
case 'pro':
|
|
104
|
+
case 'free':
|
|
105
|
+
default:
|
|
106
|
+
return 20;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
87
109
|
/** Map a Stripe price ID back to a plan ID */
|
|
88
110
|
function planFromPriceId(priceId) {
|
|
89
111
|
for (const plan of Object.values(exports.PLANS)) {
|
package/dist/plans.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plans.js","sourceRoot":"","sources":["../src/plans.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"plans.js","sourceRoot":"","sources":["../src/plans.ts"],"names":[],"mappings":";;;AA+FA,sCAgBC;AAED,0BAEC;AAWD,4CASC;AAGD,0CAOC;AAjHY,QAAA,KAAK,GAAmC;IACnD,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,MAAM;QACZ,YAAY,EAAE,CAAC;QACf,WAAW,EAAE,CAAC;QACd,kBAAkB,EAAE,EAAE;QACtB,iBAAiB,EAAE,EAAE;QACrB,eAAe,EAAE,GAAG;QACpB,MAAM,EAAE,CAAC;QACT,WAAW,EAAE,CAAC;QACd,OAAO,EAAE,CAAC;QACV,QAAQ,EAAE,CAAC;QACX,mBAAmB,EAAE,EAAE;QACvB,WAAW,EAAE,KAAK;QAClB,eAAe,EAAE,CAAC;QAClB,WAAW,EAAE,CAAC;QACd,gBAAgB,EAAE,GAAG;QACrB,kBAAkB,EAAE,CAAC;QACrB,eAAe,EAAE,CAAC;KACnB;IACD,GAAG,EAAE;QACH,EAAE,EAAE,KAAK;QACT,IAAI,EAAE,KAAK;QACX,YAAY,EAAE,GAAG;QACjB,WAAW,EAAE,IAAI;QACjB,kBAAkB,EAAE,gCAAgC;QACpD,iBAAiB,EAAE,gCAAgC;QACnD,eAAe,EAAE,IAAI;QACrB,MAAM,EAAE,CAAC;QACT,WAAW,EAAE,EAAE;QACf,OAAO,EAAE,CAAC;QACV,QAAQ,EAAE,EAAE;QACZ,mBAAmB,EAAE,EAAE;QACvB,WAAW,EAAE,IAAI;QACjB,eAAe,EAAE,CAAC;QAClB,WAAW,EAAE,CAAC;QACd,gBAAgB,EAAE,IAAI;QACtB,kBAAkB,EAAE,EAAE;QACtB,eAAe,EAAE,EAAE;KACpB;IACD,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,MAAM;QACZ,YAAY,EAAE,IAAI;QAClB,WAAW,EAAE,KAAK;QAClB,kBAAkB,EAAE,gCAAgC;QACpD,iBAAiB,EAAE,gCAAgC;QACnD,eAAe,EAAE,KAAK;QACtB,MAAM,EAAE,EAAE;QACV,WAAW,EAAE,QAAQ;QACrB,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,EAAE;QACZ,mBAAmB,EAAE,GAAG;QACxB,WAAW,EAAE,IAAI;QACjB,eAAe,EAAE,CAAC;QAClB,WAAW,EAAE,CAAC;QACd,gBAAgB,EAAE,QAAQ;QAC1B,kBAAkB,EAAE,EAAE;QACtB,eAAe,EAAE,QAAQ;KAC1B;CACO,CAAC;AAEX,SAAgB,aAAa,CAAC,IAAY;IACxC,MAAM,GAAG,GAAG,aAAK,CAAC,IAAc,CAAC,IAAI,aAAK,CAAC,IAAI,CAAC;IAChD,OAAO;QACL,eAAe,EAAE,GAAG,CAAC,eAAe;QACpC,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,mBAAmB,EAAE,GAAG,CAAC,mBAAmB;QAC5C,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,eAAe,EAAE,GAAG,CAAC,eAAe;QACpC,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;QACtC,kBAAkB,EAAE,GAAG,CAAC,kBAAkB;QAC1C,eAAe,EAAE,GAAG,CAAC,eAAe;KACrC,CAAC;AACJ,CAAC;AAED,SAAgB,OAAO,CAAC,IAAY;IAClC,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC;AACzC,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,gBAAgB,CAAC,IAAY;IAC3C,QAAQ,IAAc,EAAE,CAAC;QACvB,KAAK,MAAM;YACT,OAAO,EAAE,CAAC;QACZ,KAAK,KAAK,CAAC;QACX,KAAK,MAAM,CAAC;QACZ;YACE,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,8CAA8C;AAC9C,SAAgB,eAAe,CAAC,OAAe;IAC7C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,aAAK,CAAC,EAAE,CAAC;QACxC,IAAI,IAAI,CAAC,kBAAkB,KAAK,OAAO,IAAI,IAAI,CAAC,iBAAiB,KAAK,OAAO,EAAE,CAAC;YAC9E,OAAO,IAAI,CAAC,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|