@crowdedkingdoms/crowdyjs 11.1.0 → 12.1.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/MIGRATION.md +152 -0
- package/README.md +262 -0
- package/dist/crowdy-agent/browser-dispatcher.d.ts +41 -0
- package/dist/crowdy-agent/browser-dispatcher.d.ts.map +1 -0
- package/dist/crowdy-agent/browser-dispatcher.js +264 -0
- package/dist/crowdy-agent/controller.d.ts +144 -0
- package/dist/crowdy-agent/controller.d.ts.map +1 -0
- package/dist/crowdy-agent/controller.js +1239 -0
- package/dist/crowdy-agent/errors.d.ts +37 -0
- package/dist/crowdy-agent/errors.d.ts.map +1 -0
- package/dist/crowdy-agent/errors.js +107 -0
- package/dist/crowdy-agent/graphql-transport.d.ts +154 -0
- package/dist/crowdy-agent/graphql-transport.d.ts.map +1 -0
- package/dist/crowdy-agent/graphql-transport.js +854 -0
- package/dist/crowdy-agent/index.d.ts +16 -0
- package/dist/crowdy-agent/index.d.ts.map +1 -0
- package/dist/crowdy-agent/index.js +15 -0
- package/dist/crowdy-agent/registry.d.ts +29 -0
- package/dist/crowdy-agent/registry.d.ts.map +1 -0
- package/dist/crowdy-agent/registry.js +281 -0
- package/dist/crowdy-agent/schema.d.ts +72 -0
- package/dist/crowdy-agent/schema.d.ts.map +1 -0
- package/dist/crowdy-agent/schema.js +467 -0
- package/dist/crowdy-agent/studio-tools.d.ts +15 -0
- package/dist/crowdy-agent/studio-tools.d.ts.map +1 -0
- package/dist/crowdy-agent/studio-tools.js +280 -0
- package/dist/crowdy-agent/tool-descriptors.d.ts +4 -0
- package/dist/crowdy-agent/tool-descriptors.d.ts.map +1 -0
- package/dist/crowdy-agent/tool-descriptors.js +1049 -0
- package/dist/crowdy-agent/transport.d.ts +152 -0
- package/dist/crowdy-agent/transport.d.ts.map +1 -0
- package/dist/crowdy-agent/transport.js +27 -0
- package/dist/crowdy-agent/types.d.ts +328 -0
- package/dist/crowdy-agent/types.d.ts.map +1 -0
- package/dist/crowdy-agent/types.js +37 -0
- package/dist/crowdy-client.d.ts +3 -0
- package/dist/crowdy-client.d.ts.map +1 -1
- package/dist/crowdy-client.js +6 -0
- package/dist/crowdy-studio/agent-dom-shell.d.ts +68 -0
- package/dist/crowdy-studio/agent-dom-shell.d.ts.map +1 -0
- package/dist/crowdy-studio/agent-dom-shell.js +418 -0
- package/dist/crowdy-studio/controller.d.ts +74 -4
- package/dist/crowdy-studio/controller.d.ts.map +1 -1
- package/dist/crowdy-studio/controller.js +450 -17
- package/dist/crowdy-studio/dom-shell.d.ts +50 -4
- package/dist/crowdy-studio/dom-shell.d.ts.map +1 -1
- package/dist/crowdy-studio/dom-shell.js +554 -123
- package/dist/crowdy-studio/embed/dock.d.ts +56 -0
- package/dist/crowdy-studio/embed/dock.d.ts.map +1 -0
- package/dist/crowdy-studio/embed/dock.js +231 -0
- package/dist/crowdy-studio/embed/embed-styles.d.ts +12 -0
- package/dist/crowdy-studio/embed/embed-styles.d.ts.map +1 -0
- package/dist/crowdy-studio/embed/embed-styles.js +549 -0
- package/dist/crowdy-studio/embed/hud-layer.d.ts +40 -0
- package/dist/crowdy-studio/embed/hud-layer.d.ts.map +1 -0
- package/dist/crowdy-studio/embed/hud-layer.js +100 -0
- package/dist/crowdy-studio/embed/index.d.ts +5 -0
- package/dist/crowdy-studio/embed/index.d.ts.map +1 -0
- package/dist/crowdy-studio/embed/index.js +4 -0
- package/dist/crowdy-studio/embed/panel.d.ts +162 -0
- package/dist/crowdy-studio/embed/panel.d.ts.map +1 -0
- package/dist/crowdy-studio/embed/panel.js +642 -0
- package/dist/crowdy-studio/index.d.ts +9 -3
- package/dist/crowdy-studio/index.d.ts.map +1 -1
- package/dist/crowdy-studio/index.js +6 -0
- package/dist/crowdy-studio/layout.d.ts +50 -0
- package/dist/crowdy-studio/layout.d.ts.map +1 -0
- package/dist/crowdy-studio/layout.js +155 -0
- package/dist/crowdy-studio/models.d.ts +67 -0
- package/dist/crowdy-studio/models.d.ts.map +1 -1
- package/dist/crowdy-studio/mount.d.ts +15 -0
- package/dist/crowdy-studio/mount.d.ts.map +1 -1
- package/dist/crowdy-studio/mount.js +132 -3
- package/dist/crowdy-studio/splitter.d.ts +33 -0
- package/dist/crowdy-studio/splitter.d.ts.map +1 -0
- package/dist/crowdy-studio/splitter.js +133 -0
- package/dist/crowdy-studio/styles.d.ts +1 -1
- package/dist/crowdy-studio/styles.d.ts.map +1 -1
- package/dist/crowdy-studio/styles.js +128 -11
- package/dist/generated/graphql.d.ts +3753 -1
- package/dist/generated/graphql.d.ts.map +1 -1
- package/dist/generated/graphql.js +296 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/kit/npcs.d.ts.map +1 -1
- package/dist/kit/social.d.ts.map +1 -1
- package/dist/player-host/control-banner.d.ts +40 -0
- package/dist/player-host/control-banner.d.ts.map +1 -0
- package/dist/player-host/control-banner.js +252 -0
- package/dist/player-host/control-gate.d.ts +77 -0
- package/dist/player-host/control-gate.d.ts.map +1 -0
- package/dist/player-host/control-gate.js +197 -0
- package/dist/player-host/index.d.ts +7 -0
- package/dist/player-host/index.d.ts.map +1 -0
- package/dist/player-host/index.js +5 -0
- package/dist/player-host/lease-manager.d.ts +66 -0
- package/dist/player-host/lease-manager.d.ts.map +1 -0
- package/dist/player-host/lease-manager.js +428 -0
- package/dist/player-host/schemas.d.ts +9 -0
- package/dist/player-host/schemas.d.ts.map +1 -0
- package/dist/player-host/schemas.js +347 -0
- package/dist/player-host/tools.d.ts +13 -0
- package/dist/player-host/tools.d.ts.map +1 -0
- package/dist/player-host/tools.js +79 -0
- package/dist/player-host/types.d.ts +203 -0
- package/dist/player-host/types.d.ts.map +1 -0
- package/dist/player-host/types.js +1 -0
- package/package.json +17 -2
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CrowdyAgentToolRegistry } from './registry.js';
|
|
2
|
+
/** Frozen minimum registry for `crowdy.agent-tools/1`. */
|
|
3
|
+
export declare const CROWDY_AGENT_TOOL_REGISTRY_V1: CrowdyAgentToolRegistry;
|
|
4
|
+
export declare const CROWDY_AGENT_REGISTRY_V1: CrowdyAgentToolRegistry;
|
|
5
|
+
export { CrowdyAgentBrowserToolDispatcher, type CrowdyAgentBrowserDispatcherOptionsV1, type CrowdyAgentBrowserToolContextV1, type CrowdyAgentBrowserToolHandlerV1, type CrowdyAgentBrowserToolHandlersV1, } from './browser-dispatcher.js';
|
|
6
|
+
export { CrowdyStudioAgentController, CrowdyStudioAgentController as CrowdyStudioAgentClient, type CrowdyStudioAgentConnectionState, type CrowdyStudioAgentControllerOptionsV1, type CrowdyStudioAgentStateV1, } from './controller.js';
|
|
7
|
+
export { CrowdyAgentGraphQLTransport, type CrowdyAgentGraphQLSubscriptionClient, type CrowdyAgentGraphQLTransportOptions, } from './graphql-transport.js';
|
|
8
|
+
export { CROWDY_AGENT_ERROR_CODES, CrowdyAgentError, CrowdyAgentOutcomeUnknownError, toAgentError, type AgentErrorV1, type CrowdyAgentErrorCode, } from './errors.js';
|
|
9
|
+
export { FORBIDDEN_AGENT_TOOL_SURFACES, CrowdyAgentToolRegistry, isDescriptorDigest, type CrowdyAgentRegistryFilter, } from './registry.js';
|
|
10
|
+
export { FORBIDDEN_AGENT_AUTHORITY_FIELDS, assertBoundedJsonSchema, canonicalJson, deepFreeze, digestCanonicalJson, isDecimalString, sha256Digest, validateJsonSchemaValue, type JsonPrimitive, type JsonSchema, type JsonSchemaArray, type JsonSchemaBoolean, type JsonSchemaNull, type JsonSchemaNumber, type JsonSchemaObject, type JsonSchemaString, type JsonSchemaUnion, type JsonSchemaValidationOptions, } from './schema.js';
|
|
11
|
+
export { CROWDY_AGENT_TOOL_DESCRIPTORS_V1 } from './tool-descriptors.js';
|
|
12
|
+
export { createCrowdyStudioAgentTools, crowdyStudioAgentProjectTargets, type CrowdyStudioAgentToolsOptionsV1, } from './studio-tools.js';
|
|
13
|
+
export { CROWDY_AGENT_GRAPHQL_OPERATIONS_V1, type CrowdyAgentAttachResultV1, type CrowdyAgentConnectionV1, type CrowdyAgentCreateSessionInputV1, type CrowdyAgentEdgeV1, type CrowdyAgentEventSubscriptionHandlersV1, type CrowdyAgentEventSubscriptionV1, type CrowdyAgentHistoryPageV1, type CrowdyAgentPageInfoV1, type CrowdyStudioAgentTransportV1, } from './transport.js';
|
|
14
|
+
export { CROWDY_AGENT_EVENT_TYPES } from './types.js';
|
|
15
|
+
export type { CrowdyAgentApprovalPolicy, CrowdyAgentApprovalStatus, CrowdyAgentApprovalV1, CrowdyAgentBudgetDimensionV1, CrowdyAgentBudgetV1, CrowdyAgentHeartbeatV1, CrowdyAgentCheckpointFileV1, CrowdyAgentCheckpointV1, CrowdyAgentEventPayloadMap, CrowdyAgentEventType, CrowdyAgentEventV1, CrowdyAgentIdempotencyClass, CrowdyAgentLeaseStatus, CrowdyAgentLeaseV1, CrowdyAgentMessageV1, CrowdyAgentMode, CrowdyAgentPreemptionReason, CrowdyAgentRedactionAction, CrowdyAgentRedactionRuleV1, CrowdyAgentRegisteredToolV1, CrowdyAgentRunStatus, CrowdyAgentRunV1, CrowdyAgentScopeRequirementV1, CrowdyAgentSessionStatus, CrowdyAgentSessionV1, CrowdyAgentToolCallStatus, CrowdyAgentToolCallAckV1, CrowdyAgentToolDescriptorV1, CrowdyAgentToolExecutor, CrowdyAgentToolInvocationV1, CrowdyAgentToolResultStatus, CrowdyAgentToolResultV1, CrowdyAgentToolRisk, CrowdyAgentToolTimelineItemV1, } from './types.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/crowdy-agent/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAGxD,0DAA0D;AAC1D,eAAO,MAAM,6BAA6B,yBAEzC,CAAC;AACF,eAAO,MAAM,wBAAwB,yBAAgC,CAAC;AAEtE,OAAO,EACL,gCAAgC,EAChC,KAAK,qCAAqC,EAC1C,KAAK,+BAA+B,EACpC,KAAK,+BAA+B,EACpC,KAAK,gCAAgC,GACtC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,IAAI,uBAAuB,EACtD,KAAK,gCAAgC,EACrC,KAAK,oCAAoC,EACzC,KAAK,wBAAwB,GAC9B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,2BAA2B,EAC3B,KAAK,oCAAoC,EACzC,KAAK,kCAAkC,GACxC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,8BAA8B,EAC9B,YAAY,EACZ,KAAK,YAAY,EACjB,KAAK,oBAAoB,GAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,6BAA6B,EAC7B,uBAAuB,EACvB,kBAAkB,EAClB,KAAK,yBAAyB,GAC/B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,gCAAgC,EAChC,uBAAuB,EACvB,aAAa,EACb,UAAU,EACV,mBAAmB,EACnB,eAAe,EACf,YAAY,EACZ,uBAAuB,EACvB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,2BAA2B,GACjC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gCAAgC,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EACL,4BAA4B,EAC5B,+BAA+B,EAC/B,KAAK,+BAA+B,GACrC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,kCAAkC,EAClC,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,+BAA+B,EACpC,KAAK,iBAAiB,EACtB,KAAK,sCAAsC,EAC3C,KAAK,8BAA8B,EACnC,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAC1B,KAAK,4BAA4B,GAClC,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AACtD,YAAY,EACV,yBAAyB,EACzB,yBAAyB,EACzB,qBAAqB,EACrB,4BAA4B,EAC5B,mBAAmB,EACnB,sBAAsB,EACtB,2BAA2B,EAC3B,uBAAuB,EACvB,0BAA0B,EAC1B,oBAAoB,EACpB,kBAAkB,EAClB,2BAA2B,EAC3B,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,2BAA2B,EAC3B,0BAA0B,EAC1B,0BAA0B,EAC1B,2BAA2B,EAC3B,oBAAoB,EACpB,gBAAgB,EAChB,6BAA6B,EAC7B,wBAAwB,EACxB,oBAAoB,EACpB,yBAAyB,EACzB,wBAAwB,EACxB,2BAA2B,EAC3B,uBAAuB,EACvB,2BAA2B,EAC3B,2BAA2B,EAC3B,uBAAuB,EACvB,mBAAmB,EACnB,6BAA6B,GAC9B,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CrowdyAgentToolRegistry } from './registry.js';
|
|
2
|
+
import { CROWDY_AGENT_TOOL_DESCRIPTORS_V1 } from './tool-descriptors.js';
|
|
3
|
+
/** Frozen minimum registry for `crowdy.agent-tools/1`. */
|
|
4
|
+
export const CROWDY_AGENT_TOOL_REGISTRY_V1 = new CrowdyAgentToolRegistry(CROWDY_AGENT_TOOL_DESCRIPTORS_V1);
|
|
5
|
+
export const CROWDY_AGENT_REGISTRY_V1 = CROWDY_AGENT_TOOL_REGISTRY_V1;
|
|
6
|
+
export { CrowdyAgentBrowserToolDispatcher, } from './browser-dispatcher.js';
|
|
7
|
+
export { CrowdyStudioAgentController, CrowdyStudioAgentController as CrowdyStudioAgentClient, } from './controller.js';
|
|
8
|
+
export { CrowdyAgentGraphQLTransport, } from './graphql-transport.js';
|
|
9
|
+
export { CROWDY_AGENT_ERROR_CODES, CrowdyAgentError, CrowdyAgentOutcomeUnknownError, toAgentError, } from './errors.js';
|
|
10
|
+
export { FORBIDDEN_AGENT_TOOL_SURFACES, CrowdyAgentToolRegistry, isDescriptorDigest, } from './registry.js';
|
|
11
|
+
export { FORBIDDEN_AGENT_AUTHORITY_FIELDS, assertBoundedJsonSchema, canonicalJson, deepFreeze, digestCanonicalJson, isDecimalString, sha256Digest, validateJsonSchemaValue, } from './schema.js';
|
|
12
|
+
export { CROWDY_AGENT_TOOL_DESCRIPTORS_V1 } from './tool-descriptors.js';
|
|
13
|
+
export { createCrowdyStudioAgentTools, crowdyStudioAgentProjectTargets, } from './studio-tools.js';
|
|
14
|
+
export { CROWDY_AGENT_GRAPHQL_OPERATIONS_V1, } from './transport.js';
|
|
15
|
+
export { CROWDY_AGENT_EVENT_TYPES } from './types.js';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { CrowdyAgentMode, CrowdyAgentRegisteredToolV1, CrowdyAgentToolDescriptorV1, CrowdyAgentToolExecutor } from './types.js';
|
|
2
|
+
/** Names whose presence would create ambient or arbitrary authority. */
|
|
3
|
+
export declare const FORBIDDEN_AGENT_TOOL_SURFACES: readonly ["graphql", "fetch", "http", "url", "socket", "shell", "process", "filesystem", "dom", "keyboard", "mouse", "pointer", "host_call", "playercodebroker", "udp", "token", "cookie", "storage", "devtools", "database", "buddy"];
|
|
4
|
+
export interface CrowdyAgentRegistryFilter {
|
|
5
|
+
readonly mode?: CrowdyAgentMode;
|
|
6
|
+
readonly executor?: CrowdyAgentToolExecutor;
|
|
7
|
+
/** Effective scopes filter descriptors; it never grants a scope. */
|
|
8
|
+
readonly availableScopes?: ReadonlySet<string>;
|
|
9
|
+
}
|
|
10
|
+
/** Immutable, exact-lookup registry pinned by a canonical digest. */
|
|
11
|
+
export declare class CrowdyAgentToolRegistry {
|
|
12
|
+
readonly contractVersion: "crowdy.agent-tools/1";
|
|
13
|
+
readonly registryDigest: `sha256:${string}`;
|
|
14
|
+
private readonly entries;
|
|
15
|
+
private readonly byLogical;
|
|
16
|
+
private readonly byWire;
|
|
17
|
+
constructor(descriptors: readonly CrowdyAgentToolDescriptorV1[]);
|
|
18
|
+
list(filter?: CrowdyAgentRegistryFilter): readonly CrowdyAgentRegisteredToolV1[];
|
|
19
|
+
get(name: string, version: string): CrowdyAgentRegisteredToolV1 | undefined;
|
|
20
|
+
require(name: string, version: string): CrowdyAgentRegisteredToolV1;
|
|
21
|
+
/** Exact, case-sensitive provider wire-name reverse lookup. */
|
|
22
|
+
fromWireName(wireName: string): CrowdyAgentRegisteredToolV1;
|
|
23
|
+
validateInput(name: string, version: string, value: unknown): void;
|
|
24
|
+
validateOutput(name: string, version: string, value: unknown): void;
|
|
25
|
+
/** Resolve conditional requirements from already validated arguments. */
|
|
26
|
+
requiredScopes(name: string, version: string, argumentsValue: unknown): readonly string[];
|
|
27
|
+
}
|
|
28
|
+
export declare function isDescriptorDigest(value: string): value is `sha256:${string}`;
|
|
29
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/crowdy-agent/registry.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,eAAe,EACf,2BAA2B,EAC3B,2BAA2B,EAC3B,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAUpB,wEAAwE;AACxE,eAAO,MAAM,6BAA6B,wOAsB/B,CAAC;AAEZ,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,uBAAuB,CAAC;IAC5C,oEAAoE;IACpE,QAAQ,CAAC,eAAe,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAChD;AAED,qEAAqE;AACrE,qBAAa,uBAAuB;IAClC,QAAQ,CAAC,eAAe,EAAG,sBAAsB,CAAU;IAC3D,QAAQ,CAAC,cAAc,EAAE,UAAU,MAAM,EAAE,CAAC;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkD;IAC5E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkD;gBAE7D,WAAW,EAAE,SAAS,2BAA2B,EAAE;IA8B/D,IAAI,CAAC,MAAM,GAAE,yBAA8B,GAAG,SAAS,2BAA2B,EAAE;IAepF,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,2BAA2B,GAAG,SAAS;IAI3E,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,2BAA2B;IAcnE,+DAA+D;IAC/D,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,2BAA2B;IAW3D,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAMlE,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAMnE,yEAAyE;IACzE,cAAc,CACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,OAAO,GACtB,SAAS,MAAM,EAAE;CAyBrB;AAoMD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,UAAU,MAAM,EAAE,CAE7E"}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { CrowdyAgentError } from './errors.js';
|
|
2
|
+
import { assertBoundedJsonSchema, canonicalJson, deepFreeze, digestCanonicalJson, validateJsonSchemaValue, } from './schema.js';
|
|
3
|
+
const WIRE_NAME = /^[A-Za-z0-9_-]{1,64}$/u;
|
|
4
|
+
const LOGICAL_NAME = /^(?:studio|project|workspace|library|template|diagnostics|runtime|game)\.[a-z0-9_]+(?:\.[a-z0-9_]+)*$/u;
|
|
5
|
+
const SEMVER = /^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$/u;
|
|
6
|
+
const DIGEST = /^sha256:[0-9a-f]{64}$/u;
|
|
7
|
+
const REDACTION_PATH = /^\$(?:\.[A-Za-z_][A-Za-z0-9_]*|\[\*\])*$/u;
|
|
8
|
+
/** Names whose presence would create ambient or arbitrary authority. */
|
|
9
|
+
export const FORBIDDEN_AGENT_TOOL_SURFACES = Object.freeze([
|
|
10
|
+
'graphql',
|
|
11
|
+
'fetch',
|
|
12
|
+
'http',
|
|
13
|
+
'url',
|
|
14
|
+
'socket',
|
|
15
|
+
'shell',
|
|
16
|
+
'process',
|
|
17
|
+
'filesystem',
|
|
18
|
+
'dom',
|
|
19
|
+
'keyboard',
|
|
20
|
+
'mouse',
|
|
21
|
+
'pointer',
|
|
22
|
+
'host_call',
|
|
23
|
+
'playercodebroker',
|
|
24
|
+
'udp',
|
|
25
|
+
'token',
|
|
26
|
+
'cookie',
|
|
27
|
+
'storage',
|
|
28
|
+
'devtools',
|
|
29
|
+
'database',
|
|
30
|
+
'buddy',
|
|
31
|
+
]);
|
|
32
|
+
/** Immutable, exact-lookup registry pinned by a canonical digest. */
|
|
33
|
+
export class CrowdyAgentToolRegistry {
|
|
34
|
+
constructor(descriptors) {
|
|
35
|
+
this.contractVersion = 'crowdy.agent-tools/1';
|
|
36
|
+
this.byLogical = new Map();
|
|
37
|
+
this.byWire = new Map();
|
|
38
|
+
if (descriptors.length === 0 || descriptors.length > 256) {
|
|
39
|
+
throw descriptorError('Registry must contain 1 to 256 tools');
|
|
40
|
+
}
|
|
41
|
+
const entries = descriptors
|
|
42
|
+
.map((descriptor) => registerDescriptor(descriptor))
|
|
43
|
+
.sort((left, right) => descriptorKey(left.descriptor).localeCompare(descriptorKey(right.descriptor)));
|
|
44
|
+
for (const entry of entries) {
|
|
45
|
+
const key = descriptorKey(entry.descriptor);
|
|
46
|
+
if (this.byLogical.has(key)) {
|
|
47
|
+
throw descriptorError(`Duplicate tool descriptor ${key}`);
|
|
48
|
+
}
|
|
49
|
+
if (this.byWire.has(entry.descriptor.wireName)) {
|
|
50
|
+
throw descriptorError(`Duplicate tool wire name ${entry.descriptor.wireName}`);
|
|
51
|
+
}
|
|
52
|
+
this.byLogical.set(key, entry);
|
|
53
|
+
this.byWire.set(entry.descriptor.wireName, entry);
|
|
54
|
+
}
|
|
55
|
+
this.entries = deepFreeze(entries);
|
|
56
|
+
this.registryDigest = digestCanonicalJson({
|
|
57
|
+
contract: this.contractVersion,
|
|
58
|
+
descriptors: entries.map(({ descriptor, descriptorDigest }) => ({
|
|
59
|
+
descriptor,
|
|
60
|
+
descriptorDigest,
|
|
61
|
+
})),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
list(filter = {}) {
|
|
65
|
+
return this.entries.filter(({ descriptor }) => {
|
|
66
|
+
if (filter.mode && !descriptor.modes.includes(filter.mode))
|
|
67
|
+
return false;
|
|
68
|
+
if (filter.executor && descriptor.executor !== filter.executor)
|
|
69
|
+
return false;
|
|
70
|
+
if (filter.availableScopes) {
|
|
71
|
+
return descriptor.scopes
|
|
72
|
+
.filter((requirement) => !requirement.when)
|
|
73
|
+
.every((requirement) => filter.availableScopes?.has(requirement.scope));
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
get(name, version) {
|
|
79
|
+
return this.byLogical.get(`${name}@${version}`);
|
|
80
|
+
}
|
|
81
|
+
require(name, version) {
|
|
82
|
+
const entry = this.get(name, version);
|
|
83
|
+
if (!entry) {
|
|
84
|
+
const knownName = this.entries.some(({ descriptor }) => descriptor.name === name);
|
|
85
|
+
throw new CrowdyAgentError(knownName ? 'AGENT_TOOL_VERSION_UNSUPPORTED' : 'AGENT_TOOL_UNKNOWN', knownName
|
|
86
|
+
? `Unsupported ${name} tool version ${version}`
|
|
87
|
+
: `Unknown agent tool ${name}`);
|
|
88
|
+
}
|
|
89
|
+
return entry;
|
|
90
|
+
}
|
|
91
|
+
/** Exact, case-sensitive provider wire-name reverse lookup. */
|
|
92
|
+
fromWireName(wireName) {
|
|
93
|
+
const entry = this.byWire.get(wireName);
|
|
94
|
+
if (!entry) {
|
|
95
|
+
throw new CrowdyAgentError('AGENT_TOOL_UNKNOWN', `Unknown agent tool wire name ${wireName}`);
|
|
96
|
+
}
|
|
97
|
+
return entry;
|
|
98
|
+
}
|
|
99
|
+
validateInput(name, version, value) {
|
|
100
|
+
validateJsonSchemaValue(this.require(name, version).descriptor.inputSchema, value, {
|
|
101
|
+
direction: 'INPUT',
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
validateOutput(name, version, value) {
|
|
105
|
+
validateJsonSchemaValue(this.require(name, version).descriptor.outputSchema, value, {
|
|
106
|
+
direction: 'OUTPUT',
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/** Resolve conditional requirements from already validated arguments. */
|
|
110
|
+
requiredScopes(name, version, argumentsValue) {
|
|
111
|
+
const entry = this.require(name, version);
|
|
112
|
+
this.validateInput(name, version, argumentsValue);
|
|
113
|
+
return entry.descriptor.scopes
|
|
114
|
+
.filter((requirement) => {
|
|
115
|
+
if (!requirement.when)
|
|
116
|
+
return true;
|
|
117
|
+
const values = resolveArgumentPath(argumentsValue, requirement.when.argumentPath);
|
|
118
|
+
return requirement.when.operator === 'EQUALS'
|
|
119
|
+
? values.some((value) => Object.is(value, requirement.when?.value))
|
|
120
|
+
: values.some((value) => Array.isArray(value) &&
|
|
121
|
+
value.some((entry) => Object.is(entry, requirement.when?.value))) ||
|
|
122
|
+
values.some((value) => Object.is(value, requirement.when?.value));
|
|
123
|
+
})
|
|
124
|
+
.map((requirement) => requirement.scope);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function registerDescriptor(source) {
|
|
128
|
+
validateDescriptor(source);
|
|
129
|
+
const descriptor = deepFreeze(JSON.parse(canonicalJson(source)));
|
|
130
|
+
const descriptorDigest = digestCanonicalJson(descriptor);
|
|
131
|
+
return deepFreeze({ descriptor, descriptorDigest });
|
|
132
|
+
}
|
|
133
|
+
function validateDescriptor(descriptor) {
|
|
134
|
+
if (descriptor.schemaVersion !== 'crowdy.agent-tool/1') {
|
|
135
|
+
throw descriptorError('Unsupported descriptor schemaVersion');
|
|
136
|
+
}
|
|
137
|
+
if (!LOGICAL_NAME.test(descriptor.name)) {
|
|
138
|
+
throw descriptorError(`Invalid logical tool name ${descriptor.name}`);
|
|
139
|
+
}
|
|
140
|
+
if (!WIRE_NAME.test(descriptor.wireName)) {
|
|
141
|
+
throw descriptorError(`Invalid tool wire name ${descriptor.wireName}`);
|
|
142
|
+
}
|
|
143
|
+
if (!SEMVER.test(descriptor.version)) {
|
|
144
|
+
throw descriptorError(`Invalid tool semantic version ${descriptor.version}`);
|
|
145
|
+
}
|
|
146
|
+
const major = descriptor.version.split('.')[0];
|
|
147
|
+
if (!descriptor.wireName.endsWith(`_v${major}`)) {
|
|
148
|
+
throw descriptorError(`Tool wire name ${descriptor.wireName} must include major suffix _v${major}`);
|
|
149
|
+
}
|
|
150
|
+
const authoritySurface = `${descriptor.name}.${descriptor.wireName}`.toLowerCase();
|
|
151
|
+
const forbidden = FORBIDDEN_AGENT_TOOL_SURFACES.find((part) => authoritySurface.includes(part));
|
|
152
|
+
if (forbidden) {
|
|
153
|
+
throw descriptorError(`Tool ${descriptor.name} exposes forbidden surface ${forbidden}`);
|
|
154
|
+
}
|
|
155
|
+
if (descriptor.summary.length < 8 || descriptor.summary.length > 240) {
|
|
156
|
+
throw descriptorError(`${descriptor.name} summary must be 8 to 240 characters`);
|
|
157
|
+
}
|
|
158
|
+
if (descriptor.modes.length === 0 ||
|
|
159
|
+
new Set(descriptor.modes).size !== descriptor.modes.length) {
|
|
160
|
+
throw descriptorError(`${descriptor.name} modes must be non-empty and unique`);
|
|
161
|
+
}
|
|
162
|
+
assertBoundedJsonSchema(descriptor.inputSchema, {
|
|
163
|
+
rejectAuthorityFields: true,
|
|
164
|
+
});
|
|
165
|
+
assertBoundedJsonSchema(descriptor.outputSchema, {
|
|
166
|
+
rejectAuthorityFields: false,
|
|
167
|
+
});
|
|
168
|
+
if (!Number.isSafeInteger(descriptor.timeoutMs) ||
|
|
169
|
+
descriptor.timeoutMs < 50 ||
|
|
170
|
+
descriptor.timeoutMs > 120000) {
|
|
171
|
+
throw descriptorError(`${descriptor.name} timeout must be 50..120000ms`);
|
|
172
|
+
}
|
|
173
|
+
if (!Number.isSafeInteger(descriptor.approval.maxTtlSeconds) ||
|
|
174
|
+
descriptor.approval.maxTtlSeconds < 0 ||
|
|
175
|
+
descriptor.approval.maxTtlSeconds > 300) {
|
|
176
|
+
throw descriptorError(`${descriptor.name} approval TTL must be 0..300 seconds`);
|
|
177
|
+
}
|
|
178
|
+
const approvalRequired = ['DESTRUCTIVE', 'TRUST_CONSENT', 'ECONOMIC', 'IRREVERSIBLE'].includes(descriptor.risk.class);
|
|
179
|
+
if (approvalRequired && descriptor.approval.policy !== 'REQUIRED') {
|
|
180
|
+
throw descriptorError(`${descriptor.name} risk requires exact human approval`);
|
|
181
|
+
}
|
|
182
|
+
if (descriptor.approval.policy === 'NONE' &&
|
|
183
|
+
(descriptor.approval.reasons.length !== 0 ||
|
|
184
|
+
descriptor.approval.maxTtlSeconds !== 0)) {
|
|
185
|
+
throw descriptorError(`${descriptor.name} no-approval metadata is inconsistent`);
|
|
186
|
+
}
|
|
187
|
+
if (descriptor.approval.policy !== 'NONE' &&
|
|
188
|
+
(descriptor.approval.reasons.length === 0 ||
|
|
189
|
+
descriptor.approval.maxTtlSeconds === 0)) {
|
|
190
|
+
throw descriptorError(`${descriptor.name} approval reasons and TTL are required`);
|
|
191
|
+
}
|
|
192
|
+
if (descriptor.executor === 'BROWSER' &&
|
|
193
|
+
!['PURE', 'TOOL_CALL_ONCE', 'NON_RETRYABLE'].includes(descriptor.idempotency.class)) {
|
|
194
|
+
throw descriptorError(`${descriptor.name} browser idempotency class is unsafe`);
|
|
195
|
+
}
|
|
196
|
+
validateKeyScope(descriptor);
|
|
197
|
+
validateRedaction(descriptor);
|
|
198
|
+
if (descriptor.scopes.length > 16) {
|
|
199
|
+
throw descriptorError(`${descriptor.name} has too many scope requirements`);
|
|
200
|
+
}
|
|
201
|
+
for (const requirement of descriptor.scopes) {
|
|
202
|
+
if (!/^[a-z][a-z0-9_.]{1,79}$/u.test(requirement.scope)) {
|
|
203
|
+
throw descriptorError(`${descriptor.name} has invalid scope ${requirement.scope}`);
|
|
204
|
+
}
|
|
205
|
+
if (requirement.when &&
|
|
206
|
+
(!REDACTION_PATH.test(requirement.when.argumentPath) ||
|
|
207
|
+
requirement.when.argumentPath.includes('[*]') === false &&
|
|
208
|
+
requirement.when.operator === 'CONTAINS')) {
|
|
209
|
+
throw descriptorError(`${descriptor.name} has invalid conditional scope`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function validateKeyScope(descriptor) {
|
|
214
|
+
const expected = descriptor.idempotency.class === 'PURE'
|
|
215
|
+
? 'NONE'
|
|
216
|
+
: descriptor.idempotency.class === 'KEYED'
|
|
217
|
+
? 'USER_TOOL_ARGUMENTS'
|
|
218
|
+
: 'TOOL_CALL';
|
|
219
|
+
if (descriptor.idempotency.keyScope !== expected) {
|
|
220
|
+
throw descriptorError(`${descriptor.name} idempotency key scope must be ${expected}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
function validateRedaction(descriptor) {
|
|
224
|
+
if (!Number.isSafeInteger(descriptor.redaction.maxPersistedBytes) ||
|
|
225
|
+
descriptor.redaction.maxPersistedBytes < 0 ||
|
|
226
|
+
descriptor.redaction.maxPersistedBytes > 65536) {
|
|
227
|
+
throw descriptorError(`${descriptor.name} persisted byte bound is invalid`);
|
|
228
|
+
}
|
|
229
|
+
for (const rule of [
|
|
230
|
+
...descriptor.redaction.input,
|
|
231
|
+
...descriptor.redaction.output,
|
|
232
|
+
]) {
|
|
233
|
+
if (!REDACTION_PATH.test(rule.path)) {
|
|
234
|
+
throw descriptorError(`${descriptor.name} has invalid redaction path ${rule.path}`);
|
|
235
|
+
}
|
|
236
|
+
if (rule.action === 'TRUNCATE' &&
|
|
237
|
+
(!Number.isSafeInteger(rule.maxBytes) ||
|
|
238
|
+
(rule.maxBytes ?? 0) < 1 ||
|
|
239
|
+
(rule.maxBytes ?? 0) > descriptor.redaction.maxPersistedBytes)) {
|
|
240
|
+
throw descriptorError(`${descriptor.name} truncate rule needs bounded maxBytes`);
|
|
241
|
+
}
|
|
242
|
+
if (rule.action !== 'TRUNCATE' && rule.maxBytes !== undefined) {
|
|
243
|
+
throw descriptorError(`${descriptor.name} maxBytes is only valid for TRUNCATE`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function descriptorKey(descriptor) {
|
|
248
|
+
return `${descriptor.name}@${descriptor.version}`;
|
|
249
|
+
}
|
|
250
|
+
function descriptorError(message) {
|
|
251
|
+
return new CrowdyAgentError('AGENT_TOOL_DESCRIPTOR_INVALID', message);
|
|
252
|
+
}
|
|
253
|
+
function resolveArgumentPath(value, path) {
|
|
254
|
+
const segments = path
|
|
255
|
+
.slice(2)
|
|
256
|
+
.split('.')
|
|
257
|
+
.filter(Boolean);
|
|
258
|
+
let values = [value];
|
|
259
|
+
for (const segment of segments) {
|
|
260
|
+
const wildcard = segment.endsWith('[*]');
|
|
261
|
+
const key = wildcard ? segment.slice(0, -3) : segment;
|
|
262
|
+
const next = [];
|
|
263
|
+
for (const candidate of values) {
|
|
264
|
+
if (candidate === null ||
|
|
265
|
+
typeof candidate !== 'object' ||
|
|
266
|
+
Array.isArray(candidate)) {
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
const child = candidate[key];
|
|
270
|
+
if (wildcard && Array.isArray(child))
|
|
271
|
+
next.push(...child);
|
|
272
|
+
else if (!wildcard)
|
|
273
|
+
next.push(child);
|
|
274
|
+
}
|
|
275
|
+
values = next;
|
|
276
|
+
}
|
|
277
|
+
return values;
|
|
278
|
+
}
|
|
279
|
+
export function isDescriptorDigest(value) {
|
|
280
|
+
return DIGEST.test(value);
|
|
281
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export type JsonPrimitive = string | number | boolean | null;
|
|
2
|
+
interface JsonSchemaBase {
|
|
3
|
+
readonly description?: string;
|
|
4
|
+
readonly enum?: readonly JsonPrimitive[];
|
|
5
|
+
readonly const?: JsonPrimitive;
|
|
6
|
+
}
|
|
7
|
+
export interface JsonSchemaString extends JsonSchemaBase {
|
|
8
|
+
readonly type: 'string';
|
|
9
|
+
readonly minLength?: number;
|
|
10
|
+
readonly maxLength?: number;
|
|
11
|
+
readonly pattern?: string;
|
|
12
|
+
readonly format?: 'uuid' | 'date-time';
|
|
13
|
+
}
|
|
14
|
+
export interface JsonSchemaNumber extends JsonSchemaBase {
|
|
15
|
+
readonly type: 'number' | 'integer';
|
|
16
|
+
readonly minimum?: number;
|
|
17
|
+
readonly maximum?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface JsonSchemaBoolean extends JsonSchemaBase {
|
|
20
|
+
readonly type: 'boolean';
|
|
21
|
+
}
|
|
22
|
+
export interface JsonSchemaNull extends JsonSchemaBase {
|
|
23
|
+
readonly type: 'null';
|
|
24
|
+
}
|
|
25
|
+
export interface JsonSchemaArray extends JsonSchemaBase {
|
|
26
|
+
readonly type: 'array';
|
|
27
|
+
readonly minItems?: number;
|
|
28
|
+
readonly maxItems: number;
|
|
29
|
+
readonly uniqueItems?: boolean;
|
|
30
|
+
readonly items: JsonSchema;
|
|
31
|
+
}
|
|
32
|
+
export interface JsonSchemaObject extends JsonSchemaBase {
|
|
33
|
+
readonly type: 'object';
|
|
34
|
+
readonly additionalProperties: false;
|
|
35
|
+
readonly required: readonly string[];
|
|
36
|
+
readonly properties: Readonly<Record<string, JsonSchema>>;
|
|
37
|
+
readonly minProperties?: number;
|
|
38
|
+
readonly maxProperties?: number;
|
|
39
|
+
}
|
|
40
|
+
export interface JsonSchemaUnion {
|
|
41
|
+
readonly oneOf: readonly JsonSchema[];
|
|
42
|
+
readonly description?: string;
|
|
43
|
+
}
|
|
44
|
+
export type JsonSchema = JsonSchemaString | JsonSchemaNumber | JsonSchemaBoolean | JsonSchemaNull | JsonSchemaArray | JsonSchemaObject | JsonSchemaUnion;
|
|
45
|
+
export interface JsonSchemaValidationOptions {
|
|
46
|
+
/** Stable code distinguishes provider arguments from executor results. */
|
|
47
|
+
direction?: 'INPUT' | 'OUTPUT' | 'SCHEMA';
|
|
48
|
+
maxDepth?: number;
|
|
49
|
+
maxNodes?: number;
|
|
50
|
+
maxBytes?: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Fields the model must never supply. They are injected from authenticated
|
|
54
|
+
* session, dispatch, approval, and lease context.
|
|
55
|
+
*/
|
|
56
|
+
export declare const FORBIDDEN_AGENT_AUTHORITY_FIELDS: readonly ["userId", "ownerUserId", "appId", "projectId", "gridId", "sessionId", "runId", "toolCallId", "clientEpoch", "leaseId", "lease", "approval", "approvalGrant", "argumentHash", "descriptorDigest", "idempotencyKey", "deadline", "token", "authorization", "headers", "endpoint", "url", "permissions", "authority"];
|
|
57
|
+
/** Validate a schema itself before it enters an immutable registry. */
|
|
58
|
+
export declare function assertBoundedJsonSchema(schema: JsonSchemaObject, options?: {
|
|
59
|
+
rejectAuthorityFields?: boolean;
|
|
60
|
+
}): void;
|
|
61
|
+
/** Strictly validate JSON data and reject unknown fields or unbounded values. */
|
|
62
|
+
export declare function validateJsonSchemaValue(schema: JsonSchema, value: unknown, options?: JsonSchemaValidationOptions): void;
|
|
63
|
+
/** RFC-8785-compatible canonical JSON for the JSON subset used by contracts. */
|
|
64
|
+
export declare function canonicalJson(value: unknown): string;
|
|
65
|
+
/** Synchronous browser-safe SHA-256 used for descriptor and content digests. */
|
|
66
|
+
export declare function sha256Digest(value: string | Uint8Array): `sha256:${string}`;
|
|
67
|
+
export declare function digestCanonicalJson(value: unknown): `sha256:${string}`;
|
|
68
|
+
/** Recursively freeze a JSON-like contract object. */
|
|
69
|
+
export declare function deepFreeze<T>(value: T): Readonly<T>;
|
|
70
|
+
export declare function isDecimalString(value: string): boolean;
|
|
71
|
+
export {};
|
|
72
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/crowdy-agent/schema.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAE7D,UAAU,cAAc;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;CAChC;AAED,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACtD,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;CACxC;AAED,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACtD,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;CAC1B;AAED,MAAM,WAAW,cAAe,SAAQ,cAAc;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACtD,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,oBAAoB,EAAE,KAAK,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAC1D,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,MAAM,UAAU,GAClB,gBAAgB,GAChB,gBAAgB,GAChB,iBAAiB,GACjB,cAAc,GACd,eAAe,GACf,gBAAgB,GAChB,eAAe,CAAC;AAEpB,MAAM,WAAW,2BAA2B;IAC1C,0EAA0E;IAC1E,SAAS,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAWD;;;GAGG;AACH,eAAO,MAAM,gCAAgC,8TAyBlC,CAAC;AAMZ,uEAAuE;AACvE,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE;IAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAAO,GAChD,IAAI,CAGN;AAED,iFAAiF;AACjF,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,2BAAgC,GACxC,IAAI,CA2BN;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEpD;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,MAAM,EAAE,CAK3E;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,MAAM,EAAE,CAEtE;AAED,sDAAsD;AACtD,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAQnD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEtD"}
|