@manifest-network/manifest-mcp-fred 0.6.1 → 0.7.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/http/auth-token-service.d.ts +27 -0
- package/dist/http/auth-token-service.d.ts.map +1 -0
- package/dist/http/auth-token-service.js +42 -0
- package/dist/http/auth-token-service.js.map +1 -0
- package/dist/http/fred.d.ts +6 -1
- package/dist/http/fred.d.ts.map +1 -1
- package/dist/http/fred.js.map +1 -1
- package/dist/index.d.ts +18 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +500 -42
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +23 -1
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +196 -1
- package/dist/manifest.js.map +1 -1
- package/dist/tools/buildManifestPreview.d.ts +74 -0
- package/dist/tools/buildManifestPreview.d.ts.map +1 -0
- package/dist/tools/buildManifestPreview.js +112 -0
- package/dist/tools/buildManifestPreview.js.map +1 -0
- package/dist/tools/checkDeploymentReadiness.d.ts +64 -0
- package/dist/tools/checkDeploymentReadiness.d.ts.map +1 -0
- package/dist/tools/checkDeploymentReadiness.js +70 -0
- package/dist/tools/checkDeploymentReadiness.js.map +1 -0
- package/dist/tools/deployApp.d.ts.map +1 -1
- package/dist/tools/deployApp.js +4 -10
- package/dist/tools/deployApp.js.map +1 -1
- package/dist/tools/waitForAppReady.d.ts +29 -0
- package/dist/tools/waitForAppReady.d.ts.map +1 -0
- package/dist/tools/waitForAppReady.js +34 -0
- package/dist/tools/waitForAppReady.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { WalletProvider } from "@manifest-network/manifest-mcp-core";
|
|
2
|
+
|
|
3
|
+
//#region src/http/auth-token-service.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Wallet-bound builder for ADR-036 provider auth tokens.
|
|
6
|
+
*
|
|
7
|
+
* Owns the stateful pieces (timestamp serialization, signArbitrary binding) so
|
|
8
|
+
* that `FredMCPServer` can depend on a single collaborator rather than hand-
|
|
9
|
+
* rolling the flow at each tool call site. The underlying stateless builders
|
|
10
|
+
* (`createSignMessage`, `createAuthToken`, etc.) remain in `./auth.ts` for
|
|
11
|
+
* library callers who need them without our specific wallet wiring.
|
|
12
|
+
*
|
|
13
|
+
* The `signArbitrary` requirement is enforced lazily — a wallet without
|
|
14
|
+
* ADR-036 support still lets the server boot and serve non-auth-gated paths;
|
|
15
|
+
* only provider-auth tool calls throw `INVALID_CONFIG`.
|
|
16
|
+
*/
|
|
17
|
+
declare class AuthTokenService {
|
|
18
|
+
private readonly walletProvider;
|
|
19
|
+
private readonly timestamps;
|
|
20
|
+
constructor(walletProvider: WalletProvider);
|
|
21
|
+
providerToken(address: string, leaseUuid: string): Promise<string>;
|
|
22
|
+
leaseDataToken(address: string, leaseUuid: string, metaHashHex: string): Promise<string>;
|
|
23
|
+
private requireSignArbitrary;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { AuthTokenService };
|
|
27
|
+
//# sourceMappingURL=auth-token-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-token-service.d.ts","names":[],"sources":["../../src/http/auth-token-service.ts"],"mappings":";;;;;AAyBA;;;;;;;;;;;cAAa,gBAAA;EAAA,iBAGkB,cAAA;EAAA,iBAFZ,UAAA;cAEY,cAAA,EAAgB,cAAA;EAEvC,aAAA,CAAc,OAAA,UAAiB,SAAA,WAAoB,OAAA;EAcnD,cAAA,CACJ,OAAA,UACA,SAAA,UACA,WAAA,WACC,OAAA;EAAA,QAmBK,oBAAA;AAAA"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { AuthTimestampTracker, createAuthToken, createLeaseDataSignMessage, createSignMessage } from "./auth.js";
|
|
2
|
+
import { ManifestMCPError, ManifestMCPErrorCode } from "@manifest-network/manifest-mcp-core";
|
|
3
|
+
//#region src/http/auth-token-service.ts
|
|
4
|
+
/**
|
|
5
|
+
* Wallet-bound builder for ADR-036 provider auth tokens.
|
|
6
|
+
*
|
|
7
|
+
* Owns the stateful pieces (timestamp serialization, signArbitrary binding) so
|
|
8
|
+
* that `FredMCPServer` can depend on a single collaborator rather than hand-
|
|
9
|
+
* rolling the flow at each tool call site. The underlying stateless builders
|
|
10
|
+
* (`createSignMessage`, `createAuthToken`, etc.) remain in `./auth.ts` for
|
|
11
|
+
* library callers who need them without our specific wallet wiring.
|
|
12
|
+
*
|
|
13
|
+
* The `signArbitrary` requirement is enforced lazily — a wallet without
|
|
14
|
+
* ADR-036 support still lets the server boot and serve non-auth-gated paths;
|
|
15
|
+
* only provider-auth tool calls throw `INVALID_CONFIG`.
|
|
16
|
+
*/
|
|
17
|
+
var AuthTokenService = class {
|
|
18
|
+
constructor(walletProvider) {
|
|
19
|
+
this.walletProvider = walletProvider;
|
|
20
|
+
this.timestamps = new AuthTimestampTracker();
|
|
21
|
+
}
|
|
22
|
+
async providerToken(address, leaseUuid) {
|
|
23
|
+
const signArbitrary = this.requireSignArbitrary();
|
|
24
|
+
const timestamp = await this.timestamps.next();
|
|
25
|
+
const { pub_key, signature } = await signArbitrary(address, createSignMessage(address, leaseUuid, timestamp));
|
|
26
|
+
return createAuthToken(address, leaseUuid, timestamp, pub_key.value, signature);
|
|
27
|
+
}
|
|
28
|
+
async leaseDataToken(address, leaseUuid, metaHashHex) {
|
|
29
|
+
const signArbitrary = this.requireSignArbitrary();
|
|
30
|
+
const timestamp = await this.timestamps.next();
|
|
31
|
+
const { pub_key, signature } = await signArbitrary(address, createLeaseDataSignMessage(leaseUuid, metaHashHex, timestamp));
|
|
32
|
+
return createAuthToken(address, leaseUuid, timestamp, pub_key.value, signature, metaHashHex);
|
|
33
|
+
}
|
|
34
|
+
requireSignArbitrary() {
|
|
35
|
+
if (!this.walletProvider.signArbitrary) throw new ManifestMCPError(ManifestMCPErrorCode.INVALID_CONFIG, "Wallet does not support signArbitrary (ADR-036). Required for provider authentication. Use a wallet provider that implements signArbitrary.");
|
|
36
|
+
return this.walletProvider.signArbitrary.bind(this.walletProvider);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
//#endregion
|
|
40
|
+
export { AuthTokenService };
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=auth-token-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-token-service.js","names":[],"sources":["../../src/http/auth-token-service.ts"],"sourcesContent":["import {\n ManifestMCPError,\n ManifestMCPErrorCode,\n type WalletProvider,\n} from '@manifest-network/manifest-mcp-core';\nimport {\n AuthTimestampTracker,\n createAuthToken,\n createLeaseDataSignMessage,\n createSignMessage,\n} from './auth.js';\n\n/**\n * Wallet-bound builder for ADR-036 provider auth tokens.\n *\n * Owns the stateful pieces (timestamp serialization, signArbitrary binding) so\n * that `FredMCPServer` can depend on a single collaborator rather than hand-\n * rolling the flow at each tool call site. The underlying stateless builders\n * (`createSignMessage`, `createAuthToken`, etc.) remain in `./auth.ts` for\n * library callers who need them without our specific wallet wiring.\n *\n * The `signArbitrary` requirement is enforced lazily — a wallet without\n * ADR-036 support still lets the server boot and serve non-auth-gated paths;\n * only provider-auth tool calls throw `INVALID_CONFIG`.\n */\nexport class AuthTokenService {\n private readonly timestamps = new AuthTimestampTracker();\n\n constructor(private readonly walletProvider: WalletProvider) {}\n\n async providerToken(address: string, leaseUuid: string): Promise<string> {\n const signArbitrary = this.requireSignArbitrary();\n const timestamp = await this.timestamps.next();\n const message = createSignMessage(address, leaseUuid, timestamp);\n const { pub_key, signature } = await signArbitrary(address, message);\n return createAuthToken(\n address,\n leaseUuid,\n timestamp,\n pub_key.value,\n signature,\n );\n }\n\n async leaseDataToken(\n address: string,\n leaseUuid: string,\n metaHashHex: string,\n ): Promise<string> {\n const signArbitrary = this.requireSignArbitrary();\n const timestamp = await this.timestamps.next();\n const message = createLeaseDataSignMessage(\n leaseUuid,\n metaHashHex,\n timestamp,\n );\n const { pub_key, signature } = await signArbitrary(address, message);\n return createAuthToken(\n address,\n leaseUuid,\n timestamp,\n pub_key.value,\n signature,\n metaHashHex,\n );\n }\n\n private requireSignArbitrary(): NonNullable<WalletProvider['signArbitrary']> {\n if (!this.walletProvider.signArbitrary) {\n throw new ManifestMCPError(\n ManifestMCPErrorCode.INVALID_CONFIG,\n 'Wallet does not support signArbitrary (ADR-036). Required for provider authentication. Use a wallet provider that implements signArbitrary.',\n );\n }\n return this.walletProvider.signArbitrary.bind(this.walletProvider);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAyBA,IAAa,mBAAb,MAA8B;CAG5B,YAAY,gBAAiD;AAAhC,OAAA,iBAAA;AAF7B,OAAiB,aAAa,IAAI,sBAAsB;;CAIxD,MAAM,cAAc,SAAiB,WAAoC;EACvE,MAAM,gBAAgB,KAAK,sBAAsB;EACjD,MAAM,YAAY,MAAM,KAAK,WAAW,MAAM;EAE9C,MAAM,EAAE,SAAS,cAAc,MAAM,cAAc,SADnC,kBAAkB,SAAS,WAAW,UAAU,CACI;AACpE,SAAO,gBACL,SACA,WACA,WACA,QAAQ,OACR,UACD;;CAGH,MAAM,eACJ,SACA,WACA,aACiB;EACjB,MAAM,gBAAgB,KAAK,sBAAsB;EACjD,MAAM,YAAY,MAAM,KAAK,WAAW,MAAM;EAM9C,MAAM,EAAE,SAAS,cAAc,MAAM,cAAc,SALnC,2BACd,WACA,aACA,UACD,CACmE;AACpE,SAAO,gBACL,SACA,WACA,WACA,QAAQ,OACR,WACA,YACD;;CAGH,uBAA6E;AAC3E,MAAI,CAAC,KAAK,eAAe,cACvB,OAAM,IAAI,iBACR,qBAAqB,gBACrB,8IACD;AAEH,SAAO,KAAK,eAAe,cAAc,KAAK,KAAK,eAAe"}
|
package/dist/http/fred.d.ts
CHANGED
|
@@ -35,7 +35,12 @@ declare function getLeaseLogs(providerUrl: string, leaseUuid: string, authToken:
|
|
|
35
35
|
interface FredLeaseProvision {
|
|
36
36
|
readonly status: string;
|
|
37
37
|
readonly fail_count: number;
|
|
38
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Set only when the most recent provisioning attempt failed. The Fred
|
|
40
|
+
* provider omits the field on success, so the optional marker matches
|
|
41
|
+
* the wire shape (and matches the same field on FredLeaseStatus above).
|
|
42
|
+
*/
|
|
43
|
+
readonly last_error?: string;
|
|
39
44
|
}
|
|
40
45
|
declare function getLeaseProvision(providerUrl: string, leaseUuid: string, authToken: string, fetchFn?: typeof globalThis.fetch): Promise<FredLeaseProvision>;
|
|
41
46
|
interface FredActionResponse {
|
package/dist/http/fred.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fred.d.ts","names":[],"sources":["../../src/http/fred.ts"],"mappings":";;;;cAaa,QAAA;AAAA,UAEI,gBAAA;EAAA,SACN,IAAA;EAAA,SACA,MAAA;EAAA,SACA,KAAA,GAAQ,MAAA;EAAA,SACR,IAAA;AAAA;AAAA,UAGM,iBAAA;EAAA,SACN,SAAA,WAAoB,gBAAA;AAAA;AAAA,UAGd,eAAA;EAAA,SACN,KAAA,EAAO,UAAA;EAAA,SACP,gBAAA;EAAA,SACA,KAAA;EAAA,SACA,KAAA,GAAQ,MAAA;EAAA,SACR,SAAA,YAAqB,gBAAA;EAAA,SACrB,SAAA,GAAY,MAAA;EAAA,SACZ,UAAA;EAAA,SACA,UAAA;EAAA,SACA,UAAA;EAAA,SACA,QAAA,GAAW,MAAA,SAAe,iBAAA;AAAA;AAAA,iBAQf,cAAA,CACpB,WAAA,UACA,SAAA,UACA,SAAA,UACA,OAAA,UAAiB,UAAA,CAAW,KAAA,GAC3B,OAAA,CAAQ,eAAA;AAAA,UAsBM,aAAA;EAAA,SACN,UAAA;EAAA,SACA,MAAA;EAAA,SACA,aAAA;EAAA,SACA,IAAA,EAAM,MAAA;AAAA;AAAA,iBAGK,YAAA,CACpB,WAAA,UACA,SAAA,UACA,SAAA,UACA,IAAA,WACA,OAAA,UAAiB,UAAA,CAAW,KAAA,GAC3B,OAAA,CAAQ,aAAA;AAAA,UAgBM,kBAAA;EAAA,SACN,MAAA;EAAA,SACA,UAAA;EAAA,
|
|
1
|
+
{"version":3,"file":"fred.d.ts","names":[],"sources":["../../src/http/fred.ts"],"mappings":"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"}
|
package/dist/http/fred.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fred.js","names":[],"sources":["../../src/http/fred.ts"],"sourcesContent":["import { toBase64 } from '@cosmjs/encoding';\nimport {\n LeaseState,\n leaseStateFromJSON,\n logger,\n} from '@manifest-network/manifest-mcp-core';\nimport {\n checkedFetch,\n ProviderApiError,\n parseJsonResponse,\n validateProviderUrl,\n} from './provider.js';\n\nexport const MAX_TAIL = 1000;\n\nexport interface FredInstanceInfo {\n readonly name: string;\n readonly status: string;\n readonly ports?: Record<string, number>;\n readonly fqdn?: string;\n}\n\nexport interface FredServiceStatus {\n readonly instances: readonly FredInstanceInfo[];\n}\n\nexport interface FredLeaseStatus {\n readonly state: LeaseState;\n readonly provision_status?: string;\n readonly phase?: string;\n readonly steps?: Record<string, string>;\n readonly instances?: readonly FredInstanceInfo[];\n readonly endpoints?: Record<string, string>;\n readonly last_error?: string;\n readonly fail_count?: number;\n readonly created_at?: string;\n readonly services?: Record<string, FredServiceStatus>;\n}\n\n/** Raw wire shape before LeaseState conversion */\ninterface RawLeaseStatus extends Omit<FredLeaseStatus, 'state'> {\n readonly state: string;\n}\n\nexport async function getLeaseStatus(\n providerUrl: string,\n leaseUuid: string,\n authToken: string,\n fetchFn?: typeof globalThis.fetch,\n): Promise<FredLeaseStatus> {\n const validated = validateProviderUrl(providerUrl);\n const url = `${validated}/v1/leases/${encodeURIComponent(leaseUuid)}/status`;\n const res = await checkedFetch(\n url,\n {\n headers: { Authorization: `Bearer ${authToken}` },\n },\n undefined,\n fetchFn,\n );\n const raw = await parseJsonResponse<RawLeaseStatus>(res, url);\n const state = leaseStateFromJSON(raw.state);\n if (state === LeaseState.UNRECOGNIZED) {\n logger.warn(\n `[getLeaseStatus] Unrecognized lease state \"${raw.state}\" for lease ${leaseUuid}. ` +\n 'The provider may be running a newer version than the client supports.',\n );\n }\n return { ...raw, state };\n}\n\nexport interface FredLeaseLogs {\n readonly lease_uuid: string;\n readonly tenant: string;\n readonly provider_uuid: string;\n readonly logs: Record<string, string>;\n}\n\nexport async function getLeaseLogs(\n providerUrl: string,\n leaseUuid: string,\n authToken: string,\n tail?: number,\n fetchFn?: typeof globalThis.fetch,\n): Promise<FredLeaseLogs> {\n const validated = validateProviderUrl(providerUrl);\n const cappedTail = tail !== undefined ? Math.min(tail, MAX_TAIL) : undefined;\n const qs = cappedTail !== undefined ? `?tail=${cappedTail}` : '';\n const url = `${validated}/v1/leases/${encodeURIComponent(leaseUuid)}/logs${qs}`;\n const res = await checkedFetch(\n url,\n {\n headers: { Authorization: `Bearer ${authToken}` },\n },\n undefined,\n fetchFn,\n );\n return await parseJsonResponse<FredLeaseLogs>(res, url);\n}\n\nexport interface FredLeaseProvision {\n readonly status: string;\n readonly fail_count: number;\n readonly last_error: string;\n}\n\nexport async function getLeaseProvision(\n providerUrl: string,\n leaseUuid: string,\n authToken: string,\n fetchFn?: typeof globalThis.fetch,\n): Promise<FredLeaseProvision> {\n const validated = validateProviderUrl(providerUrl);\n const url = `${validated}/v1/leases/${encodeURIComponent(leaseUuid)}/provision`;\n const res = await checkedFetch(\n url,\n {\n headers: { Authorization: `Bearer ${authToken}` },\n },\n undefined,\n fetchFn,\n );\n return await parseJsonResponse<FredLeaseProvision>(res, url);\n}\n\nexport interface FredActionResponse {\n readonly status: string;\n}\n\nexport async function restartLease(\n providerUrl: string,\n leaseUuid: string,\n authToken: string,\n fetchFn?: typeof globalThis.fetch,\n): Promise<FredActionResponse> {\n const validated = validateProviderUrl(providerUrl);\n const url = `${validated}/v1/leases/${encodeURIComponent(leaseUuid)}/restart`;\n const res = await checkedFetch(\n url,\n {\n method: 'POST',\n headers: { Authorization: `Bearer ${authToken}` },\n },\n undefined,\n fetchFn,\n );\n return await parseJsonResponse<FredActionResponse>(res, url);\n}\n\nexport async function updateLease(\n providerUrl: string,\n leaseUuid: string,\n payload: Uint8Array,\n authToken: string,\n fetchFn?: typeof globalThis.fetch,\n): Promise<FredActionResponse> {\n const validated = validateProviderUrl(providerUrl);\n const url = `${validated}/v1/leases/${encodeURIComponent(leaseUuid)}/update`;\n // The provider expects JSON with a base64-encoded payload (Go []byte field).\n const b64 = toBase64(payload);\n const res = await checkedFetch(\n url,\n {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${authToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ payload: b64 }),\n },\n undefined,\n fetchFn,\n );\n return await parseJsonResponse<FredActionResponse>(res, url);\n}\n\nexport interface FredLeaseRelease {\n readonly version: number;\n readonly image: string;\n readonly status: string;\n readonly created_at: string;\n readonly error?: string;\n readonly manifest?: string;\n}\n\nexport interface FredLeaseReleases {\n readonly lease_uuid: string;\n readonly tenant: string;\n readonly provider_uuid: string;\n readonly releases: readonly FredLeaseRelease[];\n}\n\nexport async function getLeaseReleases(\n providerUrl: string,\n leaseUuid: string,\n authToken: string,\n fetchFn?: typeof globalThis.fetch,\n): Promise<FredLeaseReleases> {\n const validated = validateProviderUrl(providerUrl);\n const url = `${validated}/v1/leases/${encodeURIComponent(leaseUuid)}/releases`;\n const res = await checkedFetch(\n url,\n {\n headers: { Authorization: `Bearer ${authToken}` },\n },\n undefined,\n fetchFn,\n );\n return await parseJsonResponse<FredLeaseReleases>(res, url);\n}\n\nexport interface FredLeaseInfo {\n readonly host: string;\n readonly ports?: Record<string, unknown>;\n}\n\nexport async function getLeaseInfo(\n providerUrl: string,\n leaseUuid: string,\n authToken: string,\n fetchFn?: typeof globalThis.fetch,\n): Promise<FredLeaseInfo> {\n const validated = validateProviderUrl(providerUrl);\n const url = `${validated}/v1/leases/${encodeURIComponent(leaseUuid)}/info`;\n const res = await checkedFetch(\n url,\n {\n headers: { Authorization: `Bearer ${authToken}` },\n },\n undefined,\n fetchFn,\n );\n return await parseJsonResponse<FredLeaseInfo>(res, url);\n}\n\nexport type TerminalChainLeaseState = 'closed' | 'rejected' | 'expired';\n\nexport interface TerminalChainState {\n readonly state: TerminalChainLeaseState;\n}\n\nexport interface PollOptions {\n readonly intervalMs?: number;\n readonly timeoutMs?: number;\n readonly abortSignal?: AbortSignal;\n readonly onProgress?: (status: FredLeaseStatus) => void;\n /** Runs once per iteration before the provider is queried. Non-null return throws; errors propagate. */\n readonly checkChainState?: () => Promise<TerminalChainState | null>;\n}\n\nconst CHAIN_STATE_TO_LEASE_STATE: Record<TerminalChainLeaseState, LeaseState> =\n {\n closed: LeaseState.LEASE_STATE_CLOSED,\n rejected: LeaseState.LEASE_STATE_REJECTED,\n expired: LeaseState.LEASE_STATE_EXPIRED,\n };\n\nfunction leaseStateName(state: LeaseState): string {\n return LeaseState[state] ?? String(state);\n}\n\n/**\n * Thrown by pollLeaseUntilReady when the caller's checkChainState callback\n * reports a terminal lease state on-chain. Extends ProviderApiError so\n * existing catchers keep working; use `instanceof TerminalChainStateError`\n * or read `chainState` to distinguish from provider-reported terminal states.\n */\nexport interface TerminalChainStateContext {\n readonly providerUuid?: string;\n readonly providerUrl?: string;\n}\n\nexport class TerminalChainStateError extends ProviderApiError {\n public readonly chainState: TerminalChainLeaseState;\n public readonly leaseUuid: string;\n public readonly providerUuid?: string;\n public readonly providerUrl?: string;\n\n constructor(\n leaseUuid: string,\n chainState: TerminalChainLeaseState,\n context?: TerminalChainStateContext,\n ) {\n const mapped = CHAIN_STATE_TO_LEASE_STATE[chainState];\n super(\n 0,\n `Lease ${leaseUuid} entered terminal state ${leaseStateName(mapped)} on chain`,\n );\n this.name = 'TerminalChainStateError';\n this.chainState = chainState;\n this.leaseUuid = leaseUuid;\n this.providerUuid = context?.providerUuid;\n this.providerUrl = context?.providerUrl;\n Object.setPrototypeOf(this, TerminalChainStateError.prototype);\n }\n\n /**\n * Returns a new instance with the same lease/state and the supplied context,\n * preserving the original stack trace so debugging points to where the\n * terminal state was first detected.\n */\n withContext(context: TerminalChainStateContext): TerminalChainStateError {\n const enriched = new TerminalChainStateError(\n this.leaseUuid,\n this.chainState,\n context,\n );\n if (this.stack) enriched.stack = this.stack;\n return enriched;\n }\n}\n\nfunction abortableSleep(ms: number, signal?: AbortSignal): Promise<void> {\n if (!signal) return new Promise((resolve) => setTimeout(resolve, ms));\n signal.throwIfAborted();\n return new Promise<void>((resolve, reject) => {\n const onAbort = () => {\n clearTimeout(timer);\n reject(\n signal.reason ??\n new DOMException('The operation was aborted', 'AbortError'),\n );\n };\n const timer = setTimeout(() => {\n signal.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n signal.addEventListener('abort', onAbort, { once: true });\n });\n}\n\nexport async function pollLeaseUntilReady(\n providerUrl: string,\n leaseUuid: string,\n authToken: string | (() => Promise<string>),\n opts: PollOptions = {},\n fetchFn?: typeof globalThis.fetch,\n): Promise<FredLeaseStatus> {\n const {\n intervalMs = 3_000,\n timeoutMs = 120_000,\n abortSignal,\n onProgress,\n checkChainState,\n } = opts;\n const deadline = Date.now() + timeoutMs;\n let lastState: LeaseState | undefined;\n\n while (Date.now() < deadline) {\n abortSignal?.throwIfAborted();\n if (checkChainState) {\n const chainState = await checkChainState();\n if (chainState) {\n throw new TerminalChainStateError(leaseUuid, chainState.state);\n }\n abortSignal?.throwIfAborted();\n }\n const token =\n typeof authToken === 'function' ? await authToken() : authToken;\n abortSignal?.throwIfAborted();\n const status = await getLeaseStatus(providerUrl, leaseUuid, token, fetchFn);\n lastState = status.state;\n onProgress?.(status);\n switch (status.state) {\n case LeaseState.LEASE_STATE_ACTIVE:\n return status;\n case LeaseState.LEASE_STATE_PENDING:\n break;\n case LeaseState.LEASE_STATE_CLOSED:\n case LeaseState.LEASE_STATE_REJECTED:\n case LeaseState.LEASE_STATE_EXPIRED:\n throw new ProviderApiError(\n 0,\n `Lease ${leaseUuid} entered terminal state ${leaseStateName(status.state)}`,\n );\n default:\n throw new ProviderApiError(\n 0,\n `Lease ${leaseUuid} returned unexpected state ${leaseStateName(status.state)}`,\n );\n }\n await abortableSleep(intervalMs, abortSignal);\n }\n\n throw new ProviderApiError(\n 0,\n `Lease ${leaseUuid} poll timed out after ${timeoutMs}ms (last state: ${lastState !== undefined ? leaseStateName(lastState) : 'unknown'})`,\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fred.js","names":[],"sources":["../../src/http/fred.ts"],"sourcesContent":["import { toBase64 } from '@cosmjs/encoding';\nimport {\n LeaseState,\n leaseStateFromJSON,\n logger,\n} from '@manifest-network/manifest-mcp-core';\nimport {\n checkedFetch,\n ProviderApiError,\n parseJsonResponse,\n validateProviderUrl,\n} from './provider.js';\n\nexport const MAX_TAIL = 1000;\n\nexport interface FredInstanceInfo {\n readonly name: string;\n readonly status: string;\n readonly ports?: Record<string, number>;\n readonly fqdn?: string;\n}\n\nexport interface FredServiceStatus {\n readonly instances: readonly FredInstanceInfo[];\n}\n\nexport interface FredLeaseStatus {\n readonly state: LeaseState;\n readonly provision_status?: string;\n readonly phase?: string;\n readonly steps?: Record<string, string>;\n readonly instances?: readonly FredInstanceInfo[];\n readonly endpoints?: Record<string, string>;\n readonly last_error?: string;\n readonly fail_count?: number;\n readonly created_at?: string;\n readonly services?: Record<string, FredServiceStatus>;\n}\n\n/** Raw wire shape before LeaseState conversion */\ninterface RawLeaseStatus extends Omit<FredLeaseStatus, 'state'> {\n readonly state: string;\n}\n\nexport async function getLeaseStatus(\n providerUrl: string,\n leaseUuid: string,\n authToken: string,\n fetchFn?: typeof globalThis.fetch,\n): Promise<FredLeaseStatus> {\n const validated = validateProviderUrl(providerUrl);\n const url = `${validated}/v1/leases/${encodeURIComponent(leaseUuid)}/status`;\n const res = await checkedFetch(\n url,\n {\n headers: { Authorization: `Bearer ${authToken}` },\n },\n undefined,\n fetchFn,\n );\n const raw = await parseJsonResponse<RawLeaseStatus>(res, url);\n const state = leaseStateFromJSON(raw.state);\n if (state === LeaseState.UNRECOGNIZED) {\n logger.warn(\n `[getLeaseStatus] Unrecognized lease state \"${raw.state}\" for lease ${leaseUuid}. ` +\n 'The provider may be running a newer version than the client supports.',\n );\n }\n return { ...raw, state };\n}\n\nexport interface FredLeaseLogs {\n readonly lease_uuid: string;\n readonly tenant: string;\n readonly provider_uuid: string;\n readonly logs: Record<string, string>;\n}\n\nexport async function getLeaseLogs(\n providerUrl: string,\n leaseUuid: string,\n authToken: string,\n tail?: number,\n fetchFn?: typeof globalThis.fetch,\n): Promise<FredLeaseLogs> {\n const validated = validateProviderUrl(providerUrl);\n const cappedTail = tail !== undefined ? Math.min(tail, MAX_TAIL) : undefined;\n const qs = cappedTail !== undefined ? `?tail=${cappedTail}` : '';\n const url = `${validated}/v1/leases/${encodeURIComponent(leaseUuid)}/logs${qs}`;\n const res = await checkedFetch(\n url,\n {\n headers: { Authorization: `Bearer ${authToken}` },\n },\n undefined,\n fetchFn,\n );\n return await parseJsonResponse<FredLeaseLogs>(res, url);\n}\n\nexport interface FredLeaseProvision {\n readonly status: string;\n readonly fail_count: number;\n /**\n * Set only when the most recent provisioning attempt failed. The Fred\n * provider omits the field on success, so the optional marker matches\n * the wire shape (and matches the same field on FredLeaseStatus above).\n */\n readonly last_error?: string;\n}\n\nexport async function getLeaseProvision(\n providerUrl: string,\n leaseUuid: string,\n authToken: string,\n fetchFn?: typeof globalThis.fetch,\n): Promise<FredLeaseProvision> {\n const validated = validateProviderUrl(providerUrl);\n const url = `${validated}/v1/leases/${encodeURIComponent(leaseUuid)}/provision`;\n const res = await checkedFetch(\n url,\n {\n headers: { Authorization: `Bearer ${authToken}` },\n },\n undefined,\n fetchFn,\n );\n return await parseJsonResponse<FredLeaseProvision>(res, url);\n}\n\nexport interface FredActionResponse {\n readonly status: string;\n}\n\nexport async function restartLease(\n providerUrl: string,\n leaseUuid: string,\n authToken: string,\n fetchFn?: typeof globalThis.fetch,\n): Promise<FredActionResponse> {\n const validated = validateProviderUrl(providerUrl);\n const url = `${validated}/v1/leases/${encodeURIComponent(leaseUuid)}/restart`;\n const res = await checkedFetch(\n url,\n {\n method: 'POST',\n headers: { Authorization: `Bearer ${authToken}` },\n },\n undefined,\n fetchFn,\n );\n return await parseJsonResponse<FredActionResponse>(res, url);\n}\n\nexport async function updateLease(\n providerUrl: string,\n leaseUuid: string,\n payload: Uint8Array,\n authToken: string,\n fetchFn?: typeof globalThis.fetch,\n): Promise<FredActionResponse> {\n const validated = validateProviderUrl(providerUrl);\n const url = `${validated}/v1/leases/${encodeURIComponent(leaseUuid)}/update`;\n // The provider expects JSON with a base64-encoded payload (Go []byte field).\n const b64 = toBase64(payload);\n const res = await checkedFetch(\n url,\n {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${authToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ payload: b64 }),\n },\n undefined,\n fetchFn,\n );\n return await parseJsonResponse<FredActionResponse>(res, url);\n}\n\nexport interface FredLeaseRelease {\n readonly version: number;\n readonly image: string;\n readonly status: string;\n readonly created_at: string;\n readonly error?: string;\n readonly manifest?: string;\n}\n\nexport interface FredLeaseReleases {\n readonly lease_uuid: string;\n readonly tenant: string;\n readonly provider_uuid: string;\n readonly releases: readonly FredLeaseRelease[];\n}\n\nexport async function getLeaseReleases(\n providerUrl: string,\n leaseUuid: string,\n authToken: string,\n fetchFn?: typeof globalThis.fetch,\n): Promise<FredLeaseReleases> {\n const validated = validateProviderUrl(providerUrl);\n const url = `${validated}/v1/leases/${encodeURIComponent(leaseUuid)}/releases`;\n const res = await checkedFetch(\n url,\n {\n headers: { Authorization: `Bearer ${authToken}` },\n },\n undefined,\n fetchFn,\n );\n return await parseJsonResponse<FredLeaseReleases>(res, url);\n}\n\nexport interface FredLeaseInfo {\n readonly host: string;\n readonly ports?: Record<string, unknown>;\n}\n\nexport async function getLeaseInfo(\n providerUrl: string,\n leaseUuid: string,\n authToken: string,\n fetchFn?: typeof globalThis.fetch,\n): Promise<FredLeaseInfo> {\n const validated = validateProviderUrl(providerUrl);\n const url = `${validated}/v1/leases/${encodeURIComponent(leaseUuid)}/info`;\n const res = await checkedFetch(\n url,\n {\n headers: { Authorization: `Bearer ${authToken}` },\n },\n undefined,\n fetchFn,\n );\n return await parseJsonResponse<FredLeaseInfo>(res, url);\n}\n\nexport type TerminalChainLeaseState = 'closed' | 'rejected' | 'expired';\n\nexport interface TerminalChainState {\n readonly state: TerminalChainLeaseState;\n}\n\nexport interface PollOptions {\n readonly intervalMs?: number;\n readonly timeoutMs?: number;\n readonly abortSignal?: AbortSignal;\n readonly onProgress?: (status: FredLeaseStatus) => void;\n /** Runs once per iteration before the provider is queried. Non-null return throws; errors propagate. */\n readonly checkChainState?: () => Promise<TerminalChainState | null>;\n}\n\nconst CHAIN_STATE_TO_LEASE_STATE: Record<TerminalChainLeaseState, LeaseState> =\n {\n closed: LeaseState.LEASE_STATE_CLOSED,\n rejected: LeaseState.LEASE_STATE_REJECTED,\n expired: LeaseState.LEASE_STATE_EXPIRED,\n };\n\nfunction leaseStateName(state: LeaseState): string {\n return LeaseState[state] ?? String(state);\n}\n\n/**\n * Thrown by pollLeaseUntilReady when the caller's checkChainState callback\n * reports a terminal lease state on-chain. Extends ProviderApiError so\n * existing catchers keep working; use `instanceof TerminalChainStateError`\n * or read `chainState` to distinguish from provider-reported terminal states.\n */\nexport interface TerminalChainStateContext {\n readonly providerUuid?: string;\n readonly providerUrl?: string;\n}\n\nexport class TerminalChainStateError extends ProviderApiError {\n public readonly chainState: TerminalChainLeaseState;\n public readonly leaseUuid: string;\n public readonly providerUuid?: string;\n public readonly providerUrl?: string;\n\n constructor(\n leaseUuid: string,\n chainState: TerminalChainLeaseState,\n context?: TerminalChainStateContext,\n ) {\n const mapped = CHAIN_STATE_TO_LEASE_STATE[chainState];\n super(\n 0,\n `Lease ${leaseUuid} entered terminal state ${leaseStateName(mapped)} on chain`,\n );\n this.name = 'TerminalChainStateError';\n this.chainState = chainState;\n this.leaseUuid = leaseUuid;\n this.providerUuid = context?.providerUuid;\n this.providerUrl = context?.providerUrl;\n Object.setPrototypeOf(this, TerminalChainStateError.prototype);\n }\n\n /**\n * Returns a new instance with the same lease/state and the supplied context,\n * preserving the original stack trace so debugging points to where the\n * terminal state was first detected.\n */\n withContext(context: TerminalChainStateContext): TerminalChainStateError {\n const enriched = new TerminalChainStateError(\n this.leaseUuid,\n this.chainState,\n context,\n );\n if (this.stack) enriched.stack = this.stack;\n return enriched;\n }\n}\n\nfunction abortableSleep(ms: number, signal?: AbortSignal): Promise<void> {\n if (!signal) return new Promise((resolve) => setTimeout(resolve, ms));\n signal.throwIfAborted();\n return new Promise<void>((resolve, reject) => {\n const onAbort = () => {\n clearTimeout(timer);\n reject(\n signal.reason ??\n new DOMException('The operation was aborted', 'AbortError'),\n );\n };\n const timer = setTimeout(() => {\n signal.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n signal.addEventListener('abort', onAbort, { once: true });\n });\n}\n\nexport async function pollLeaseUntilReady(\n providerUrl: string,\n leaseUuid: string,\n authToken: string | (() => Promise<string>),\n opts: PollOptions = {},\n fetchFn?: typeof globalThis.fetch,\n): Promise<FredLeaseStatus> {\n const {\n intervalMs = 3_000,\n timeoutMs = 120_000,\n abortSignal,\n onProgress,\n checkChainState,\n } = opts;\n const deadline = Date.now() + timeoutMs;\n let lastState: LeaseState | undefined;\n\n while (Date.now() < deadline) {\n abortSignal?.throwIfAborted();\n if (checkChainState) {\n const chainState = await checkChainState();\n if (chainState) {\n throw new TerminalChainStateError(leaseUuid, chainState.state);\n }\n abortSignal?.throwIfAborted();\n }\n const token =\n typeof authToken === 'function' ? await authToken() : authToken;\n abortSignal?.throwIfAborted();\n const status = await getLeaseStatus(providerUrl, leaseUuid, token, fetchFn);\n lastState = status.state;\n onProgress?.(status);\n switch (status.state) {\n case LeaseState.LEASE_STATE_ACTIVE:\n return status;\n case LeaseState.LEASE_STATE_PENDING:\n break;\n case LeaseState.LEASE_STATE_CLOSED:\n case LeaseState.LEASE_STATE_REJECTED:\n case LeaseState.LEASE_STATE_EXPIRED:\n throw new ProviderApiError(\n 0,\n `Lease ${leaseUuid} entered terminal state ${leaseStateName(status.state)}`,\n );\n default:\n throw new ProviderApiError(\n 0,\n `Lease ${leaseUuid} returned unexpected state ${leaseStateName(status.state)}`,\n );\n }\n await abortableSleep(intervalMs, abortSignal);\n }\n\n throw new ProviderApiError(\n 0,\n `Lease ${leaseUuid} poll timed out after ${timeoutMs}ms (last state: ${lastState !== undefined ? leaseStateName(lastState) : 'unknown'})`,\n );\n}\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { AuthTokenPayload, createAuthToken, createLeaseDataSignMessage, createSignMessage } from "./http/auth.js";
|
|
2
2
|
import { ConnectionDetails, InstanceInfo, LeaseConnectionResponse, ProviderApiError, ProviderHealthResponse, ServiceConnectionDetails, checkedFetch, getLeaseConnectionInfo, getProviderHealth, uploadLeaseData, validateProviderUrl } from "./http/provider.js";
|
|
3
3
|
import { FredActionResponse, FredInstanceInfo, FredLeaseInfo, FredLeaseLogs, FredLeaseProvision, FredLeaseRelease, FredLeaseReleases, FredLeaseStatus, FredServiceStatus, MAX_TAIL, PollOptions, TerminalChainLeaseState, TerminalChainState, TerminalChainStateContext, TerminalChainStateError, getLeaseInfo, getLeaseLogs, getLeaseProvision, getLeaseReleases, getLeaseStatus, pollLeaseUntilReady, restartLease, updateLease } from "./http/fred.js";
|
|
4
|
-
import { BuildManifestOptions, buildManifest, buildStackManifest, deriveAppNameFromImage, getServiceNames, isStackManifest, mergeManifest, normalizePorts, parseStackManifest, validateServiceName } from "./manifest.js";
|
|
4
|
+
import { BuildManifestOptions, ManifestFormat, ManifestValidationResult, buildManifest, buildStackManifest, deriveAppNameFromImage, getServiceNames, isStackManifest, mergeManifest, metaHashHex, normalizePorts, parseStackManifest, validateManifest, validateServiceName } from "./manifest.js";
|
|
5
5
|
import { appStatus } from "./tools/appStatus.js";
|
|
6
6
|
import { browseCatalog, mapWithConcurrency } from "./tools/browseCatalog.js";
|
|
7
|
+
import { BuildManifestPreviewInput, BuildManifestPreviewResult, ManifestPreviewServiceInput, buildManifestPreview } from "./tools/buildManifestPreview.js";
|
|
8
|
+
import { CheckDeploymentReadinessInput, CheckDeploymentReadinessResult, SkuSummary, checkDeploymentReadiness } from "./tools/checkDeploymentReadiness.js";
|
|
7
9
|
import { DeployAppInput, DeployAppResult, ServiceConfig, deployApp } from "./tools/deployApp.js";
|
|
8
10
|
import { fetchActiveLease } from "./tools/fetchActiveLease.js";
|
|
9
11
|
import { getAppLogs } from "./tools/getLogs.js";
|
|
10
12
|
import { resolveProviderUrl } from "./tools/resolveLeaseProvider.js";
|
|
11
13
|
import { restartApp } from "./tools/restartApp.js";
|
|
12
14
|
import { updateApp } from "./tools/updateApp.js";
|
|
15
|
+
import { WaitForAppReadyOptions, WaitForAppReadyResult, waitForAppReady } from "./tools/waitForAppReady.js";
|
|
13
16
|
import { CosmosClientManager, INFRASTRUCTURE_ERROR_CODES, ManifestMCPError, ManifestMCPErrorCode, ManifestMCPServerOptions, ManifestMCPServerOptions as ManifestMCPServerOptions$1, MnemonicServerConfig } from "@manifest-network/manifest-mcp-core";
|
|
14
17
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
15
18
|
|
|
@@ -18,17 +21,26 @@ declare class FredMCPServer {
|
|
|
18
21
|
private mcpServer;
|
|
19
22
|
private clientManager;
|
|
20
23
|
private walletProvider;
|
|
24
|
+
private authTokens;
|
|
21
25
|
constructor(options: ManifestMCPServerOptions$1);
|
|
22
|
-
private requireSignArbitrary;
|
|
23
|
-
private authTimestamps;
|
|
24
|
-
private getProviderAuthToken;
|
|
25
|
-
private getLeaseDataAuthToken;
|
|
26
26
|
private registerTools;
|
|
27
|
+
private registerResources;
|
|
28
|
+
private registerPrompts;
|
|
29
|
+
/**
|
|
30
|
+
* Builds a fire-and-forget progress emitter for a long-running tool.
|
|
31
|
+
* Returns `undefined` if the caller didn't request progress (no
|
|
32
|
+
* `progressToken` in `extra._meta`); callers can branch on that to skip
|
|
33
|
+
* notification work entirely.
|
|
34
|
+
*
|
|
35
|
+
* Notifications are best-effort: failures are logged but don't fail the
|
|
36
|
+
* tool. Each call increments the progress counter.
|
|
37
|
+
*/
|
|
38
|
+
private progressEmitter;
|
|
27
39
|
getServer(): Server;
|
|
28
40
|
getClientManager(): CosmosClientManager;
|
|
29
41
|
disconnect(): void;
|
|
30
42
|
}
|
|
31
43
|
declare function createMnemonicFredServer(config: MnemonicServerConfig): Promise<FredMCPServer>;
|
|
32
44
|
//#endregion
|
|
33
|
-
export { type AuthTokenPayload, type BuildManifestOptions, type ConnectionDetails, type DeployAppInput, type DeployAppResult, type FredActionResponse, type FredInstanceInfo, type FredLeaseInfo, type FredLeaseLogs, type FredLeaseProvision, type FredLeaseRelease, type FredLeaseReleases, type FredLeaseStatus, FredMCPServer, type FredServiceStatus, INFRASTRUCTURE_ERROR_CODES, type InstanceInfo, type LeaseConnectionResponse, MAX_TAIL, ManifestMCPError, ManifestMCPErrorCode, type ManifestMCPServerOptions, type PollOptions, ProviderApiError, type ProviderHealthResponse, type ServiceConfig, type ServiceConnectionDetails, type TerminalChainLeaseState, type TerminalChainState, type TerminalChainStateContext, TerminalChainStateError, appStatus, browseCatalog, buildManifest, buildStackManifest, checkedFetch, createAuthToken, createLeaseDataSignMessage, createMnemonicFredServer, createSignMessage, deployApp, deriveAppNameFromImage, fetchActiveLease, getAppLogs, getLeaseConnectionInfo, getLeaseInfo, getLeaseLogs, getLeaseProvision, getLeaseReleases, getLeaseStatus, getProviderHealth, getServiceNames, isStackManifest, mapWithConcurrency, mergeManifest, normalizePorts, parseStackManifest, pollLeaseUntilReady, resolveProviderUrl, restartApp, restartLease, updateApp, updateLease, uploadLeaseData, validateProviderUrl, validateServiceName };
|
|
45
|
+
export { type AuthTokenPayload, type BuildManifestOptions, type BuildManifestPreviewInput, type BuildManifestPreviewResult, type CheckDeploymentReadinessInput, type CheckDeploymentReadinessResult, type ConnectionDetails, type DeployAppInput, type DeployAppResult, type FredActionResponse, type FredInstanceInfo, type FredLeaseInfo, type FredLeaseLogs, type FredLeaseProvision, type FredLeaseRelease, type FredLeaseReleases, type FredLeaseStatus, FredMCPServer, type FredServiceStatus, INFRASTRUCTURE_ERROR_CODES, type InstanceInfo, type LeaseConnectionResponse, MAX_TAIL, type ManifestFormat, ManifestMCPError, ManifestMCPErrorCode, type ManifestMCPServerOptions, type ManifestPreviewServiceInput, type ManifestValidationResult, type PollOptions, ProviderApiError, type ProviderHealthResponse, type ServiceConfig, type ServiceConnectionDetails, type SkuSummary, type TerminalChainLeaseState, type TerminalChainState, type TerminalChainStateContext, TerminalChainStateError, type WaitForAppReadyOptions, type WaitForAppReadyResult, appStatus, browseCatalog, buildManifest, buildManifestPreview, buildStackManifest, checkDeploymentReadiness, checkedFetch, createAuthToken, createLeaseDataSignMessage, createMnemonicFredServer, createSignMessage, deployApp, deriveAppNameFromImage, fetchActiveLease, getAppLogs, getLeaseConnectionInfo, getLeaseInfo, getLeaseLogs, getLeaseProvision, getLeaseReleases, getLeaseStatus, getProviderHealth, getServiceNames, isStackManifest, mapWithConcurrency, mergeManifest, metaHashHex, normalizePorts, parseStackManifest, pollLeaseUntilReady, resolveProviderUrl, restartApp, restartLease, updateApp, updateLease, uploadLeaseData, validateManifest, validateProviderUrl, validateServiceName, waitForAppReady };
|
|
34
46
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;cA8Ia,aAAA;EAAA,QACH,SAAA;EAAA,QACA,aAAA;EAAA,QACA,cAAA;EAAA,QACA,UAAA;cAEI,OAAA,EAAS,0BAAA;EAAA,QA4Bb,aAAA;EAAA,QAq1BA,iBAAA;EAAA,QAgKA,eAAA;EArhCA;;;;;;;;;EAAA,QAypCA,eAAA;EA0BR,SAAA,CAAA,GAAa,MAAA;EAIb,gBAAA,CAAA,GAAoB,mBAAA;EAIpB,UAAA,CAAA;AAAA;AAAA,iBAKc,wBAAA,CACd,MAAA,EAAQ,oBAAA,GACP,OAAA,CAAQ,aAAA"}
|