@gdrl/kronos-lib 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +12 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +12 -4
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/{types-Gt5ZdRxW.d.mts → types-Cn8Lsqkz.d.mts} +10 -0
- package/dist/{types-Gt5ZdRxW.d.ts → types-Cn8Lsqkz.d.ts} +10 -0
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -81,6 +81,14 @@ await client.refreshCollections({ episode_ids: ['ep-1', 'ep-2'] });
|
|
|
81
81
|
| `appId` | App ID; injected into Worker and Mastra request bodies. |
|
|
82
82
|
| `tenantUserId`| Tenant/user ID; injected into request bodies. |
|
|
83
83
|
|
|
84
|
+
### Local development
|
|
85
|
+
|
|
86
|
+
When `NODE_ENV` is not `production`, the client defaults to local URLs:
|
|
87
|
+
- Worker: `http://localhost:8787`
|
|
88
|
+
- Mastra: `http://localhost:4111`
|
|
89
|
+
|
|
90
|
+
Override with `KRONOS_WORKER_URL` and `KRONOS_MASTRA_URL` in your app's `.env` if your local ports differ. For the frontend (KronosProvider), use `NEXT_PUBLIC_KRONOS_WORKER_URL` (kronos-nextjs already defaults to localhost).
|
|
91
|
+
|
|
84
92
|
## API Overview
|
|
85
93
|
|
|
86
94
|
### Ingest (Worker)
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { K as KronosClientConfig, I as IngestResponse, a as IngestStatusResponse, C as CreateMCPServerResponse, L as ListMCPServersResponse, G as GetMCPServerResponse, b as ConnectMCPServerResponse, R as RotateMCPServerTokenResponse, M as MemoryStatsResponse, S as ScratchsheetResponse, c as ListScopesResponse, d as GetScopeResponse, e as ScopeSpec, f as CreateScopeResponse, U as UpdateScopeResponse, g as ListTriggersResponse, h as CreateTriggerRequest, i as CreateTriggerResponse, T as TriggerRecord, j as UpdateTriggerRequest, k as UpdateTriggerResponse, D as DeleteTriggerResponse, l as CreateFrontendTokenResponse, m as SkillManageParams, n as SkillManageResponse, o as ContextGraphSummaryResponse, p as ContextGraphReadResponse } from './types-
|
|
2
|
-
export { x as ConnectMCPServerRequest, Y as ContextGraphProcedureSummary, F as CreateFrontendTokenRequest, t as CreateMCPServerRequest, B as CreateScopeRequest, r as IngestMemoryDisposition, s as IngestRequest, q as IngestStatus, w as MCPServerDetails, u as MCPServerStatus, v as MCPServerToolCapabilities, O as OnTriggered, y as RotateMCPServerTokenRequest, A as ScopeDetail, z as ScopeSummary, N as SkillFileContentMode, P as SkillFileInput, Q as SkillFileRecord, H as SkillFileType, W as SkillMetadataRecord, J as SkillReadMode, X as SkillSummaryRecord, V as SkillTreeNode, E as TriggerType } from './types-
|
|
1
|
+
import { K as KronosClientConfig, I as IngestResponse, a as IngestStatusResponse, C as CreateMCPServerResponse, L as ListMCPServersResponse, G as GetMCPServerResponse, b as ConnectMCPServerResponse, R as RotateMCPServerTokenResponse, M as MemoryStatsResponse, S as ScratchsheetResponse, c as ListScopesResponse, d as GetScopeResponse, e as ScopeSpec, f as CreateScopeResponse, U as UpdateScopeResponse, g as ListTriggersResponse, h as CreateTriggerRequest, i as CreateTriggerResponse, T as TriggerRecord, j as UpdateTriggerRequest, k as UpdateTriggerResponse, D as DeleteTriggerResponse, l as CreateFrontendTokenResponse, m as SkillManageParams, n as SkillManageResponse, o as ContextGraphSummaryResponse, p as ContextGraphReadResponse } from './types-Cn8Lsqkz.mjs';
|
|
2
|
+
export { x as ConnectMCPServerRequest, Y as ContextGraphProcedureSummary, F as CreateFrontendTokenRequest, t as CreateMCPServerRequest, B as CreateScopeRequest, r as IngestMemoryDisposition, s as IngestRequest, q as IngestStatus, w as MCPServerDetails, u as MCPServerStatus, v as MCPServerToolCapabilities, O as OnTriggered, y as RotateMCPServerTokenRequest, A as ScopeDetail, z as ScopeSummary, N as SkillFileContentMode, P as SkillFileInput, Q as SkillFileRecord, H as SkillFileType, W as SkillMetadataRecord, J as SkillReadMode, X as SkillSummaryRecord, V as SkillTreeNode, E as TriggerType } from './types-Cn8Lsqkz.mjs';
|
|
3
3
|
|
|
4
4
|
declare class KronosClient {
|
|
5
5
|
private readonly workerUrl;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { K as KronosClientConfig, I as IngestResponse, a as IngestStatusResponse, C as CreateMCPServerResponse, L as ListMCPServersResponse, G as GetMCPServerResponse, b as ConnectMCPServerResponse, R as RotateMCPServerTokenResponse, M as MemoryStatsResponse, S as ScratchsheetResponse, c as ListScopesResponse, d as GetScopeResponse, e as ScopeSpec, f as CreateScopeResponse, U as UpdateScopeResponse, g as ListTriggersResponse, h as CreateTriggerRequest, i as CreateTriggerResponse, T as TriggerRecord, j as UpdateTriggerRequest, k as UpdateTriggerResponse, D as DeleteTriggerResponse, l as CreateFrontendTokenResponse, m as SkillManageParams, n as SkillManageResponse, o as ContextGraphSummaryResponse, p as ContextGraphReadResponse } from './types-
|
|
2
|
-
export { x as ConnectMCPServerRequest, Y as ContextGraphProcedureSummary, F as CreateFrontendTokenRequest, t as CreateMCPServerRequest, B as CreateScopeRequest, r as IngestMemoryDisposition, s as IngestRequest, q as IngestStatus, w as MCPServerDetails, u as MCPServerStatus, v as MCPServerToolCapabilities, O as OnTriggered, y as RotateMCPServerTokenRequest, A as ScopeDetail, z as ScopeSummary, N as SkillFileContentMode, P as SkillFileInput, Q as SkillFileRecord, H as SkillFileType, W as SkillMetadataRecord, J as SkillReadMode, X as SkillSummaryRecord, V as SkillTreeNode, E as TriggerType } from './types-
|
|
1
|
+
import { K as KronosClientConfig, I as IngestResponse, a as IngestStatusResponse, C as CreateMCPServerResponse, L as ListMCPServersResponse, G as GetMCPServerResponse, b as ConnectMCPServerResponse, R as RotateMCPServerTokenResponse, M as MemoryStatsResponse, S as ScratchsheetResponse, c as ListScopesResponse, d as GetScopeResponse, e as ScopeSpec, f as CreateScopeResponse, U as UpdateScopeResponse, g as ListTriggersResponse, h as CreateTriggerRequest, i as CreateTriggerResponse, T as TriggerRecord, j as UpdateTriggerRequest, k as UpdateTriggerResponse, D as DeleteTriggerResponse, l as CreateFrontendTokenResponse, m as SkillManageParams, n as SkillManageResponse, o as ContextGraphSummaryResponse, p as ContextGraphReadResponse } from './types-Cn8Lsqkz.js';
|
|
2
|
+
export { x as ConnectMCPServerRequest, Y as ContextGraphProcedureSummary, F as CreateFrontendTokenRequest, t as CreateMCPServerRequest, B as CreateScopeRequest, r as IngestMemoryDisposition, s as IngestRequest, q as IngestStatus, w as MCPServerDetails, u as MCPServerStatus, v as MCPServerToolCapabilities, O as OnTriggered, y as RotateMCPServerTokenRequest, A as ScopeDetail, z as ScopeSummary, N as SkillFileContentMode, P as SkillFileInput, Q as SkillFileRecord, H as SkillFileType, W as SkillMetadataRecord, J as SkillReadMode, X as SkillSummaryRecord, V as SkillTreeNode, E as TriggerType } from './types-Cn8Lsqkz.js';
|
|
3
3
|
|
|
4
4
|
declare class KronosClient {
|
|
5
5
|
private readonly workerUrl;
|
package/dist/index.js
CHANGED
|
@@ -88,9 +88,17 @@ function generateIdempotencyKey() {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
// src/client.ts
|
|
91
|
-
var
|
|
92
|
-
var
|
|
91
|
+
var PRODUCTION_WORKER_URL = "https://api.kronos.ai";
|
|
92
|
+
var PRODUCTION_MASTRA_URL = "https://mastra.kronos.ai";
|
|
93
|
+
var DEV_WORKER_URL = "http://localhost:8787";
|
|
94
|
+
var DEV_MASTRA_URL = "http://localhost:4111";
|
|
93
95
|
var INTERNAL_CONTEXT_GRAPH_SKILL_NAME = "__internal_context_graph__";
|
|
96
|
+
function defaultWorkerUrl() {
|
|
97
|
+
return process.env.NODE_ENV === "production" ? PRODUCTION_WORKER_URL : DEV_WORKER_URL;
|
|
98
|
+
}
|
|
99
|
+
function defaultMastraUrl() {
|
|
100
|
+
return process.env.NODE_ENV === "production" ? PRODUCTION_MASTRA_URL : DEV_MASTRA_URL;
|
|
101
|
+
}
|
|
94
102
|
var KronosClient = class {
|
|
95
103
|
constructor(config) {
|
|
96
104
|
if (!config.apiKey) {
|
|
@@ -99,8 +107,8 @@ var KronosClient = class {
|
|
|
99
107
|
if (!config.appId) {
|
|
100
108
|
throw new Error("KronosClient: appId is required in constructor");
|
|
101
109
|
}
|
|
102
|
-
this.workerUrl =
|
|
103
|
-
this.mastraUrl =
|
|
110
|
+
this.workerUrl = (config.workerUrl ?? process.env.KRONOS_WORKER_URL ?? defaultWorkerUrl()).replace(/\/$/, "");
|
|
111
|
+
this.mastraUrl = (config.mastraUrl ?? process.env.KRONOS_MASTRA_URL ?? defaultMastraUrl()).replace(/\/$/, "");
|
|
104
112
|
this.apiKey = config.apiKey;
|
|
105
113
|
this.appId = config.appId;
|
|
106
114
|
console.log("[KronosClient] \u2705 KronosClient initialized:", {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/utils.ts","../src/client.ts","../src/webhook-verification.ts"],"sourcesContent":["export { KronosClient } from './client';\nexport { generateIdempotencyKey } from './utils';\nexport { verifyWebhookSecret } from './webhook-verification';\nexport {\n KronosError,\n KronosBadRequestError,\n KronosUnauthorizedError,\n KronosForbiddenError,\n KronosNotFoundError,\n KronosServerError,\n} from './errors';\n\nexport type {\n KronosClientConfig,\n IngestStatus,\n IngestMemoryDisposition,\n IngestRequest,\n IngestResponse,\n IngestStatusResponse,\n CreateMCPServerRequest,\n CreateMCPServerResponse,\n MCPServerStatus,\n MCPServerToolCapabilities,\n MCPServerDetails,\n ListMCPServersResponse,\n GetMCPServerResponse,\n ConnectMCPServerRequest,\n ConnectMCPServerResponse,\n RotateMCPServerTokenRequest,\n RotateMCPServerTokenResponse,\n MemoryStatsResponse,\n ScratchsheetResponse,\n ScopeSummary,\n ScopeDetail,\n ListScopesResponse,\n GetScopeResponse,\n ScopeSpec,\n CreateScopeRequest,\n CreateScopeResponse,\n TriggerType,\n OnTriggered,\n TriggerRecord,\n CreateTriggerRequest,\n CreateTriggerResponse,\n ListTriggersResponse,\n UpdateTriggerRequest,\n UpdateTriggerResponse,\n DeleteTriggerResponse,\n CreateFrontendTokenRequest,\n CreateFrontendTokenResponse,\n SkillFileType,\n SkillReadMode,\n SkillFileContentMode,\n SkillFileInput,\n SkillFileRecord,\n SkillTreeNode,\n SkillMetadataRecord,\n SkillSummaryRecord,\n SkillManageParams,\n SkillManageResponse,\n ContextGraphProcedureSummary,\n ContextGraphSummaryResponse,\n ContextGraphReadResponse,\n} from './types';\n","/**\n * Base error for Kronos API failures\n */\nexport class KronosError extends Error {\n constructor(\n message: string,\n public readonly status?: number,\n public readonly code?: string,\n public readonly body?: unknown\n ) {\n super(message);\n this.name = 'KronosError';\n Object.setPrototypeOf(this, KronosError.prototype);\n }\n}\n\n/**\n * 400 Bad Request - invalid or missing parameters\n */\nexport class KronosBadRequestError extends KronosError {\n constructor(message: string, body?: unknown) {\n super(message, 400, 'bad_request', body);\n this.name = 'KronosBadRequestError';\n Object.setPrototypeOf(this, KronosBadRequestError.prototype);\n }\n}\n\n/**\n * 401 Unauthorized - invalid or missing API key\n */\nexport class KronosUnauthorizedError extends KronosError {\n constructor(message: string, body?: unknown) {\n super(message, 401, 'unauthorized', body);\n this.name = 'KronosUnauthorizedError';\n Object.setPrototypeOf(this, KronosUnauthorizedError.prototype);\n }\n}\n\n/**\n * 403 Forbidden - valid auth but insufficient permissions\n */\nexport class KronosForbiddenError extends KronosError {\n constructor(message: string, body?: unknown) {\n super(message, 403, 'forbidden', body);\n this.name = 'KronosForbiddenError';\n Object.setPrototypeOf(this, KronosForbiddenError.prototype);\n }\n}\n\n/**\n * 404 Not Found - resource does not exist\n */\nexport class KronosNotFoundError extends KronosError {\n constructor(message: string, body?: unknown) {\n super(message, 404, 'not_found', body);\n this.name = 'KronosNotFoundError';\n Object.setPrototypeOf(this, KronosNotFoundError.prototype);\n }\n}\n\n/**\n * 5xx or network/unknown errors\n */\nexport class KronosServerError extends KronosError {\n constructor(message: string, status?: number, body?: unknown) {\n super(message, status, 'server_error', body);\n this.name = 'KronosServerError';\n Object.setPrototypeOf(this, KronosServerError.prototype);\n }\n}\n","/**\n * Generate an idempotency key for ingest requests.\n * Uses crypto.randomUUID() when available; falls back to a timestamp-based value.\n * Callers can pass their own key via the ingest options to achieve true idempotency.\n */\nexport function generateIdempotencyKey(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return `idem_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;\n}\n","import type {\n KronosClientConfig,\n IngestRequest,\n IngestResponse,\n IngestStatusResponse,\n CreateMCPServerRequest,\n CreateMCPServerResponse,\n UpdateMCPServerRequest,\n ListMCPServersResponse,\n GetMCPServerResponse,\n ConnectMCPServerRequest,\n ConnectMCPServerResponse,\n RotateMCPServerTokenResponse,\n MemoryStatsResponse,\n ScratchsheetResponse,\n ListScopesResponse,\n GetScopeResponse,\n CreateScopeRequest,\n CreateScopeResponse,\n UpdateScopeResponse,\n CreateTriggerRequest,\n CreateTriggerResponse,\n CreateFrontendTokenResponse,\n ListTriggersResponse,\n ScopeSpec,\n UpdateTriggerRequest,\n UpdateTriggerResponse,\n DeleteTriggerResponse,\n TriggerRecord,\n SkillManageParams,\n SkillManageResponse,\n ContextGraphSummaryResponse,\n ContextGraphReadResponse,\n ContextGraphProcedureSummary,\n} from './types';\nimport {\n KronosError,\n KronosBadRequestError,\n KronosUnauthorizedError,\n KronosForbiddenError,\n KronosNotFoundError,\n KronosServerError,\n} from './errors';\nimport { generateIdempotencyKey } from './utils';\n\n// Service URLs are hardcoded in the library - users cannot configure these\n// These are YOUR backend services that power the library\n// These are replaced at BUILD TIME by tsup.config.ts reading from .env file\n// Defaults shown below - override via .env file in kronos-lib directory\nconst WORKER_URL = process.env.KRONOS_WORKER_URL || 'https://api.kronos.ai';\nconst MASTRA_URL = process.env.KRONOS_MASTRA_URL || 'https://mastra.kronos.ai';\nconst INTERNAL_CONTEXT_GRAPH_SKILL_NAME = '__internal_context_graph__';\n\nexport class KronosClient {\n private readonly workerUrl: string;\n private readonly mastraUrl: string;\n private readonly apiKey: string;\n private readonly appId: string;\n\n constructor(config: KronosClientConfig) {\n // Validate required constructor parameters\n if (!config.apiKey) {\n throw new Error('KronosClient: apiKey is required in constructor');\n }\n \n if (!config.appId) {\n throw new Error('KronosClient: appId is required in constructor');\n }\n \n // Service URLs are hardcoded - users cannot change these\n // They are YOUR backend services, set at library build time\n this.workerUrl = WORKER_URL.replace(/\\/$/, '');\n this.mastraUrl = MASTRA_URL.replace(/\\/$/, '');\n this.apiKey = config.apiKey;\n this.appId = config.appId;\n \n console.log('[KronosClient] ✅ KronosClient initialized:', {\n appId: this.appId,\n workerUrl: this.workerUrl,\n mastraUrl: this.mastraUrl,\n hasApiKey: !!this.apiKey,\n });\n \n // Perform async health check (fire and forget)\n this.healthCheck().catch(() => {\n // Health check failed, but don't block initialization\n });\n }\n \n /**\n * Perform a health check to verify the client can connect to the Kronos worker\n * This is called automatically during initialization\n */\n private async healthCheck(): Promise<void> {\n try {\n const response = await fetch(`${this.workerUrl}/health`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n \n if (response.ok) {\n const data = await response.json();\n if (data.status === 'ok') {\n console.log('[KronosClient] ✅ Health check passed - Client is connected and working');\n } else {\n console.warn('[KronosClient] ⚠️ Health check returned unexpected status:', data);\n }\n } else {\n console.warn(`[KronosClient] ⚠️ Health check failed with status ${response.status}. Client may not be working correctly.`);\n }\n } catch (error: any) {\n console.warn('[KronosClient] ⚠️ Health check failed - Unable to connect to Kronos worker:', error.message);\n console.warn('[KronosClient] Please verify that:');\n console.warn('[KronosClient] 1. The worker URL is correct:', this.workerUrl);\n console.warn('[KronosClient] 2. The worker is running and accessible');\n console.warn('[KronosClient] 3. Network connectivity is available');\n }\n }\n\n // ---------------------------------------------------------------------------\n // Worker request helper (uses Bearer auth)\n // ---------------------------------------------------------------------------\n private async workerFetch<T>(\n path: string,\n options: { method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; json?: object; idempotencyKey?: string } = {}\n ): Promise<T> {\n const { json, idempotencyKey, method } = options;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n };\n if (idempotencyKey) headers['Idempotency-Key'] = idempotencyKey;\n const res = await fetch(`${this.workerUrl}${path}`, {\n method: method ?? (json ? 'POST' : 'GET'),\n headers,\n body: json ? JSON.stringify(json) : undefined,\n });\n return this.handleResponse<T>(res);\n }\n\n // ---------------------------------------------------------------------------\n // Mastra request helper (no Bearer auth per current API)\n // ---------------------------------------------------------------------------\n private async mastraFetch<T>(\n path: string,\n options: { method?: 'GET' | 'POST'; json?: object } = {}\n ): Promise<T> {\n const { json, method } = options;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n const res = await fetch(`${this.mastraUrl}${path}`, {\n method: method ?? (json ? 'POST' : 'GET'),\n headers,\n body: json ? JSON.stringify(json) : undefined,\n });\n return this.handleResponse<T>(res);\n }\n\n private async handleResponse<T>(res: Response): Promise<T> {\n const text = await res.text();\n let body: unknown = null;\n try {\n body = text ? JSON.parse(text) : null;\n } catch {\n body = text;\n }\n\n if (!res.ok) {\n const errBody = body as { error?: string } | null;\n const message = (errBody && typeof errBody.error === 'string')\n ? errBody.error\n : `Request failed with status ${res.status}`;\n\n switch (res.status) {\n case 400:\n throw new KronosBadRequestError(message, body);\n case 401:\n throw new KronosUnauthorizedError(message, body);\n case 403:\n throw new KronosForbiddenError(message, body);\n case 404:\n throw new KronosNotFoundError(message, body);\n default:\n if (res.status >= 500) {\n throw new KronosServerError(message, res.status, body);\n }\n throw new KronosError(message, res.status, undefined, body);\n }\n }\n\n return (body ?? null) as T;\n }\n\n // ---------------------------------------------------------------------------\n // Ingest API\n // ---------------------------------------------------------------------------\n\n /**\n * Submit a document for ingestion.\n * @param params - source_type, content, optional metadata, addToMemory, and idempotencyKey\n * @returns ingest_id\n */\n async ingest(params: {\n tenant_user_id: string;\n source_type: string;\n priority?: 'low' | 'medium' | 'high';\n addToMemory?: boolean;\n content: { type: 'text'; text: string };\n metadata?: Record<string, unknown>;\n idempotencyKey?: string;\n }): Promise<IngestResponse> {\n const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();\n const body: IngestRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n source_type: params.source_type,\n priority: params.priority,\n addToMemory: params.addToMemory,\n content: params.content,\n metadata: params.metadata,\n };\n return this.workerFetch<IngestResponse>('/v1/ingest', {\n method: 'POST',\n json: body,\n idempotencyKey,\n });\n }\n\n /**\n * Get the status of an ingest.\n */\n async getIngestStatus(ingestId: string): Promise<IngestStatusResponse> {\n return this.workerFetch<IngestStatusResponse>(`/v1/ingest/${ingestId}`, {\n method: 'GET',\n });\n }\n\n // ---------------------------------------------------------------------------\n // MCP Server API\n // ---------------------------------------------------------------------------\n\n /**\n * Create an MCP server scoped to the given scopes.\n * Use connectMCPServer() to get a short-lived access token for MCP auth.\n */\n async createMCPServer(params: {\n tenant_user_id: string;\n name: string;\n /** Omit or pass [] for all-memory access. */\n scope_ids?: string[] | null;\n description?: string;\n options?: {\n /** Expose `search_skills` and `read_skill`. Defaults to true. */\n exposeSkillsTool?: boolean;\n /** Expose the read-only `context_graph` tool. Defaults to false. */\n exposeContextGraphTool?: boolean;\n };\n }): Promise<CreateMCPServerResponse> {\n const body: CreateMCPServerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n scope_ids: params.scope_ids ?? [],\n name: params.name,\n description: params.description,\n options: {\n exposeSkillsTool: params.options?.exposeSkillsTool ?? true,\n exposeContextGraphTool: params.options?.exposeContextGraphTool ?? false,\n },\n };\n const res = await this.workerFetch<{\n mcp_server_id: string;\n url: string;\n status: 'active' | 'disabled';\n name: string;\n description: string | null;\n scope_ids: string[];\n tool_capabilities: { skills: boolean; context_graph: boolean };\n }>('/v1/mcp-servers', { method: 'POST', json: body });\n return {\n mcp_server_id: res.mcp_server_id,\n url: res.url.startsWith('http') ? res.url : `${this.workerUrl}${res.url}`,\n status: res.status,\n name: res.name,\n description: res.description,\n scope_ids: res.scope_ids,\n tool_capabilities: res.tool_capabilities ?? {\n skills: true,\n context_graph: false,\n },\n };\n }\n\n /**\n * List MCP servers for a user. Returns metadata only (no token).\n */\n async listMCPServers(params: {\n tenant_user_id: string;\n }): Promise<ListMCPServersResponse> {\n const path = `/v1/mcp-servers?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<ListMCPServersResponse>(path, { method: 'GET' });\n }\n\n /**\n * Get MCP server details for a user by server ID. Returns metadata only (no token).\n */\n async getMCPServer(params: {\n tenant_user_id: string;\n serverId: string;\n }): Promise<GetMCPServerResponse> {\n const path = `/v1/mcp-servers/${params.serverId}?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<GetMCPServerResponse>(path, { method: 'GET' });\n }\n\n async updateMCPServer(params: {\n tenant_user_id: string;\n serverId: string;\n tool_capabilities: {\n skills: boolean;\n context_graph: boolean;\n };\n }): Promise<GetMCPServerResponse> {\n const body: UpdateMCPServerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n tool_capabilities: params.tool_capabilities,\n };\n\n return this.workerFetch<GetMCPServerResponse>(`/v1/mcp-servers/${params.serverId}`, {\n method: 'PUT',\n json: body,\n });\n }\n\n /**\n * Connect to an MCP server by ID and receive a short-lived access token.\n * Use the returned access_token as Bearer token when calling the MCP endpoint.\n */\n async connectMCPServer(params: {\n tenant_user_id: string;\n serverId: string;\n }): Promise<ConnectMCPServerResponse> {\n const body: ConnectMCPServerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n };\n const res = await this.workerFetch<ConnectMCPServerResponse>(\n `/v1/mcp-servers/${params.serverId}/connect`,\n { method: 'POST', json: body }\n );\n return {\n ...res,\n url: res.url.startsWith('http') ? res.url : `${this.workerUrl}${res.url}`,\n };\n }\n\n /**\n * Rotate the token for an MCP server. The new token is returned only on rotate.\n */\n async rotateMCPServerToken(params: {\n tenant_user_id: string;\n serverId: string;\n }): Promise<RotateMCPServerTokenResponse> {\n return this.workerFetch<RotateMCPServerTokenResponse>(\n `/v1/mcp-servers/${params.serverId}/rotate-token`,\n {\n method: 'POST',\n json: { app_id: this.appId, tenant_user_id: params.tenant_user_id },\n }\n );\n }\n\n /**\n * Get memory stats for a user (total claim count across entire memory graph).\n * Worker caches the response for 5 minutes per user.\n */\n async getMemoryStats(params: {\n tenant_user_id: string;\n }): Promise<MemoryStatsResponse> {\n const path = `/v1/memory-stats?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<MemoryStatsResponse>(path, { method: 'GET' });\n }\n\n /**\n * Read the current scratchsheet document for a user.\n */\n async getScratchsheet(params: {\n tenant_user_id: string;\n }): Promise<ScratchsheetResponse> {\n const path = `/v1/scratchsheet?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<ScratchsheetResponse>(path, { method: 'GET' });\n }\n\n /**\n * List scopes for a user. Returns full scope details. Cached 5 min per user.\n */\n async listScopes(params: {\n tenant_user_id: string;\n }): Promise<ListScopesResponse> {\n const path = `/v1/scopes?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<ListScopesResponse>(path, { method: 'GET' });\n }\n\n /**\n * Get a single scope by ID. Returns full scope details.\n */\n async getScope(params: {\n tenant_user_id: string;\n scope_id: string;\n }): Promise<GetScopeResponse> {\n const path = `/v1/scopes/${encodeURIComponent(params.scope_id)}?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<GetScopeResponse>(path, { method: 'GET' });\n }\n\n // ---------------------------------------------------------------------------\n // Scope API (Mastra)\n // ---------------------------------------------------------------------------\n\n /**\n * Create a scope. A backfill job runs asynchronously to populate it.\n * If spec.allowed_source_types is omitted, it defaults to ['all'].\n * Uses the Worker so the scopes list cache is invalidated after create.\n */\n async createScope(params: {\n tenant_user_id: string;\n spec: ScopeSpec;\n created_by: string;\n description?: string;\n }): Promise<CreateScopeResponse> {\n const spec = {\n ...params.spec,\n allowed_source_types: params.spec.allowed_source_types ?? ['all'],\n };\n const body: CreateScopeRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n spec,\n created_by: params.created_by,\n description: params.description,\n };\n return this.workerFetch<CreateScopeResponse>('/v1/scopes', {\n method: 'POST',\n json: body,\n });\n }\n\n /**\n * Update a scope. Only provided fields are updated.\n * If include_query, exclude_query, match_mode, time_range, or allowed_source_types change,\n * a backfill job runs to recompute membership (response includes backfill_job_id).\n * Otherwise only DB and Neo4j metadata are updated.\n */\n async updateScope(params: {\n tenant_user_id: string;\n scope_id: string;\n name?: string;\n description?: string | null;\n include_query?: string;\n exclude_query?: string | null;\n match_mode?: 'strict' | 'broad';\n time_range?: { start?: string; end?: string };\n allowed_source_types?: string[] | 'all';\n }): Promise<UpdateScopeResponse> {\n const { scope_id, tenant_user_id, ...patch } = params;\n const body: Record<string, unknown> = {};\n if (patch.name !== undefined) body.name = patch.name;\n if (patch.description !== undefined) body.description = patch.description;\n if (patch.include_query !== undefined) body.include_query = patch.include_query;\n if (patch.exclude_query !== undefined) body.exclude_query = patch.exclude_query;\n if (patch.match_mode !== undefined) body.match_mode = patch.match_mode;\n if (patch.time_range !== undefined) body.time_range = patch.time_range;\n if (patch.allowed_source_types !== undefined) body.allowed_source_types = patch.allowed_source_types;\n\n const path = `/v1/scopes/${encodeURIComponent(scope_id)}?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id,\n }).toString()}`;\n return this.workerFetch<UpdateScopeResponse>(path, {\n method: 'PATCH',\n json: body,\n });\n }\n\n /**\n * Soft-delete a scope. Invalidates the scopes list cache for that user.\n */\n async deleteScope(params: {\n tenant_user_id: string;\n scope_id: string;\n }): Promise<{ deleted: boolean }> {\n const path = `/v1/scopes/${encodeURIComponent(params.scope_id)}?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<{ deleted: boolean }>(path, { method: 'DELETE' });\n }\n\n // ---------------------------------------------------------------------------\n // Webhook Verification API (Worker)\n // ---------------------------------------------------------------------------\n\n /**\n * Verify a webhook secret for a trigger.\n * This method calls the Kronos worker API to verify the webhook secret.\n * \n * @param params - app_id, tenant_user_id, trigger_id and received_secret to verify\n * @returns true if secret is valid, false otherwise\n */\n async verifyWebhookSecret(params: {\n tenant_user_id: string;\n trigger_id: string;\n received_secret: string;\n }): Promise<boolean> {\n const body = {\n trigger_id: params.trigger_id,\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n received_secret: params.received_secret,\n };\n \n try {\n const response = await this.workerFetch<{ valid: boolean }>('/v1/triggers/verify-webhook', {\n method: 'POST',\n json: body,\n });\n \n return response.valid;\n } catch (error: any) {\n // If verification fails (e.g., trigger not found), return false\n console.error('[KronosClient] Webhook verification error:', error);\n return false;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Trigger Management API (Worker)\n // ---------------------------------------------------------------------------\n\n /**\n * List triggers for a tenant user.\n */\n async listTriggers(params: {\n tenant_user_id: string;\n }): Promise<ListTriggersResponse> {\n const query = new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n });\n \n return this.workerFetch<ListTriggersResponse>(`/v1/triggers?${query.toString()}`, {\n method: 'GET',\n });\n }\n\n /**\n * Create a trigger.\n * Supports NL creation (trigger_description) or manual creation (trigger_type/trigger_spec).\n *\n * @returns CreateTriggerResponse (accepted for NL, trigger_id for manual)\n */\n async createTrigger(params: {\n tenant_user_id: string;\n webhook_url: string;\n webhook_secret: string;\n title?: string | null;\n action_description?: string;\n skill_id?: string;\n skill_version_id?: string;\n trigger_description?: string;\n trigger_type?: CreateTriggerRequest['trigger_type'];\n trigger_spec?: CreateTriggerRequest['trigger_spec'];\n next_run_at?: string;\n on_triggered?: CreateTriggerRequest['on_triggered'];\n metadata?: Record<string, unknown>;\n idempotencyKey?: string;\n }): Promise<CreateTriggerResponse> {\n const body: CreateTriggerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n webhook_url: params.webhook_url,\n webhook_secret: params.webhook_secret,\n title: params.title,\n action_description: params.action_description,\n skill_id: params.skill_id,\n skill_version_id: params.skill_version_id,\n trigger_description: params.trigger_description,\n trigger_type: params.trigger_type,\n trigger_spec: params.trigger_spec,\n next_run_at: params.next_run_at,\n on_triggered: params.on_triggered,\n metadata: params.metadata,\n };\n\n return this.workerFetch<CreateTriggerResponse>('/v1/triggers', {\n method: 'POST',\n json: body,\n idempotencyKey: params.idempotencyKey,\n });\n }\n\n /**\n * Get details for a specific trigger.\n * Uses listTriggers and filters by trigger_id.\n */\n async getTriggerDetails(params: {\n tenant_user_id: string;\n trigger_id: string;\n }): Promise<TriggerRecord> {\n const response = await this.listTriggers({ tenant_user_id: params.tenant_user_id });\n const trigger = response.triggers.find((t) => t.trigger_id === params.trigger_id);\n\n if (!trigger) {\n throw new KronosNotFoundError(`Trigger not found: ${params.trigger_id}`);\n }\n\n return trigger;\n }\n\n /**\n * Update a trigger.\n * Updates the webhook_url, action_description, status, or metadata of an existing trigger.\n * \n * @param params - app_id, tenant_user_id, trigger_id and fields to update\n * @returns UpdateTriggerResponse with success status\n */\n async updateTrigger(params: {\n tenant_user_id: string;\n trigger_id: string;\n webhook_url?: string;\n title?: string | null;\n trigger_type?: UpdateTriggerRequest['trigger_type'];\n trigger_spec?: UpdateTriggerRequest['trigger_spec'];\n next_run_at?: UpdateTriggerRequest['next_run_at'];\n action_description?: string;\n skill_id?: string | null;\n skill_version_id?: string | null;\n on_triggered?: UpdateTriggerRequest['on_triggered'];\n status?: string;\n metadata?: Record<string, unknown>;\n }): Promise<UpdateTriggerResponse> {\n const body: UpdateTriggerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n webhook_url: params.webhook_url,\n title: params.title,\n trigger_type: params.trigger_type,\n trigger_spec: params.trigger_spec,\n next_run_at: params.next_run_at,\n action_description: params.action_description,\n skill_id: params.skill_id,\n skill_version_id: params.skill_version_id,\n on_triggered: params.on_triggered,\n status: params.status,\n metadata: params.metadata,\n };\n \n return this.workerFetch<UpdateTriggerResponse>(`/v1/triggers/${params.trigger_id}`, {\n method: 'PUT',\n json: body,\n });\n }\n\n /**\n * Delete a trigger.\n */\n async deleteTrigger(params: {\n tenant_user_id: string;\n trigger_id: string;\n }): Promise<DeleteTriggerResponse> {\n const query = new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n });\n\n return this.workerFetch<DeleteTriggerResponse>(\n `/v1/triggers/${encodeURIComponent(params.trigger_id)}?${query.toString()}`,\n { method: 'DELETE' }\n );\n }\n\n // ---------------------------------------------------------------------------\n // Frontend Tokens (Server-side only)\n // ---------------------------------------------------------------------------\n\n /**\n * Issue a short-lived, user-scoped frontend token.\n * The browser can use this token directly against the Kronos worker for\n * allowed operations (e.g. trigger CRUD) without needing the app API key.\n *\n * This method must be called from a trusted server environment.\n */\n async createFrontendToken(params: {\n tenantUserId: string;\n ttlSeconds?: number;\n ops?: string[];\n }): Promise<CreateFrontendTokenResponse> {\n const res = await this.workerFetch<{ token: string; expires_at: string }>(\n '/v1/frontend-tokens',\n {\n method: 'POST',\n json: {\n app_id: this.appId,\n tenant_user_id: params.tenantUserId,\n ttl_seconds: params.ttlSeconds,\n ops: params.ops,\n },\n },\n );\n return { token: res.token, expiresAt: res.expires_at };\n }\n\n // ---------------------------------------------------------------------------\n // Skills API (Worker)\n // ---------------------------------------------------------------------------\n\n /**\n * Canonical skills API with operation-based contract.\n */\n async manageSkill(params: SkillManageParams): Promise<SkillManageResponse> {\n const idempotencyKey =\n params.operation === 'create' || params.operation === 'update'\n ? params.idempotencyKey\n : undefined;\n\n return this.workerFetch<SkillManageResponse>('/v1/skills/manage', {\n method: 'POST',\n json: {\n ...params,\n app_id: this.appId,\n },\n idempotencyKey,\n });\n }\n\n private async resolveContextGraphSkillId(\n tenantUserId: string\n ): Promise<string | null> {\n const listed = await this.manageSkill({\n operation: 'list',\n tenant_user_id: tenantUserId,\n include_internal: true,\n });\n\n const match = (listed.skills ?? []).find(\n (skill) => skill.name === INTERNAL_CONTEXT_GRAPH_SKILL_NAME\n );\n\n return match?.skill_id ?? null;\n }\n\n private parseContextGraphProcedures(\n files: Array<{ path: string; content?: string }>\n ): ContextGraphProcedureSummary[] {\n return files\n .filter((file) => file.path.startsWith('procedures/') && file.path.endsWith('.md'))\n .map((file) => {\n const content = file.content ?? '';\n const normalized = content.replace(/\\r\\n/g, '\\n');\n\n if (normalized.startsWith('---\\n')) {\n const endIndex = normalized.indexOf('\\n---\\n', 4);\n if (endIndex !== -1) {\n const frontmatter = normalized.slice(4, endIndex);\n const metadata: Record<string, string> = {};\n for (const line of frontmatter.split('\\n')) {\n const separatorIndex = line.indexOf(':');\n if (separatorIndex === -1) continue;\n const key = line.slice(0, separatorIndex).trim();\n const value = line.slice(separatorIndex + 1).trim();\n if (key && value) {\n metadata[key] = value;\n }\n }\n\n return {\n title: metadata.title || (file.path.split('/').pop() ?? file.path),\n description: metadata.description || '',\n path: file.path,\n };\n }\n }\n\n const lines = content.split(/\\r?\\n/);\n const titleLine = lines.find((line) => line.startsWith('# '));\n const title = titleLine ? titleLine.replace(/^#\\s+/, '').trim() : file.path.split('/').pop() ?? file.path;\n const description =\n lines\n .slice(1)\n .map((line) => line.trim())\n .find((line) => line.length > 0 && !line.startsWith('#')) ?? '';\n\n return {\n title,\n description,\n path: file.path,\n };\n })\n .sort((a, b) => a.path.localeCompare(b.path));\n }\n\n async getContextGraph(params: {\n tenant_user_id: string;\n }): Promise<ContextGraphSummaryResponse> {\n const skillId = await this.resolveContextGraphSkillId(params.tenant_user_id);\n if (!skillId) {\n return {\n skill_id: null,\n procedures: [],\n };\n }\n\n const treeResult = await this.manageSkill({\n operation: 'read',\n tenant_user_id: params.tenant_user_id,\n skill_id: skillId,\n mode: 'tree',\n });\n\n const procedurePaths = (treeResult.tree ?? [])\n .filter((node) => node.kind === 'file' && node.path.startsWith('procedures/') && node.path.endsWith('.md'))\n .map((node) => node.path);\n\n if (procedurePaths.length === 0) {\n return {\n skill_id: skillId,\n procedures: [],\n };\n }\n\n const filesResult = await this.manageSkill({\n operation: 'read',\n tenant_user_id: params.tenant_user_id,\n skill_id: skillId,\n mode: 'files',\n files: procedurePaths,\n fileContent: 'full',\n });\n\n return {\n skill_id: skillId,\n procedures: this.parseContextGraphProcedures(filesResult.files ?? []),\n };\n }\n\n async readContextGraph(params: {\n tenant_user_id: string;\n path?: string;\n }): Promise<ContextGraphReadResponse> {\n const skillId = await this.resolveContextGraphSkillId(params.tenant_user_id);\n const requestedPath = params.path?.trim() || 'SKILL.md';\n\n if (!skillId) {\n return {\n skill_id: null,\n path: requestedPath,\n content: null,\n };\n }\n\n if (requestedPath === 'SKILL.md') {\n const result = await this.manageSkill({\n operation: 'read',\n tenant_user_id: params.tenant_user_id,\n skill_id: skillId,\n mode: 'instructions',\n });\n\n return {\n skill_id: skillId,\n path: 'SKILL.md',\n content: result.instructions ?? null,\n };\n }\n\n const result = await this.manageSkill({\n operation: 'read',\n tenant_user_id: params.tenant_user_id,\n skill_id: skillId,\n mode: 'files',\n files: [requestedPath],\n fileContent: 'full',\n });\n\n const file = (result.files ?? []).find((entry) => entry.path === requestedPath);\n\n return {\n skill_id: skillId,\n path: requestedPath,\n content: file?.content ?? null,\n };\n }\n}\n","/**\n * Webhook verification utilities for Kronos triggers\n * Provides secure constant-time comparison for webhook secrets\n */\n\n/**\n * Verify a webhook secret using constant-time comparison to prevent timing attacks.\n * \n * @param receivedSecret - The secret received in the webhook header\n * @param storedSecret - The secret stored in the database for the trigger\n * @returns true if secrets match, false otherwise\n * \n * @example\n * ```typescript\n * import { verifyWebhookSecret } from '@gdrl/kronos-lib/webhook-verification';\n * \n * const isValid = verifyWebhookSecret(\n * request.headers.get('X-Kronos-Webhook-Secret'),\n * trigger.webhook_secret\n * );\n * \n * if (!isValid) {\n * return new Response('Unauthorized', { status: 401 });\n * }\n * ```\n */\nexport function verifyWebhookSecret(\n receivedSecret: string | null | undefined,\n storedSecret: string | null | undefined\n): boolean {\n // If either is missing, they don't match\n if (!receivedSecret || !storedSecret) {\n return false;\n }\n\n // Constant-time comparison to prevent timing attacks\n if (receivedSecret.length !== storedSecret.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < receivedSecret.length; i++) {\n result |= receivedSecret.charCodeAt(i) ^ storedSecret.charCodeAt(i);\n }\n\n return result === 0;\n}\n"],"mappings":"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","names":["result"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/utils.ts","../src/client.ts","../src/webhook-verification.ts"],"sourcesContent":["export { KronosClient } from './client';\nexport { generateIdempotencyKey } from './utils';\nexport { verifyWebhookSecret } from './webhook-verification';\nexport {\n KronosError,\n KronosBadRequestError,\n KronosUnauthorizedError,\n KronosForbiddenError,\n KronosNotFoundError,\n KronosServerError,\n} from './errors';\n\nexport type {\n KronosClientConfig,\n IngestStatus,\n IngestMemoryDisposition,\n IngestRequest,\n IngestResponse,\n IngestStatusResponse,\n CreateMCPServerRequest,\n CreateMCPServerResponse,\n MCPServerStatus,\n MCPServerToolCapabilities,\n MCPServerDetails,\n ListMCPServersResponse,\n GetMCPServerResponse,\n ConnectMCPServerRequest,\n ConnectMCPServerResponse,\n RotateMCPServerTokenRequest,\n RotateMCPServerTokenResponse,\n MemoryStatsResponse,\n ScratchsheetResponse,\n ScopeSummary,\n ScopeDetail,\n ListScopesResponse,\n GetScopeResponse,\n ScopeSpec,\n CreateScopeRequest,\n CreateScopeResponse,\n TriggerType,\n OnTriggered,\n TriggerRecord,\n CreateTriggerRequest,\n CreateTriggerResponse,\n ListTriggersResponse,\n UpdateTriggerRequest,\n UpdateTriggerResponse,\n DeleteTriggerResponse,\n CreateFrontendTokenRequest,\n CreateFrontendTokenResponse,\n SkillFileType,\n SkillReadMode,\n SkillFileContentMode,\n SkillFileInput,\n SkillFileRecord,\n SkillTreeNode,\n SkillMetadataRecord,\n SkillSummaryRecord,\n SkillManageParams,\n SkillManageResponse,\n ContextGraphProcedureSummary,\n ContextGraphSummaryResponse,\n ContextGraphReadResponse,\n} from './types';\n","/**\n * Base error for Kronos API failures\n */\nexport class KronosError extends Error {\n constructor(\n message: string,\n public readonly status?: number,\n public readonly code?: string,\n public readonly body?: unknown\n ) {\n super(message);\n this.name = 'KronosError';\n Object.setPrototypeOf(this, KronosError.prototype);\n }\n}\n\n/**\n * 400 Bad Request - invalid or missing parameters\n */\nexport class KronosBadRequestError extends KronosError {\n constructor(message: string, body?: unknown) {\n super(message, 400, 'bad_request', body);\n this.name = 'KronosBadRequestError';\n Object.setPrototypeOf(this, KronosBadRequestError.prototype);\n }\n}\n\n/**\n * 401 Unauthorized - invalid or missing API key\n */\nexport class KronosUnauthorizedError extends KronosError {\n constructor(message: string, body?: unknown) {\n super(message, 401, 'unauthorized', body);\n this.name = 'KronosUnauthorizedError';\n Object.setPrototypeOf(this, KronosUnauthorizedError.prototype);\n }\n}\n\n/**\n * 403 Forbidden - valid auth but insufficient permissions\n */\nexport class KronosForbiddenError extends KronosError {\n constructor(message: string, body?: unknown) {\n super(message, 403, 'forbidden', body);\n this.name = 'KronosForbiddenError';\n Object.setPrototypeOf(this, KronosForbiddenError.prototype);\n }\n}\n\n/**\n * 404 Not Found - resource does not exist\n */\nexport class KronosNotFoundError extends KronosError {\n constructor(message: string, body?: unknown) {\n super(message, 404, 'not_found', body);\n this.name = 'KronosNotFoundError';\n Object.setPrototypeOf(this, KronosNotFoundError.prototype);\n }\n}\n\n/**\n * 5xx or network/unknown errors\n */\nexport class KronosServerError extends KronosError {\n constructor(message: string, status?: number, body?: unknown) {\n super(message, status, 'server_error', body);\n this.name = 'KronosServerError';\n Object.setPrototypeOf(this, KronosServerError.prototype);\n }\n}\n","/**\n * Generate an idempotency key for ingest requests.\n * Uses crypto.randomUUID() when available; falls back to a timestamp-based value.\n * Callers can pass their own key via the ingest options to achieve true idempotency.\n */\nexport function generateIdempotencyKey(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return `idem_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;\n}\n","import type {\n KronosClientConfig,\n IngestRequest,\n IngestResponse,\n IngestStatusResponse,\n CreateMCPServerRequest,\n CreateMCPServerResponse,\n UpdateMCPServerRequest,\n ListMCPServersResponse,\n GetMCPServerResponse,\n ConnectMCPServerRequest,\n ConnectMCPServerResponse,\n RotateMCPServerTokenResponse,\n MemoryStatsResponse,\n ScratchsheetResponse,\n ListScopesResponse,\n GetScopeResponse,\n CreateScopeRequest,\n CreateScopeResponse,\n UpdateScopeResponse,\n CreateTriggerRequest,\n CreateTriggerResponse,\n CreateFrontendTokenResponse,\n ListTriggersResponse,\n ScopeSpec,\n UpdateTriggerRequest,\n UpdateTriggerResponse,\n DeleteTriggerResponse,\n TriggerRecord,\n SkillManageParams,\n SkillManageResponse,\n ContextGraphSummaryResponse,\n ContextGraphReadResponse,\n ContextGraphProcedureSummary,\n} from './types';\nimport {\n KronosError,\n KronosBadRequestError,\n KronosUnauthorizedError,\n KronosForbiddenError,\n KronosNotFoundError,\n KronosServerError,\n} from './errors';\nimport { generateIdempotencyKey } from './utils';\n\nconst PRODUCTION_WORKER_URL = 'https://api.kronos.ai';\nconst PRODUCTION_MASTRA_URL = 'https://mastra.kronos.ai';\nconst DEV_WORKER_URL = 'http://localhost:8787';\nconst DEV_MASTRA_URL = 'http://localhost:4111';\nconst INTERNAL_CONTEXT_GRAPH_SKILL_NAME = '__internal_context_graph__';\n\nfunction defaultWorkerUrl(): string {\n return process.env.NODE_ENV === 'production' ? PRODUCTION_WORKER_URL : DEV_WORKER_URL;\n}\nfunction defaultMastraUrl(): string {\n return process.env.NODE_ENV === 'production' ? PRODUCTION_MASTRA_URL : DEV_MASTRA_URL;\n}\n\nexport class KronosClient {\n private readonly workerUrl: string;\n private readonly mastraUrl: string;\n private readonly apiKey: string;\n private readonly appId: string;\n\n constructor(config: KronosClientConfig) {\n if (!config.apiKey) {\n throw new Error('KronosClient: apiKey is required in constructor');\n }\n if (!config.appId) {\n throw new Error('KronosClient: appId is required in constructor');\n }\n this.workerUrl = (config.workerUrl ?? process.env.KRONOS_WORKER_URL ?? defaultWorkerUrl()).replace(/\\/$/, '');\n this.mastraUrl = (config.mastraUrl ?? process.env.KRONOS_MASTRA_URL ?? defaultMastraUrl()).replace(/\\/$/, '');\n this.apiKey = config.apiKey;\n this.appId = config.appId;\n \n console.log('[KronosClient] ✅ KronosClient initialized:', {\n appId: this.appId,\n workerUrl: this.workerUrl,\n mastraUrl: this.mastraUrl,\n hasApiKey: !!this.apiKey,\n });\n \n // Perform async health check (fire and forget)\n this.healthCheck().catch(() => {\n // Health check failed, but don't block initialization\n });\n }\n \n /**\n * Perform a health check to verify the client can connect to the Kronos worker\n * This is called automatically during initialization\n */\n private async healthCheck(): Promise<void> {\n try {\n const response = await fetch(`${this.workerUrl}/health`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n \n if (response.ok) {\n const data = await response.json();\n if (data.status === 'ok') {\n console.log('[KronosClient] ✅ Health check passed - Client is connected and working');\n } else {\n console.warn('[KronosClient] ⚠️ Health check returned unexpected status:', data);\n }\n } else {\n console.warn(`[KronosClient] ⚠️ Health check failed with status ${response.status}. Client may not be working correctly.`);\n }\n } catch (error: any) {\n console.warn('[KronosClient] ⚠️ Health check failed - Unable to connect to Kronos worker:', error.message);\n console.warn('[KronosClient] Please verify that:');\n console.warn('[KronosClient] 1. The worker URL is correct:', this.workerUrl);\n console.warn('[KronosClient] 2. The worker is running and accessible');\n console.warn('[KronosClient] 3. Network connectivity is available');\n }\n }\n\n // ---------------------------------------------------------------------------\n // Worker request helper (uses Bearer auth)\n // ---------------------------------------------------------------------------\n private async workerFetch<T>(\n path: string,\n options: { method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; json?: object; idempotencyKey?: string } = {}\n ): Promise<T> {\n const { json, idempotencyKey, method } = options;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n };\n if (idempotencyKey) headers['Idempotency-Key'] = idempotencyKey;\n const res = await fetch(`${this.workerUrl}${path}`, {\n method: method ?? (json ? 'POST' : 'GET'),\n headers,\n body: json ? JSON.stringify(json) : undefined,\n });\n return this.handleResponse<T>(res);\n }\n\n // ---------------------------------------------------------------------------\n // Mastra request helper (no Bearer auth per current API)\n // ---------------------------------------------------------------------------\n private async mastraFetch<T>(\n path: string,\n options: { method?: 'GET' | 'POST'; json?: object } = {}\n ): Promise<T> {\n const { json, method } = options;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n const res = await fetch(`${this.mastraUrl}${path}`, {\n method: method ?? (json ? 'POST' : 'GET'),\n headers,\n body: json ? JSON.stringify(json) : undefined,\n });\n return this.handleResponse<T>(res);\n }\n\n private async handleResponse<T>(res: Response): Promise<T> {\n const text = await res.text();\n let body: unknown = null;\n try {\n body = text ? JSON.parse(text) : null;\n } catch {\n body = text;\n }\n\n if (!res.ok) {\n const errBody = body as { error?: string } | null;\n const message = (errBody && typeof errBody.error === 'string')\n ? errBody.error\n : `Request failed with status ${res.status}`;\n\n switch (res.status) {\n case 400:\n throw new KronosBadRequestError(message, body);\n case 401:\n throw new KronosUnauthorizedError(message, body);\n case 403:\n throw new KronosForbiddenError(message, body);\n case 404:\n throw new KronosNotFoundError(message, body);\n default:\n if (res.status >= 500) {\n throw new KronosServerError(message, res.status, body);\n }\n throw new KronosError(message, res.status, undefined, body);\n }\n }\n\n return (body ?? null) as T;\n }\n\n // ---------------------------------------------------------------------------\n // Ingest API\n // ---------------------------------------------------------------------------\n\n /**\n * Submit a document for ingestion.\n * @param params - source_type, content, optional metadata, addToMemory, and idempotencyKey\n * @returns ingest_id\n */\n async ingest(params: {\n tenant_user_id: string;\n source_type: string;\n priority?: 'low' | 'medium' | 'high';\n addToMemory?: boolean;\n content: { type: 'text'; text: string };\n metadata?: Record<string, unknown>;\n idempotencyKey?: string;\n }): Promise<IngestResponse> {\n const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();\n const body: IngestRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n source_type: params.source_type,\n priority: params.priority,\n addToMemory: params.addToMemory,\n content: params.content,\n metadata: params.metadata,\n };\n return this.workerFetch<IngestResponse>('/v1/ingest', {\n method: 'POST',\n json: body,\n idempotencyKey,\n });\n }\n\n /**\n * Get the status of an ingest.\n */\n async getIngestStatus(ingestId: string): Promise<IngestStatusResponse> {\n return this.workerFetch<IngestStatusResponse>(`/v1/ingest/${ingestId}`, {\n method: 'GET',\n });\n }\n\n // ---------------------------------------------------------------------------\n // MCP Server API\n // ---------------------------------------------------------------------------\n\n /**\n * Create an MCP server scoped to the given scopes.\n * Use connectMCPServer() to get a short-lived access token for MCP auth.\n */\n async createMCPServer(params: {\n tenant_user_id: string;\n name: string;\n /** Omit or pass [] for all-memory access. */\n scope_ids?: string[] | null;\n description?: string;\n options?: {\n /** Expose `search_skills` and `read_skill`. Defaults to true. */\n exposeSkillsTool?: boolean;\n /** Expose the read-only `context_graph` tool. Defaults to false. */\n exposeContextGraphTool?: boolean;\n };\n }): Promise<CreateMCPServerResponse> {\n const body: CreateMCPServerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n scope_ids: params.scope_ids ?? [],\n name: params.name,\n description: params.description,\n options: {\n exposeSkillsTool: params.options?.exposeSkillsTool ?? true,\n exposeContextGraphTool: params.options?.exposeContextGraphTool ?? false,\n },\n };\n const res = await this.workerFetch<{\n mcp_server_id: string;\n url: string;\n status: 'active' | 'disabled';\n name: string;\n description: string | null;\n scope_ids: string[];\n tool_capabilities: { skills: boolean; context_graph: boolean };\n }>('/v1/mcp-servers', { method: 'POST', json: body });\n return {\n mcp_server_id: res.mcp_server_id,\n url: res.url.startsWith('http') ? res.url : `${this.workerUrl}${res.url}`,\n status: res.status,\n name: res.name,\n description: res.description,\n scope_ids: res.scope_ids,\n tool_capabilities: res.tool_capabilities ?? {\n skills: true,\n context_graph: false,\n },\n };\n }\n\n /**\n * List MCP servers for a user. Returns metadata only (no token).\n */\n async listMCPServers(params: {\n tenant_user_id: string;\n }): Promise<ListMCPServersResponse> {\n const path = `/v1/mcp-servers?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<ListMCPServersResponse>(path, { method: 'GET' });\n }\n\n /**\n * Get MCP server details for a user by server ID. Returns metadata only (no token).\n */\n async getMCPServer(params: {\n tenant_user_id: string;\n serverId: string;\n }): Promise<GetMCPServerResponse> {\n const path = `/v1/mcp-servers/${params.serverId}?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<GetMCPServerResponse>(path, { method: 'GET' });\n }\n\n async updateMCPServer(params: {\n tenant_user_id: string;\n serverId: string;\n tool_capabilities: {\n skills: boolean;\n context_graph: boolean;\n };\n }): Promise<GetMCPServerResponse> {\n const body: UpdateMCPServerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n tool_capabilities: params.tool_capabilities,\n };\n\n return this.workerFetch<GetMCPServerResponse>(`/v1/mcp-servers/${params.serverId}`, {\n method: 'PUT',\n json: body,\n });\n }\n\n /**\n * Connect to an MCP server by ID and receive a short-lived access token.\n * Use the returned access_token as Bearer token when calling the MCP endpoint.\n */\n async connectMCPServer(params: {\n tenant_user_id: string;\n serverId: string;\n }): Promise<ConnectMCPServerResponse> {\n const body: ConnectMCPServerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n };\n const res = await this.workerFetch<ConnectMCPServerResponse>(\n `/v1/mcp-servers/${params.serverId}/connect`,\n { method: 'POST', json: body }\n );\n return {\n ...res,\n url: res.url.startsWith('http') ? res.url : `${this.workerUrl}${res.url}`,\n };\n }\n\n /**\n * Rotate the token for an MCP server. The new token is returned only on rotate.\n */\n async rotateMCPServerToken(params: {\n tenant_user_id: string;\n serverId: string;\n }): Promise<RotateMCPServerTokenResponse> {\n return this.workerFetch<RotateMCPServerTokenResponse>(\n `/v1/mcp-servers/${params.serverId}/rotate-token`,\n {\n method: 'POST',\n json: { app_id: this.appId, tenant_user_id: params.tenant_user_id },\n }\n );\n }\n\n /**\n * Get memory stats for a user (total claim count across entire memory graph).\n * Worker caches the response for 5 minutes per user.\n */\n async getMemoryStats(params: {\n tenant_user_id: string;\n }): Promise<MemoryStatsResponse> {\n const path = `/v1/memory-stats?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<MemoryStatsResponse>(path, { method: 'GET' });\n }\n\n /**\n * Read the current scratchsheet document for a user.\n */\n async getScratchsheet(params: {\n tenant_user_id: string;\n }): Promise<ScratchsheetResponse> {\n const path = `/v1/scratchsheet?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<ScratchsheetResponse>(path, { method: 'GET' });\n }\n\n /**\n * List scopes for a user. Returns full scope details. Cached 5 min per user.\n */\n async listScopes(params: {\n tenant_user_id: string;\n }): Promise<ListScopesResponse> {\n const path = `/v1/scopes?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<ListScopesResponse>(path, { method: 'GET' });\n }\n\n /**\n * Get a single scope by ID. Returns full scope details.\n */\n async getScope(params: {\n tenant_user_id: string;\n scope_id: string;\n }): Promise<GetScopeResponse> {\n const path = `/v1/scopes/${encodeURIComponent(params.scope_id)}?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<GetScopeResponse>(path, { method: 'GET' });\n }\n\n // ---------------------------------------------------------------------------\n // Scope API (Mastra)\n // ---------------------------------------------------------------------------\n\n /**\n * Create a scope. A backfill job runs asynchronously to populate it.\n * If spec.allowed_source_types is omitted, it defaults to ['all'].\n * Uses the Worker so the scopes list cache is invalidated after create.\n */\n async createScope(params: {\n tenant_user_id: string;\n spec: ScopeSpec;\n created_by: string;\n description?: string;\n }): Promise<CreateScopeResponse> {\n const spec = {\n ...params.spec,\n allowed_source_types: params.spec.allowed_source_types ?? ['all'],\n };\n const body: CreateScopeRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n spec,\n created_by: params.created_by,\n description: params.description,\n };\n return this.workerFetch<CreateScopeResponse>('/v1/scopes', {\n method: 'POST',\n json: body,\n });\n }\n\n /**\n * Update a scope. Only provided fields are updated.\n * If include_query, exclude_query, match_mode, time_range, or allowed_source_types change,\n * a backfill job runs to recompute membership (response includes backfill_job_id).\n * Otherwise only DB and Neo4j metadata are updated.\n */\n async updateScope(params: {\n tenant_user_id: string;\n scope_id: string;\n name?: string;\n description?: string | null;\n include_query?: string;\n exclude_query?: string | null;\n match_mode?: 'strict' | 'broad';\n time_range?: { start?: string; end?: string };\n allowed_source_types?: string[] | 'all';\n }): Promise<UpdateScopeResponse> {\n const { scope_id, tenant_user_id, ...patch } = params;\n const body: Record<string, unknown> = {};\n if (patch.name !== undefined) body.name = patch.name;\n if (patch.description !== undefined) body.description = patch.description;\n if (patch.include_query !== undefined) body.include_query = patch.include_query;\n if (patch.exclude_query !== undefined) body.exclude_query = patch.exclude_query;\n if (patch.match_mode !== undefined) body.match_mode = patch.match_mode;\n if (patch.time_range !== undefined) body.time_range = patch.time_range;\n if (patch.allowed_source_types !== undefined) body.allowed_source_types = patch.allowed_source_types;\n\n const path = `/v1/scopes/${encodeURIComponent(scope_id)}?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id,\n }).toString()}`;\n return this.workerFetch<UpdateScopeResponse>(path, {\n method: 'PATCH',\n json: body,\n });\n }\n\n /**\n * Soft-delete a scope. Invalidates the scopes list cache for that user.\n */\n async deleteScope(params: {\n tenant_user_id: string;\n scope_id: string;\n }): Promise<{ deleted: boolean }> {\n const path = `/v1/scopes/${encodeURIComponent(params.scope_id)}?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<{ deleted: boolean }>(path, { method: 'DELETE' });\n }\n\n // ---------------------------------------------------------------------------\n // Webhook Verification API (Worker)\n // ---------------------------------------------------------------------------\n\n /**\n * Verify a webhook secret for a trigger.\n * This method calls the Kronos worker API to verify the webhook secret.\n * \n * @param params - app_id, tenant_user_id, trigger_id and received_secret to verify\n * @returns true if secret is valid, false otherwise\n */\n async verifyWebhookSecret(params: {\n tenant_user_id: string;\n trigger_id: string;\n received_secret: string;\n }): Promise<boolean> {\n const body = {\n trigger_id: params.trigger_id,\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n received_secret: params.received_secret,\n };\n \n try {\n const response = await this.workerFetch<{ valid: boolean }>('/v1/triggers/verify-webhook', {\n method: 'POST',\n json: body,\n });\n \n return response.valid;\n } catch (error: any) {\n // If verification fails (e.g., trigger not found), return false\n console.error('[KronosClient] Webhook verification error:', error);\n return false;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Trigger Management API (Worker)\n // ---------------------------------------------------------------------------\n\n /**\n * List triggers for a tenant user.\n */\n async listTriggers(params: {\n tenant_user_id: string;\n }): Promise<ListTriggersResponse> {\n const query = new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n });\n \n return this.workerFetch<ListTriggersResponse>(`/v1/triggers?${query.toString()}`, {\n method: 'GET',\n });\n }\n\n /**\n * Create a trigger.\n * Supports NL creation (trigger_description) or manual creation (trigger_type/trigger_spec).\n *\n * @returns CreateTriggerResponse (accepted for NL, trigger_id for manual)\n */\n async createTrigger(params: {\n tenant_user_id: string;\n webhook_url: string;\n webhook_secret: string;\n title?: string | null;\n action_description?: string;\n skill_id?: string;\n skill_version_id?: string;\n trigger_description?: string;\n trigger_type?: CreateTriggerRequest['trigger_type'];\n trigger_spec?: CreateTriggerRequest['trigger_spec'];\n next_run_at?: string;\n on_triggered?: CreateTriggerRequest['on_triggered'];\n metadata?: Record<string, unknown>;\n idempotencyKey?: string;\n }): Promise<CreateTriggerResponse> {\n const body: CreateTriggerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n webhook_url: params.webhook_url,\n webhook_secret: params.webhook_secret,\n title: params.title,\n action_description: params.action_description,\n skill_id: params.skill_id,\n skill_version_id: params.skill_version_id,\n trigger_description: params.trigger_description,\n trigger_type: params.trigger_type,\n trigger_spec: params.trigger_spec,\n next_run_at: params.next_run_at,\n on_triggered: params.on_triggered,\n metadata: params.metadata,\n };\n\n return this.workerFetch<CreateTriggerResponse>('/v1/triggers', {\n method: 'POST',\n json: body,\n idempotencyKey: params.idempotencyKey,\n });\n }\n\n /**\n * Get details for a specific trigger.\n * Uses listTriggers and filters by trigger_id.\n */\n async getTriggerDetails(params: {\n tenant_user_id: string;\n trigger_id: string;\n }): Promise<TriggerRecord> {\n const response = await this.listTriggers({ tenant_user_id: params.tenant_user_id });\n const trigger = response.triggers.find((t) => t.trigger_id === params.trigger_id);\n\n if (!trigger) {\n throw new KronosNotFoundError(`Trigger not found: ${params.trigger_id}`);\n }\n\n return trigger;\n }\n\n /**\n * Update a trigger.\n * Updates the webhook_url, action_description, status, or metadata of an existing trigger.\n * \n * @param params - app_id, tenant_user_id, trigger_id and fields to update\n * @returns UpdateTriggerResponse with success status\n */\n async updateTrigger(params: {\n tenant_user_id: string;\n trigger_id: string;\n webhook_url?: string;\n title?: string | null;\n trigger_type?: UpdateTriggerRequest['trigger_type'];\n trigger_spec?: UpdateTriggerRequest['trigger_spec'];\n next_run_at?: UpdateTriggerRequest['next_run_at'];\n action_description?: string;\n skill_id?: string | null;\n skill_version_id?: string | null;\n on_triggered?: UpdateTriggerRequest['on_triggered'];\n status?: string;\n metadata?: Record<string, unknown>;\n }): Promise<UpdateTriggerResponse> {\n const body: UpdateTriggerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n webhook_url: params.webhook_url,\n title: params.title,\n trigger_type: params.trigger_type,\n trigger_spec: params.trigger_spec,\n next_run_at: params.next_run_at,\n action_description: params.action_description,\n skill_id: params.skill_id,\n skill_version_id: params.skill_version_id,\n on_triggered: params.on_triggered,\n status: params.status,\n metadata: params.metadata,\n };\n \n return this.workerFetch<UpdateTriggerResponse>(`/v1/triggers/${params.trigger_id}`, {\n method: 'PUT',\n json: body,\n });\n }\n\n /**\n * Delete a trigger.\n */\n async deleteTrigger(params: {\n tenant_user_id: string;\n trigger_id: string;\n }): Promise<DeleteTriggerResponse> {\n const query = new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n });\n\n return this.workerFetch<DeleteTriggerResponse>(\n `/v1/triggers/${encodeURIComponent(params.trigger_id)}?${query.toString()}`,\n { method: 'DELETE' }\n );\n }\n\n // ---------------------------------------------------------------------------\n // Frontend Tokens (Server-side only)\n // ---------------------------------------------------------------------------\n\n /**\n * Issue a short-lived, user-scoped frontend token.\n * The browser can use this token directly against the Kronos worker for\n * allowed operations (e.g. trigger CRUD) without needing the app API key.\n *\n * This method must be called from a trusted server environment.\n */\n async createFrontendToken(params: {\n tenantUserId: string;\n ttlSeconds?: number;\n ops?: string[];\n }): Promise<CreateFrontendTokenResponse> {\n const res = await this.workerFetch<{ token: string; expires_at: string }>(\n '/v1/frontend-tokens',\n {\n method: 'POST',\n json: {\n app_id: this.appId,\n tenant_user_id: params.tenantUserId,\n ttl_seconds: params.ttlSeconds,\n ops: params.ops,\n },\n },\n );\n return { token: res.token, expiresAt: res.expires_at };\n }\n\n // ---------------------------------------------------------------------------\n // Skills API (Worker)\n // ---------------------------------------------------------------------------\n\n /**\n * Canonical skills API with operation-based contract.\n */\n async manageSkill(params: SkillManageParams): Promise<SkillManageResponse> {\n const idempotencyKey =\n params.operation === 'create' || params.operation === 'update'\n ? params.idempotencyKey\n : undefined;\n\n return this.workerFetch<SkillManageResponse>('/v1/skills/manage', {\n method: 'POST',\n json: {\n ...params,\n app_id: this.appId,\n },\n idempotencyKey,\n });\n }\n\n private async resolveContextGraphSkillId(\n tenantUserId: string\n ): Promise<string | null> {\n const listed = await this.manageSkill({\n operation: 'list',\n tenant_user_id: tenantUserId,\n include_internal: true,\n });\n\n const match = (listed.skills ?? []).find(\n (skill) => skill.name === INTERNAL_CONTEXT_GRAPH_SKILL_NAME\n );\n\n return match?.skill_id ?? null;\n }\n\n private parseContextGraphProcedures(\n files: Array<{ path: string; content?: string }>\n ): ContextGraphProcedureSummary[] {\n return files\n .filter((file) => file.path.startsWith('procedures/') && file.path.endsWith('.md'))\n .map((file) => {\n const content = file.content ?? '';\n const normalized = content.replace(/\\r\\n/g, '\\n');\n\n if (normalized.startsWith('---\\n')) {\n const endIndex = normalized.indexOf('\\n---\\n', 4);\n if (endIndex !== -1) {\n const frontmatter = normalized.slice(4, endIndex);\n const metadata: Record<string, string> = {};\n for (const line of frontmatter.split('\\n')) {\n const separatorIndex = line.indexOf(':');\n if (separatorIndex === -1) continue;\n const key = line.slice(0, separatorIndex).trim();\n const value = line.slice(separatorIndex + 1).trim();\n if (key && value) {\n metadata[key] = value;\n }\n }\n\n return {\n title: metadata.title || (file.path.split('/').pop() ?? file.path),\n description: metadata.description || '',\n path: file.path,\n };\n }\n }\n\n const lines = content.split(/\\r?\\n/);\n const titleLine = lines.find((line) => line.startsWith('# '));\n const title = titleLine ? titleLine.replace(/^#\\s+/, '').trim() : file.path.split('/').pop() ?? file.path;\n const description =\n lines\n .slice(1)\n .map((line) => line.trim())\n .find((line) => line.length > 0 && !line.startsWith('#')) ?? '';\n\n return {\n title,\n description,\n path: file.path,\n };\n })\n .sort((a, b) => a.path.localeCompare(b.path));\n }\n\n async getContextGraph(params: {\n tenant_user_id: string;\n }): Promise<ContextGraphSummaryResponse> {\n const skillId = await this.resolveContextGraphSkillId(params.tenant_user_id);\n if (!skillId) {\n return {\n skill_id: null,\n procedures: [],\n };\n }\n\n const treeResult = await this.manageSkill({\n operation: 'read',\n tenant_user_id: params.tenant_user_id,\n skill_id: skillId,\n mode: 'tree',\n });\n\n const procedurePaths = (treeResult.tree ?? [])\n .filter((node) => node.kind === 'file' && node.path.startsWith('procedures/') && node.path.endsWith('.md'))\n .map((node) => node.path);\n\n if (procedurePaths.length === 0) {\n return {\n skill_id: skillId,\n procedures: [],\n };\n }\n\n const filesResult = await this.manageSkill({\n operation: 'read',\n tenant_user_id: params.tenant_user_id,\n skill_id: skillId,\n mode: 'files',\n files: procedurePaths,\n fileContent: 'full',\n });\n\n return {\n skill_id: skillId,\n procedures: this.parseContextGraphProcedures(filesResult.files ?? []),\n };\n }\n\n async readContextGraph(params: {\n tenant_user_id: string;\n path?: string;\n }): Promise<ContextGraphReadResponse> {\n const skillId = await this.resolveContextGraphSkillId(params.tenant_user_id);\n const requestedPath = params.path?.trim() || 'SKILL.md';\n\n if (!skillId) {\n return {\n skill_id: null,\n path: requestedPath,\n content: null,\n };\n }\n\n if (requestedPath === 'SKILL.md') {\n const result = await this.manageSkill({\n operation: 'read',\n tenant_user_id: params.tenant_user_id,\n skill_id: skillId,\n mode: 'instructions',\n });\n\n return {\n skill_id: skillId,\n path: 'SKILL.md',\n content: result.instructions ?? null,\n };\n }\n\n const result = await this.manageSkill({\n operation: 'read',\n tenant_user_id: params.tenant_user_id,\n skill_id: skillId,\n mode: 'files',\n files: [requestedPath],\n fileContent: 'full',\n });\n\n const file = (result.files ?? []).find((entry) => entry.path === requestedPath);\n\n return {\n skill_id: skillId,\n path: requestedPath,\n content: file?.content ?? null,\n };\n }\n}\n","/**\n * Webhook verification utilities for Kronos triggers\n * Provides secure constant-time comparison for webhook secrets\n */\n\n/**\n * Verify a webhook secret using constant-time comparison to prevent timing attacks.\n * \n * @param receivedSecret - The secret received in the webhook header\n * @param storedSecret - The secret stored in the database for the trigger\n * @returns true if secrets match, false otherwise\n * \n * @example\n * ```typescript\n * import { verifyWebhookSecret } from '@gdrl/kronos-lib/webhook-verification';\n * \n * const isValid = verifyWebhookSecret(\n * request.headers.get('X-Kronos-Webhook-Secret'),\n * trigger.webhook_secret\n * );\n * \n * if (!isValid) {\n * return new Response('Unauthorized', { status: 401 });\n * }\n * ```\n */\nexport function verifyWebhookSecret(\n receivedSecret: string | null | undefined,\n storedSecret: string | null | undefined\n): boolean {\n // If either is missing, they don't match\n if (!receivedSecret || !storedSecret) {\n return false;\n }\n\n // Constant-time comparison to prevent timing attacks\n if (receivedSecret.length !== storedSecret.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < receivedSecret.length; i++) {\n result |= receivedSecret.charCodeAt(i) ^ storedSecret.charCodeAt(i);\n }\n\n return result === 0;\n}\n"],"mappings":"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","names":["result"]}
|
package/dist/index.mjs
CHANGED
|
@@ -54,9 +54,17 @@ function generateIdempotencyKey() {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
// src/client.ts
|
|
57
|
-
var
|
|
58
|
-
var
|
|
57
|
+
var PRODUCTION_WORKER_URL = "https://api.kronos.ai";
|
|
58
|
+
var PRODUCTION_MASTRA_URL = "https://mastra.kronos.ai";
|
|
59
|
+
var DEV_WORKER_URL = "http://localhost:8787";
|
|
60
|
+
var DEV_MASTRA_URL = "http://localhost:4111";
|
|
59
61
|
var INTERNAL_CONTEXT_GRAPH_SKILL_NAME = "__internal_context_graph__";
|
|
62
|
+
function defaultWorkerUrl() {
|
|
63
|
+
return process.env.NODE_ENV === "production" ? PRODUCTION_WORKER_URL : DEV_WORKER_URL;
|
|
64
|
+
}
|
|
65
|
+
function defaultMastraUrl() {
|
|
66
|
+
return process.env.NODE_ENV === "production" ? PRODUCTION_MASTRA_URL : DEV_MASTRA_URL;
|
|
67
|
+
}
|
|
60
68
|
var KronosClient = class {
|
|
61
69
|
constructor(config) {
|
|
62
70
|
if (!config.apiKey) {
|
|
@@ -65,8 +73,8 @@ var KronosClient = class {
|
|
|
65
73
|
if (!config.appId) {
|
|
66
74
|
throw new Error("KronosClient: appId is required in constructor");
|
|
67
75
|
}
|
|
68
|
-
this.workerUrl =
|
|
69
|
-
this.mastraUrl =
|
|
76
|
+
this.workerUrl = (config.workerUrl ?? process.env.KRONOS_WORKER_URL ?? defaultWorkerUrl()).replace(/\/$/, "");
|
|
77
|
+
this.mastraUrl = (config.mastraUrl ?? process.env.KRONOS_MASTRA_URL ?? defaultMastraUrl()).replace(/\/$/, "");
|
|
70
78
|
this.apiKey = config.apiKey;
|
|
71
79
|
this.appId = config.appId;
|
|
72
80
|
console.log("[KronosClient] \u2705 KronosClient initialized:", {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/utils.ts","../src/client.ts","../src/webhook-verification.ts"],"sourcesContent":["/**\n * Base error for Kronos API failures\n */\nexport class KronosError extends Error {\n constructor(\n message: string,\n public readonly status?: number,\n public readonly code?: string,\n public readonly body?: unknown\n ) {\n super(message);\n this.name = 'KronosError';\n Object.setPrototypeOf(this, KronosError.prototype);\n }\n}\n\n/**\n * 400 Bad Request - invalid or missing parameters\n */\nexport class KronosBadRequestError extends KronosError {\n constructor(message: string, body?: unknown) {\n super(message, 400, 'bad_request', body);\n this.name = 'KronosBadRequestError';\n Object.setPrototypeOf(this, KronosBadRequestError.prototype);\n }\n}\n\n/**\n * 401 Unauthorized - invalid or missing API key\n */\nexport class KronosUnauthorizedError extends KronosError {\n constructor(message: string, body?: unknown) {\n super(message, 401, 'unauthorized', body);\n this.name = 'KronosUnauthorizedError';\n Object.setPrototypeOf(this, KronosUnauthorizedError.prototype);\n }\n}\n\n/**\n * 403 Forbidden - valid auth but insufficient permissions\n */\nexport class KronosForbiddenError extends KronosError {\n constructor(message: string, body?: unknown) {\n super(message, 403, 'forbidden', body);\n this.name = 'KronosForbiddenError';\n Object.setPrototypeOf(this, KronosForbiddenError.prototype);\n }\n}\n\n/**\n * 404 Not Found - resource does not exist\n */\nexport class KronosNotFoundError extends KronosError {\n constructor(message: string, body?: unknown) {\n super(message, 404, 'not_found', body);\n this.name = 'KronosNotFoundError';\n Object.setPrototypeOf(this, KronosNotFoundError.prototype);\n }\n}\n\n/**\n * 5xx or network/unknown errors\n */\nexport class KronosServerError extends KronosError {\n constructor(message: string, status?: number, body?: unknown) {\n super(message, status, 'server_error', body);\n this.name = 'KronosServerError';\n Object.setPrototypeOf(this, KronosServerError.prototype);\n }\n}\n","/**\n * Generate an idempotency key for ingest requests.\n * Uses crypto.randomUUID() when available; falls back to a timestamp-based value.\n * Callers can pass their own key via the ingest options to achieve true idempotency.\n */\nexport function generateIdempotencyKey(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return `idem_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;\n}\n","import type {\n KronosClientConfig,\n IngestRequest,\n IngestResponse,\n IngestStatusResponse,\n CreateMCPServerRequest,\n CreateMCPServerResponse,\n UpdateMCPServerRequest,\n ListMCPServersResponse,\n GetMCPServerResponse,\n ConnectMCPServerRequest,\n ConnectMCPServerResponse,\n RotateMCPServerTokenResponse,\n MemoryStatsResponse,\n ScratchsheetResponse,\n ListScopesResponse,\n GetScopeResponse,\n CreateScopeRequest,\n CreateScopeResponse,\n UpdateScopeResponse,\n CreateTriggerRequest,\n CreateTriggerResponse,\n CreateFrontendTokenResponse,\n ListTriggersResponse,\n ScopeSpec,\n UpdateTriggerRequest,\n UpdateTriggerResponse,\n DeleteTriggerResponse,\n TriggerRecord,\n SkillManageParams,\n SkillManageResponse,\n ContextGraphSummaryResponse,\n ContextGraphReadResponse,\n ContextGraphProcedureSummary,\n} from './types';\nimport {\n KronosError,\n KronosBadRequestError,\n KronosUnauthorizedError,\n KronosForbiddenError,\n KronosNotFoundError,\n KronosServerError,\n} from './errors';\nimport { generateIdempotencyKey } from './utils';\n\n// Service URLs are hardcoded in the library - users cannot configure these\n// These are YOUR backend services that power the library\n// These are replaced at BUILD TIME by tsup.config.ts reading from .env file\n// Defaults shown below - override via .env file in kronos-lib directory\nconst WORKER_URL = process.env.KRONOS_WORKER_URL || 'https://api.kronos.ai';\nconst MASTRA_URL = process.env.KRONOS_MASTRA_URL || 'https://mastra.kronos.ai';\nconst INTERNAL_CONTEXT_GRAPH_SKILL_NAME = '__internal_context_graph__';\n\nexport class KronosClient {\n private readonly workerUrl: string;\n private readonly mastraUrl: string;\n private readonly apiKey: string;\n private readonly appId: string;\n\n constructor(config: KronosClientConfig) {\n // Validate required constructor parameters\n if (!config.apiKey) {\n throw new Error('KronosClient: apiKey is required in constructor');\n }\n \n if (!config.appId) {\n throw new Error('KronosClient: appId is required in constructor');\n }\n \n // Service URLs are hardcoded - users cannot change these\n // They are YOUR backend services, set at library build time\n this.workerUrl = WORKER_URL.replace(/\\/$/, '');\n this.mastraUrl = MASTRA_URL.replace(/\\/$/, '');\n this.apiKey = config.apiKey;\n this.appId = config.appId;\n \n console.log('[KronosClient] ✅ KronosClient initialized:', {\n appId: this.appId,\n workerUrl: this.workerUrl,\n mastraUrl: this.mastraUrl,\n hasApiKey: !!this.apiKey,\n });\n \n // Perform async health check (fire and forget)\n this.healthCheck().catch(() => {\n // Health check failed, but don't block initialization\n });\n }\n \n /**\n * Perform a health check to verify the client can connect to the Kronos worker\n * This is called automatically during initialization\n */\n private async healthCheck(): Promise<void> {\n try {\n const response = await fetch(`${this.workerUrl}/health`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n \n if (response.ok) {\n const data = await response.json();\n if (data.status === 'ok') {\n console.log('[KronosClient] ✅ Health check passed - Client is connected and working');\n } else {\n console.warn('[KronosClient] ⚠️ Health check returned unexpected status:', data);\n }\n } else {\n console.warn(`[KronosClient] ⚠️ Health check failed with status ${response.status}. Client may not be working correctly.`);\n }\n } catch (error: any) {\n console.warn('[KronosClient] ⚠️ Health check failed - Unable to connect to Kronos worker:', error.message);\n console.warn('[KronosClient] Please verify that:');\n console.warn('[KronosClient] 1. The worker URL is correct:', this.workerUrl);\n console.warn('[KronosClient] 2. The worker is running and accessible');\n console.warn('[KronosClient] 3. Network connectivity is available');\n }\n }\n\n // ---------------------------------------------------------------------------\n // Worker request helper (uses Bearer auth)\n // ---------------------------------------------------------------------------\n private async workerFetch<T>(\n path: string,\n options: { method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; json?: object; idempotencyKey?: string } = {}\n ): Promise<T> {\n const { json, idempotencyKey, method } = options;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n };\n if (idempotencyKey) headers['Idempotency-Key'] = idempotencyKey;\n const res = await fetch(`${this.workerUrl}${path}`, {\n method: method ?? (json ? 'POST' : 'GET'),\n headers,\n body: json ? JSON.stringify(json) : undefined,\n });\n return this.handleResponse<T>(res);\n }\n\n // ---------------------------------------------------------------------------\n // Mastra request helper (no Bearer auth per current API)\n // ---------------------------------------------------------------------------\n private async mastraFetch<T>(\n path: string,\n options: { method?: 'GET' | 'POST'; json?: object } = {}\n ): Promise<T> {\n const { json, method } = options;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n const res = await fetch(`${this.mastraUrl}${path}`, {\n method: method ?? (json ? 'POST' : 'GET'),\n headers,\n body: json ? JSON.stringify(json) : undefined,\n });\n return this.handleResponse<T>(res);\n }\n\n private async handleResponse<T>(res: Response): Promise<T> {\n const text = await res.text();\n let body: unknown = null;\n try {\n body = text ? JSON.parse(text) : null;\n } catch {\n body = text;\n }\n\n if (!res.ok) {\n const errBody = body as { error?: string } | null;\n const message = (errBody && typeof errBody.error === 'string')\n ? errBody.error\n : `Request failed with status ${res.status}`;\n\n switch (res.status) {\n case 400:\n throw new KronosBadRequestError(message, body);\n case 401:\n throw new KronosUnauthorizedError(message, body);\n case 403:\n throw new KronosForbiddenError(message, body);\n case 404:\n throw new KronosNotFoundError(message, body);\n default:\n if (res.status >= 500) {\n throw new KronosServerError(message, res.status, body);\n }\n throw new KronosError(message, res.status, undefined, body);\n }\n }\n\n return (body ?? null) as T;\n }\n\n // ---------------------------------------------------------------------------\n // Ingest API\n // ---------------------------------------------------------------------------\n\n /**\n * Submit a document for ingestion.\n * @param params - source_type, content, optional metadata, addToMemory, and idempotencyKey\n * @returns ingest_id\n */\n async ingest(params: {\n tenant_user_id: string;\n source_type: string;\n priority?: 'low' | 'medium' | 'high';\n addToMemory?: boolean;\n content: { type: 'text'; text: string };\n metadata?: Record<string, unknown>;\n idempotencyKey?: string;\n }): Promise<IngestResponse> {\n const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();\n const body: IngestRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n source_type: params.source_type,\n priority: params.priority,\n addToMemory: params.addToMemory,\n content: params.content,\n metadata: params.metadata,\n };\n return this.workerFetch<IngestResponse>('/v1/ingest', {\n method: 'POST',\n json: body,\n idempotencyKey,\n });\n }\n\n /**\n * Get the status of an ingest.\n */\n async getIngestStatus(ingestId: string): Promise<IngestStatusResponse> {\n return this.workerFetch<IngestStatusResponse>(`/v1/ingest/${ingestId}`, {\n method: 'GET',\n });\n }\n\n // ---------------------------------------------------------------------------\n // MCP Server API\n // ---------------------------------------------------------------------------\n\n /**\n * Create an MCP server scoped to the given scopes.\n * Use connectMCPServer() to get a short-lived access token for MCP auth.\n */\n async createMCPServer(params: {\n tenant_user_id: string;\n name: string;\n /** Omit or pass [] for all-memory access. */\n scope_ids?: string[] | null;\n description?: string;\n options?: {\n /** Expose `search_skills` and `read_skill`. Defaults to true. */\n exposeSkillsTool?: boolean;\n /** Expose the read-only `context_graph` tool. Defaults to false. */\n exposeContextGraphTool?: boolean;\n };\n }): Promise<CreateMCPServerResponse> {\n const body: CreateMCPServerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n scope_ids: params.scope_ids ?? [],\n name: params.name,\n description: params.description,\n options: {\n exposeSkillsTool: params.options?.exposeSkillsTool ?? true,\n exposeContextGraphTool: params.options?.exposeContextGraphTool ?? false,\n },\n };\n const res = await this.workerFetch<{\n mcp_server_id: string;\n url: string;\n status: 'active' | 'disabled';\n name: string;\n description: string | null;\n scope_ids: string[];\n tool_capabilities: { skills: boolean; context_graph: boolean };\n }>('/v1/mcp-servers', { method: 'POST', json: body });\n return {\n mcp_server_id: res.mcp_server_id,\n url: res.url.startsWith('http') ? res.url : `${this.workerUrl}${res.url}`,\n status: res.status,\n name: res.name,\n description: res.description,\n scope_ids: res.scope_ids,\n tool_capabilities: res.tool_capabilities ?? {\n skills: true,\n context_graph: false,\n },\n };\n }\n\n /**\n * List MCP servers for a user. Returns metadata only (no token).\n */\n async listMCPServers(params: {\n tenant_user_id: string;\n }): Promise<ListMCPServersResponse> {\n const path = `/v1/mcp-servers?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<ListMCPServersResponse>(path, { method: 'GET' });\n }\n\n /**\n * Get MCP server details for a user by server ID. Returns metadata only (no token).\n */\n async getMCPServer(params: {\n tenant_user_id: string;\n serverId: string;\n }): Promise<GetMCPServerResponse> {\n const path = `/v1/mcp-servers/${params.serverId}?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<GetMCPServerResponse>(path, { method: 'GET' });\n }\n\n async updateMCPServer(params: {\n tenant_user_id: string;\n serverId: string;\n tool_capabilities: {\n skills: boolean;\n context_graph: boolean;\n };\n }): Promise<GetMCPServerResponse> {\n const body: UpdateMCPServerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n tool_capabilities: params.tool_capabilities,\n };\n\n return this.workerFetch<GetMCPServerResponse>(`/v1/mcp-servers/${params.serverId}`, {\n method: 'PUT',\n json: body,\n });\n }\n\n /**\n * Connect to an MCP server by ID and receive a short-lived access token.\n * Use the returned access_token as Bearer token when calling the MCP endpoint.\n */\n async connectMCPServer(params: {\n tenant_user_id: string;\n serverId: string;\n }): Promise<ConnectMCPServerResponse> {\n const body: ConnectMCPServerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n };\n const res = await this.workerFetch<ConnectMCPServerResponse>(\n `/v1/mcp-servers/${params.serverId}/connect`,\n { method: 'POST', json: body }\n );\n return {\n ...res,\n url: res.url.startsWith('http') ? res.url : `${this.workerUrl}${res.url}`,\n };\n }\n\n /**\n * Rotate the token for an MCP server. The new token is returned only on rotate.\n */\n async rotateMCPServerToken(params: {\n tenant_user_id: string;\n serverId: string;\n }): Promise<RotateMCPServerTokenResponse> {\n return this.workerFetch<RotateMCPServerTokenResponse>(\n `/v1/mcp-servers/${params.serverId}/rotate-token`,\n {\n method: 'POST',\n json: { app_id: this.appId, tenant_user_id: params.tenant_user_id },\n }\n );\n }\n\n /**\n * Get memory stats for a user (total claim count across entire memory graph).\n * Worker caches the response for 5 minutes per user.\n */\n async getMemoryStats(params: {\n tenant_user_id: string;\n }): Promise<MemoryStatsResponse> {\n const path = `/v1/memory-stats?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<MemoryStatsResponse>(path, { method: 'GET' });\n }\n\n /**\n * Read the current scratchsheet document for a user.\n */\n async getScratchsheet(params: {\n tenant_user_id: string;\n }): Promise<ScratchsheetResponse> {\n const path = `/v1/scratchsheet?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<ScratchsheetResponse>(path, { method: 'GET' });\n }\n\n /**\n * List scopes for a user. Returns full scope details. Cached 5 min per user.\n */\n async listScopes(params: {\n tenant_user_id: string;\n }): Promise<ListScopesResponse> {\n const path = `/v1/scopes?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<ListScopesResponse>(path, { method: 'GET' });\n }\n\n /**\n * Get a single scope by ID. Returns full scope details.\n */\n async getScope(params: {\n tenant_user_id: string;\n scope_id: string;\n }): Promise<GetScopeResponse> {\n const path = `/v1/scopes/${encodeURIComponent(params.scope_id)}?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<GetScopeResponse>(path, { method: 'GET' });\n }\n\n // ---------------------------------------------------------------------------\n // Scope API (Mastra)\n // ---------------------------------------------------------------------------\n\n /**\n * Create a scope. A backfill job runs asynchronously to populate it.\n * If spec.allowed_source_types is omitted, it defaults to ['all'].\n * Uses the Worker so the scopes list cache is invalidated after create.\n */\n async createScope(params: {\n tenant_user_id: string;\n spec: ScopeSpec;\n created_by: string;\n description?: string;\n }): Promise<CreateScopeResponse> {\n const spec = {\n ...params.spec,\n allowed_source_types: params.spec.allowed_source_types ?? ['all'],\n };\n const body: CreateScopeRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n spec,\n created_by: params.created_by,\n description: params.description,\n };\n return this.workerFetch<CreateScopeResponse>('/v1/scopes', {\n method: 'POST',\n json: body,\n });\n }\n\n /**\n * Update a scope. Only provided fields are updated.\n * If include_query, exclude_query, match_mode, time_range, or allowed_source_types change,\n * a backfill job runs to recompute membership (response includes backfill_job_id).\n * Otherwise only DB and Neo4j metadata are updated.\n */\n async updateScope(params: {\n tenant_user_id: string;\n scope_id: string;\n name?: string;\n description?: string | null;\n include_query?: string;\n exclude_query?: string | null;\n match_mode?: 'strict' | 'broad';\n time_range?: { start?: string; end?: string };\n allowed_source_types?: string[] | 'all';\n }): Promise<UpdateScopeResponse> {\n const { scope_id, tenant_user_id, ...patch } = params;\n const body: Record<string, unknown> = {};\n if (patch.name !== undefined) body.name = patch.name;\n if (patch.description !== undefined) body.description = patch.description;\n if (patch.include_query !== undefined) body.include_query = patch.include_query;\n if (patch.exclude_query !== undefined) body.exclude_query = patch.exclude_query;\n if (patch.match_mode !== undefined) body.match_mode = patch.match_mode;\n if (patch.time_range !== undefined) body.time_range = patch.time_range;\n if (patch.allowed_source_types !== undefined) body.allowed_source_types = patch.allowed_source_types;\n\n const path = `/v1/scopes/${encodeURIComponent(scope_id)}?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id,\n }).toString()}`;\n return this.workerFetch<UpdateScopeResponse>(path, {\n method: 'PATCH',\n json: body,\n });\n }\n\n /**\n * Soft-delete a scope. Invalidates the scopes list cache for that user.\n */\n async deleteScope(params: {\n tenant_user_id: string;\n scope_id: string;\n }): Promise<{ deleted: boolean }> {\n const path = `/v1/scopes/${encodeURIComponent(params.scope_id)}?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<{ deleted: boolean }>(path, { method: 'DELETE' });\n }\n\n // ---------------------------------------------------------------------------\n // Webhook Verification API (Worker)\n // ---------------------------------------------------------------------------\n\n /**\n * Verify a webhook secret for a trigger.\n * This method calls the Kronos worker API to verify the webhook secret.\n * \n * @param params - app_id, tenant_user_id, trigger_id and received_secret to verify\n * @returns true if secret is valid, false otherwise\n */\n async verifyWebhookSecret(params: {\n tenant_user_id: string;\n trigger_id: string;\n received_secret: string;\n }): Promise<boolean> {\n const body = {\n trigger_id: params.trigger_id,\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n received_secret: params.received_secret,\n };\n \n try {\n const response = await this.workerFetch<{ valid: boolean }>('/v1/triggers/verify-webhook', {\n method: 'POST',\n json: body,\n });\n \n return response.valid;\n } catch (error: any) {\n // If verification fails (e.g., trigger not found), return false\n console.error('[KronosClient] Webhook verification error:', error);\n return false;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Trigger Management API (Worker)\n // ---------------------------------------------------------------------------\n\n /**\n * List triggers for a tenant user.\n */\n async listTriggers(params: {\n tenant_user_id: string;\n }): Promise<ListTriggersResponse> {\n const query = new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n });\n \n return this.workerFetch<ListTriggersResponse>(`/v1/triggers?${query.toString()}`, {\n method: 'GET',\n });\n }\n\n /**\n * Create a trigger.\n * Supports NL creation (trigger_description) or manual creation (trigger_type/trigger_spec).\n *\n * @returns CreateTriggerResponse (accepted for NL, trigger_id for manual)\n */\n async createTrigger(params: {\n tenant_user_id: string;\n webhook_url: string;\n webhook_secret: string;\n title?: string | null;\n action_description?: string;\n skill_id?: string;\n skill_version_id?: string;\n trigger_description?: string;\n trigger_type?: CreateTriggerRequest['trigger_type'];\n trigger_spec?: CreateTriggerRequest['trigger_spec'];\n next_run_at?: string;\n on_triggered?: CreateTriggerRequest['on_triggered'];\n metadata?: Record<string, unknown>;\n idempotencyKey?: string;\n }): Promise<CreateTriggerResponse> {\n const body: CreateTriggerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n webhook_url: params.webhook_url,\n webhook_secret: params.webhook_secret,\n title: params.title,\n action_description: params.action_description,\n skill_id: params.skill_id,\n skill_version_id: params.skill_version_id,\n trigger_description: params.trigger_description,\n trigger_type: params.trigger_type,\n trigger_spec: params.trigger_spec,\n next_run_at: params.next_run_at,\n on_triggered: params.on_triggered,\n metadata: params.metadata,\n };\n\n return this.workerFetch<CreateTriggerResponse>('/v1/triggers', {\n method: 'POST',\n json: body,\n idempotencyKey: params.idempotencyKey,\n });\n }\n\n /**\n * Get details for a specific trigger.\n * Uses listTriggers and filters by trigger_id.\n */\n async getTriggerDetails(params: {\n tenant_user_id: string;\n trigger_id: string;\n }): Promise<TriggerRecord> {\n const response = await this.listTriggers({ tenant_user_id: params.tenant_user_id });\n const trigger = response.triggers.find((t) => t.trigger_id === params.trigger_id);\n\n if (!trigger) {\n throw new KronosNotFoundError(`Trigger not found: ${params.trigger_id}`);\n }\n\n return trigger;\n }\n\n /**\n * Update a trigger.\n * Updates the webhook_url, action_description, status, or metadata of an existing trigger.\n * \n * @param params - app_id, tenant_user_id, trigger_id and fields to update\n * @returns UpdateTriggerResponse with success status\n */\n async updateTrigger(params: {\n tenant_user_id: string;\n trigger_id: string;\n webhook_url?: string;\n title?: string | null;\n trigger_type?: UpdateTriggerRequest['trigger_type'];\n trigger_spec?: UpdateTriggerRequest['trigger_spec'];\n next_run_at?: UpdateTriggerRequest['next_run_at'];\n action_description?: string;\n skill_id?: string | null;\n skill_version_id?: string | null;\n on_triggered?: UpdateTriggerRequest['on_triggered'];\n status?: string;\n metadata?: Record<string, unknown>;\n }): Promise<UpdateTriggerResponse> {\n const body: UpdateTriggerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n webhook_url: params.webhook_url,\n title: params.title,\n trigger_type: params.trigger_type,\n trigger_spec: params.trigger_spec,\n next_run_at: params.next_run_at,\n action_description: params.action_description,\n skill_id: params.skill_id,\n skill_version_id: params.skill_version_id,\n on_triggered: params.on_triggered,\n status: params.status,\n metadata: params.metadata,\n };\n \n return this.workerFetch<UpdateTriggerResponse>(`/v1/triggers/${params.trigger_id}`, {\n method: 'PUT',\n json: body,\n });\n }\n\n /**\n * Delete a trigger.\n */\n async deleteTrigger(params: {\n tenant_user_id: string;\n trigger_id: string;\n }): Promise<DeleteTriggerResponse> {\n const query = new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n });\n\n return this.workerFetch<DeleteTriggerResponse>(\n `/v1/triggers/${encodeURIComponent(params.trigger_id)}?${query.toString()}`,\n { method: 'DELETE' }\n );\n }\n\n // ---------------------------------------------------------------------------\n // Frontend Tokens (Server-side only)\n // ---------------------------------------------------------------------------\n\n /**\n * Issue a short-lived, user-scoped frontend token.\n * The browser can use this token directly against the Kronos worker for\n * allowed operations (e.g. trigger CRUD) without needing the app API key.\n *\n * This method must be called from a trusted server environment.\n */\n async createFrontendToken(params: {\n tenantUserId: string;\n ttlSeconds?: number;\n ops?: string[];\n }): Promise<CreateFrontendTokenResponse> {\n const res = await this.workerFetch<{ token: string; expires_at: string }>(\n '/v1/frontend-tokens',\n {\n method: 'POST',\n json: {\n app_id: this.appId,\n tenant_user_id: params.tenantUserId,\n ttl_seconds: params.ttlSeconds,\n ops: params.ops,\n },\n },\n );\n return { token: res.token, expiresAt: res.expires_at };\n }\n\n // ---------------------------------------------------------------------------\n // Skills API (Worker)\n // ---------------------------------------------------------------------------\n\n /**\n * Canonical skills API with operation-based contract.\n */\n async manageSkill(params: SkillManageParams): Promise<SkillManageResponse> {\n const idempotencyKey =\n params.operation === 'create' || params.operation === 'update'\n ? params.idempotencyKey\n : undefined;\n\n return this.workerFetch<SkillManageResponse>('/v1/skills/manage', {\n method: 'POST',\n json: {\n ...params,\n app_id: this.appId,\n },\n idempotencyKey,\n });\n }\n\n private async resolveContextGraphSkillId(\n tenantUserId: string\n ): Promise<string | null> {\n const listed = await this.manageSkill({\n operation: 'list',\n tenant_user_id: tenantUserId,\n include_internal: true,\n });\n\n const match = (listed.skills ?? []).find(\n (skill) => skill.name === INTERNAL_CONTEXT_GRAPH_SKILL_NAME\n );\n\n return match?.skill_id ?? null;\n }\n\n private parseContextGraphProcedures(\n files: Array<{ path: string; content?: string }>\n ): ContextGraphProcedureSummary[] {\n return files\n .filter((file) => file.path.startsWith('procedures/') && file.path.endsWith('.md'))\n .map((file) => {\n const content = file.content ?? '';\n const normalized = content.replace(/\\r\\n/g, '\\n');\n\n if (normalized.startsWith('---\\n')) {\n const endIndex = normalized.indexOf('\\n---\\n', 4);\n if (endIndex !== -1) {\n const frontmatter = normalized.slice(4, endIndex);\n const metadata: Record<string, string> = {};\n for (const line of frontmatter.split('\\n')) {\n const separatorIndex = line.indexOf(':');\n if (separatorIndex === -1) continue;\n const key = line.slice(0, separatorIndex).trim();\n const value = line.slice(separatorIndex + 1).trim();\n if (key && value) {\n metadata[key] = value;\n }\n }\n\n return {\n title: metadata.title || (file.path.split('/').pop() ?? file.path),\n description: metadata.description || '',\n path: file.path,\n };\n }\n }\n\n const lines = content.split(/\\r?\\n/);\n const titleLine = lines.find((line) => line.startsWith('# '));\n const title = titleLine ? titleLine.replace(/^#\\s+/, '').trim() : file.path.split('/').pop() ?? file.path;\n const description =\n lines\n .slice(1)\n .map((line) => line.trim())\n .find((line) => line.length > 0 && !line.startsWith('#')) ?? '';\n\n return {\n title,\n description,\n path: file.path,\n };\n })\n .sort((a, b) => a.path.localeCompare(b.path));\n }\n\n async getContextGraph(params: {\n tenant_user_id: string;\n }): Promise<ContextGraphSummaryResponse> {\n const skillId = await this.resolveContextGraphSkillId(params.tenant_user_id);\n if (!skillId) {\n return {\n skill_id: null,\n procedures: [],\n };\n }\n\n const treeResult = await this.manageSkill({\n operation: 'read',\n tenant_user_id: params.tenant_user_id,\n skill_id: skillId,\n mode: 'tree',\n });\n\n const procedurePaths = (treeResult.tree ?? [])\n .filter((node) => node.kind === 'file' && node.path.startsWith('procedures/') && node.path.endsWith('.md'))\n .map((node) => node.path);\n\n if (procedurePaths.length === 0) {\n return {\n skill_id: skillId,\n procedures: [],\n };\n }\n\n const filesResult = await this.manageSkill({\n operation: 'read',\n tenant_user_id: params.tenant_user_id,\n skill_id: skillId,\n mode: 'files',\n files: procedurePaths,\n fileContent: 'full',\n });\n\n return {\n skill_id: skillId,\n procedures: this.parseContextGraphProcedures(filesResult.files ?? []),\n };\n }\n\n async readContextGraph(params: {\n tenant_user_id: string;\n path?: string;\n }): Promise<ContextGraphReadResponse> {\n const skillId = await this.resolveContextGraphSkillId(params.tenant_user_id);\n const requestedPath = params.path?.trim() || 'SKILL.md';\n\n if (!skillId) {\n return {\n skill_id: null,\n path: requestedPath,\n content: null,\n };\n }\n\n if (requestedPath === 'SKILL.md') {\n const result = await this.manageSkill({\n operation: 'read',\n tenant_user_id: params.tenant_user_id,\n skill_id: skillId,\n mode: 'instructions',\n });\n\n return {\n skill_id: skillId,\n path: 'SKILL.md',\n content: result.instructions ?? null,\n };\n }\n\n const result = await this.manageSkill({\n operation: 'read',\n tenant_user_id: params.tenant_user_id,\n skill_id: skillId,\n mode: 'files',\n files: [requestedPath],\n fileContent: 'full',\n });\n\n const file = (result.files ?? []).find((entry) => entry.path === requestedPath);\n\n return {\n skill_id: skillId,\n path: requestedPath,\n content: file?.content ?? null,\n };\n }\n}\n","/**\n * Webhook verification utilities for Kronos triggers\n * Provides secure constant-time comparison for webhook secrets\n */\n\n/**\n * Verify a webhook secret using constant-time comparison to prevent timing attacks.\n * \n * @param receivedSecret - The secret received in the webhook header\n * @param storedSecret - The secret stored in the database for the trigger\n * @returns true if secrets match, false otherwise\n * \n * @example\n * ```typescript\n * import { verifyWebhookSecret } from '@gdrl/kronos-lib/webhook-verification';\n * \n * const isValid = verifyWebhookSecret(\n * request.headers.get('X-Kronos-Webhook-Secret'),\n * trigger.webhook_secret\n * );\n * \n * if (!isValid) {\n * return new Response('Unauthorized', { status: 401 });\n * }\n * ```\n */\nexport function verifyWebhookSecret(\n receivedSecret: string | null | undefined,\n storedSecret: string | null | undefined\n): boolean {\n // If either is missing, they don't match\n if (!receivedSecret || !storedSecret) {\n return false;\n }\n\n // Constant-time comparison to prevent timing attacks\n if (receivedSecret.length !== storedSecret.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < receivedSecret.length; i++) {\n result |= receivedSecret.charCodeAt(i) ^ storedSecret.charCodeAt(i);\n }\n\n return result === 0;\n}\n"],"mappings":";AAGO,IAAM,cAAN,MAAM,qBAAoB,MAAM;AAAA,EACrC,YACE,SACgB,QACA,MACA,MAChB;AACA,UAAM,OAAO;AAJG;AACA;AACA;AAGhB,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,aAAY,SAAS;AAAA,EACnD;AACF;AAKO,IAAM,wBAAN,MAAM,+BAA8B,YAAY;AAAA,EACrD,YAAY,SAAiB,MAAgB;AAC3C,UAAM,SAAS,KAAK,eAAe,IAAI;AACvC,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,uBAAsB,SAAS;AAAA,EAC7D;AACF;AAKO,IAAM,0BAAN,MAAM,iCAAgC,YAAY;AAAA,EACvD,YAAY,SAAiB,MAAgB;AAC3C,UAAM,SAAS,KAAK,gBAAgB,IAAI;AACxC,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,yBAAwB,SAAS;AAAA,EAC/D;AACF;AAKO,IAAM,uBAAN,MAAM,8BAA6B,YAAY;AAAA,EACpD,YAAY,SAAiB,MAAgB;AAC3C,UAAM,SAAS,KAAK,aAAa,IAAI;AACrC,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,sBAAqB,SAAS;AAAA,EAC5D;AACF;AAKO,IAAM,sBAAN,MAAM,6BAA4B,YAAY;AAAA,EACnD,YAAY,SAAiB,MAAgB;AAC3C,UAAM,SAAS,KAAK,aAAa,IAAI;AACrC,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,qBAAoB,SAAS;AAAA,EAC3D;AACF;AAKO,IAAM,oBAAN,MAAM,2BAA0B,YAAY;AAAA,EACjD,YAAY,SAAiB,QAAiB,MAAgB;AAC5D,UAAM,SAAS,QAAQ,gBAAgB,IAAI;AAC3C,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,mBAAkB,SAAS;AAAA,EACzD;AACF;;;AChEO,SAAS,yBAAiC;AAC/C,MAAI,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,YAAY;AAC5E,WAAO,OAAO,WAAW;AAAA,EAC3B;AACA,SAAO,QAAQ,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AACtE;;;ACuCA,IAAM,aAAa;AACnB,IAAM,aAAa;AACnB,IAAM,oCAAoC;AAEnC,IAAM,eAAN,MAAmB;AAAA,EAMxB,YAAY,QAA4B;AAEtC,QAAI,CAAC,OAAO,QAAQ;AAClB,YAAM,IAAI,MAAM,iDAAiD;AAAA,IACnE;AAEA,QAAI,CAAC,OAAO,OAAO;AACjB,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AAIA,SAAK,YAAY,WAAW,QAAQ,OAAO,EAAE;AAC7C,SAAK,YAAY,WAAW,QAAQ,OAAO,EAAE;AAC7C,SAAK,SAAS,OAAO;AACrB,SAAK,QAAQ,OAAO;AAEpB,YAAQ,IAAI,mDAA8C;AAAA,MACxD,OAAO,KAAK;AAAA,MACZ,WAAW,KAAK;AAAA,MAChB,WAAW,KAAK;AAAA,MAChB,WAAW,CAAC,CAAC,KAAK;AAAA,IACpB,CAAC;AAGD,SAAK,YAAY,EAAE,MAAM,MAAM;AAAA,IAE/B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,cAA6B;AACzC,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,SAAS,WAAW;AAAA,QACvD,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,MACF,CAAC;AAED,UAAI,SAAS,IAAI;AACf,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAI,KAAK,WAAW,MAAM;AACxB,kBAAQ,IAAI,6EAAwE;AAAA,QACtF,OAAO;AACL,kBAAQ,KAAK,yEAA+D,IAAI;AAAA,QAClF;AAAA,MACF,OAAO;AACL,gBAAQ,KAAK,gEAAsD,SAAS,MAAM,wCAAwC;AAAA,MAC5H;AAAA,IACF,SAAS,OAAY;AACnB,cAAQ,KAAK,0FAAgF,MAAM,OAAO;AAC1G,cAAQ,KAAK,oCAAoC;AACjD,cAAQ,KAAK,kDAAkD,KAAK,SAAS;AAC7E,cAAQ,KAAK,0DAA0D;AACvE,cAAQ,KAAK,uDAAuD;AAAA,IACtE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,YACZ,MACA,UAA4G,CAAC,GACjG;AACZ,UAAM,EAAE,MAAM,gBAAgB,OAAO,IAAI;AACzC,UAAM,UAAkC;AAAA,MACtC,gBAAgB;AAAA,MAChB,eAAe,UAAU,KAAK,MAAM;AAAA,IACtC;AACA,QAAI,eAAgB,SAAQ,iBAAiB,IAAI;AACjD,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,SAAS,GAAG,IAAI,IAAI;AAAA,MAClD,QAAQ,WAAW,OAAO,SAAS;AAAA,MACnC;AAAA,MACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AACD,WAAO,KAAK,eAAkB,GAAG;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,YACZ,MACA,UAAsD,CAAC,GAC3C;AACZ,UAAM,EAAE,MAAM,OAAO,IAAI;AACzB,UAAM,UAAkC;AAAA,MACtC,gBAAgB;AAAA,IAClB;AACA,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,SAAS,GAAG,IAAI,IAAI;AAAA,MAClD,QAAQ,WAAW,OAAO,SAAS;AAAA,MACnC;AAAA,MACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AACD,WAAO,KAAK,eAAkB,GAAG;AAAA,EACnC;AAAA,EAEA,MAAc,eAAkB,KAA2B;AACzD,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,QAAI,OAAgB;AACpB,QAAI;AACF,aAAO,OAAO,KAAK,MAAM,IAAI,IAAI;AAAA,IACnC,QAAQ;AACN,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,UAAU;AAChB,YAAM,UAAW,WAAW,OAAO,QAAQ,UAAU,WACjD,QAAQ,QACR,8BAA8B,IAAI,MAAM;AAE5C,cAAQ,IAAI,QAAQ;AAAA,QAClB,KAAK;AACH,gBAAM,IAAI,sBAAsB,SAAS,IAAI;AAAA,QAC/C,KAAK;AACH,gBAAM,IAAI,wBAAwB,SAAS,IAAI;AAAA,QACjD,KAAK;AACH,gBAAM,IAAI,qBAAqB,SAAS,IAAI;AAAA,QAC9C,KAAK;AACH,gBAAM,IAAI,oBAAoB,SAAS,IAAI;AAAA,QAC7C;AACE,cAAI,IAAI,UAAU,KAAK;AACrB,kBAAM,IAAI,kBAAkB,SAAS,IAAI,QAAQ,IAAI;AAAA,UACvD;AACA,gBAAM,IAAI,YAAY,SAAS,IAAI,QAAQ,QAAW,IAAI;AAAA,MAC9D;AAAA,IACF;AAEA,WAAQ,QAAQ;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,OAAO,QAQe;AAC1B,UAAM,iBAAiB,OAAO,kBAAkB,uBAAuB;AACvE,UAAM,OAAsB;AAAA,MAC1B,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,MACvB,aAAa,OAAO;AAAA,MACpB,UAAU,OAAO;AAAA,MACjB,aAAa,OAAO;AAAA,MACpB,SAAS,OAAO;AAAA,MAChB,UAAU,OAAO;AAAA,IACnB;AACA,WAAO,KAAK,YAA4B,cAAc;AAAA,MACpD,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAgB,UAAiD;AACrE,WAAO,KAAK,YAAkC,cAAc,QAAQ,IAAI;AAAA,MACtE,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,gBAAgB,QAYe;AACnC,UAAM,OAA+B;AAAA,MACnC,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,MACvB,WAAW,OAAO,aAAa,CAAC;AAAA,MAChC,MAAM,OAAO;AAAA,MACb,aAAa,OAAO;AAAA,MACpB,SAAS;AAAA,QACP,kBAAkB,OAAO,SAAS,oBAAoB;AAAA,QACtD,wBAAwB,OAAO,SAAS,0BAA0B;AAAA,MACpE;AAAA,IACF;AACA,UAAM,MAAM,MAAM,KAAK,YAQpB,mBAAmB,EAAE,QAAQ,QAAQ,MAAM,KAAK,CAAC;AACpD,WAAO;AAAA,MACL,eAAe,IAAI;AAAA,MACnB,KAAK,IAAI,IAAI,WAAW,MAAM,IAAI,IAAI,MAAM,GAAG,KAAK,SAAS,GAAG,IAAI,GAAG;AAAA,MACvE,QAAQ,IAAI;AAAA,MACZ,MAAM,IAAI;AAAA,MACV,aAAa,IAAI;AAAA,MACjB,WAAW,IAAI;AAAA,MACf,mBAAmB,IAAI,qBAAqB;AAAA,QAC1C,QAAQ;AAAA,QACR,eAAe;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAe,QAEe;AAClC,UAAM,OAAO,mBAAmB,IAAI,gBAAgB;AAAA,MAClD,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,IACzB,CAAC,EAAE,SAAS,CAAC;AACb,WAAO,KAAK,YAAoC,MAAM,EAAE,QAAQ,MAAM,CAAC;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,QAGe;AAChC,UAAM,OAAO,mBAAmB,OAAO,QAAQ,IAAI,IAAI,gBAAgB;AAAA,MACrE,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,IACzB,CAAC,EAAE,SAAS,CAAC;AACb,WAAO,KAAK,YAAkC,MAAM,EAAE,QAAQ,MAAM,CAAC;AAAA,EACvE;AAAA,EAEA,MAAM,gBAAgB,QAOY;AAChC,UAAM,OAA+B;AAAA,MACnC,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,MACvB,mBAAmB,OAAO;AAAA,IAC5B;AAEA,WAAO,KAAK,YAAkC,mBAAmB,OAAO,QAAQ,IAAI;AAAA,MAClF,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,iBAAiB,QAGe;AACpC,UAAM,OAAgC;AAAA,MACpC,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,IACzB;AACA,UAAM,MAAM,MAAM,KAAK;AAAA,MACrB,mBAAmB,OAAO,QAAQ;AAAA,MAClC,EAAE,QAAQ,QAAQ,MAAM,KAAK;AAAA,IAC/B;AACA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,KAAK,IAAI,IAAI,WAAW,MAAM,IAAI,IAAI,MAAM,GAAG,KAAK,SAAS,GAAG,IAAI,GAAG;AAAA,IACzE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,qBAAqB,QAGe;AACxC,WAAO,KAAK;AAAA,MACV,mBAAmB,OAAO,QAAQ;AAAA,MAClC;AAAA,QACE,QAAQ;AAAA,QACR,MAAM,EAAE,QAAQ,KAAK,OAAO,gBAAgB,OAAO,eAAe;AAAA,MACpE;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,eAAe,QAEY;AAC/B,UAAM,OAAO,oBAAoB,IAAI,gBAAgB;AAAA,MACnD,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,IACzB,CAAC,EAAE,SAAS,CAAC;AACb,WAAO,KAAK,YAAiC,MAAM,EAAE,QAAQ,MAAM,CAAC;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAgB,QAEY;AAChC,UAAM,OAAO,oBAAoB,IAAI,gBAAgB;AAAA,MACnD,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,IACzB,CAAC,EAAE,SAAS,CAAC;AACb,WAAO,KAAK,YAAkC,MAAM,EAAE,QAAQ,MAAM,CAAC;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,QAEe;AAC9B,UAAM,OAAO,cAAc,IAAI,gBAAgB;AAAA,MAC7C,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,IACzB,CAAC,EAAE,SAAS,CAAC;AACb,WAAO,KAAK,YAAgC,MAAM,EAAE,QAAQ,MAAM,CAAC;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,QAGe;AAC5B,UAAM,OAAO,cAAc,mBAAmB,OAAO,QAAQ,CAAC,IAAI,IAAI,gBAAgB;AAAA,MACpF,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,IACzB,CAAC,EAAE,SAAS,CAAC;AACb,WAAO,KAAK,YAA8B,MAAM,EAAE,QAAQ,MAAM,CAAC;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,YAAY,QAKe;AAC/B,UAAM,OAAO;AAAA,MACX,GAAG,OAAO;AAAA,MACV,sBAAsB,OAAO,KAAK,wBAAwB,CAAC,KAAK;AAAA,IAClE;AACA,UAAM,OAA2B;AAAA,MAC/B,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,MACvB;AAAA,MACA,YAAY,OAAO;AAAA,MACnB,aAAa,OAAO;AAAA,IACtB;AACA,WAAO,KAAK,YAAiC,cAAc;AAAA,MACzD,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,YAAY,QAUe;AAC/B,UAAM,EAAE,UAAU,gBAAgB,GAAG,MAAM,IAAI;AAC/C,UAAM,OAAgC,CAAC;AACvC,QAAI,MAAM,SAAS,OAAW,MAAK,OAAO,MAAM;AAChD,QAAI,MAAM,gBAAgB,OAAW,MAAK,cAAc,MAAM;AAC9D,QAAI,MAAM,kBAAkB,OAAW,MAAK,gBAAgB,MAAM;AAClE,QAAI,MAAM,kBAAkB,OAAW,MAAK,gBAAgB,MAAM;AAClE,QAAI,MAAM,eAAe,OAAW,MAAK,aAAa,MAAM;AAC5D,QAAI,MAAM,eAAe,OAAW,MAAK,aAAa,MAAM;AAC5D,QAAI,MAAM,yBAAyB,OAAW,MAAK,uBAAuB,MAAM;AAEhF,UAAM,OAAO,cAAc,mBAAmB,QAAQ,CAAC,IAAI,IAAI,gBAAgB;AAAA,MAC7E,QAAQ,KAAK;AAAA,MACb;AAAA,IACF,CAAC,EAAE,SAAS,CAAC;AACb,WAAO,KAAK,YAAiC,MAAM;AAAA,MACjD,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,QAGgB;AAChC,UAAM,OAAO,cAAc,mBAAmB,OAAO,QAAQ,CAAC,IAAI,IAAI,gBAAgB;AAAA,MACpF,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,IACzB,CAAC,EAAE,SAAS,CAAC;AACb,WAAO,KAAK,YAAkC,MAAM,EAAE,QAAQ,SAAS,CAAC;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,oBAAoB,QAIL;AACnB,UAAM,OAAO;AAAA,MACX,YAAY,OAAO;AAAA,MACnB,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,MACvB,iBAAiB,OAAO;AAAA,IAC1B;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,YAAgC,+BAA+B;AAAA,QACzF,QAAQ;AAAA,QACR,MAAM;AAAA,MACR,CAAC;AAED,aAAO,SAAS;AAAA,IAClB,SAAS,OAAY;AAEnB,cAAQ,MAAM,8CAA8C,KAAK;AACjE,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,aAAa,QAEe;AAChC,UAAM,QAAQ,IAAI,gBAAgB;AAAA,MAChC,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,IACzB,CAAC;AAED,WAAO,KAAK,YAAkC,gBAAgB,MAAM,SAAS,CAAC,IAAI;AAAA,MAChF,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cAAc,QAee;AACjC,UAAM,OAA6B;AAAA,MACjC,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,MACvB,aAAa,OAAO;AAAA,MACpB,gBAAgB,OAAO;AAAA,MACvB,OAAO,OAAO;AAAA,MACd,oBAAoB,OAAO;AAAA,MAC3B,UAAU,OAAO;AAAA,MACjB,kBAAkB,OAAO;AAAA,MACzB,qBAAqB,OAAO;AAAA,MAC5B,cAAc,OAAO;AAAA,MACrB,cAAc,OAAO;AAAA,MACrB,aAAa,OAAO;AAAA,MACpB,cAAc,OAAO;AAAA,MACrB,UAAU,OAAO;AAAA,IACnB;AAEA,WAAO,KAAK,YAAmC,gBAAgB;AAAA,MAC7D,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,gBAAgB,OAAO;AAAA,IACzB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,kBAAkB,QAGG;AACzB,UAAM,WAAW,MAAM,KAAK,aAAa,EAAE,gBAAgB,OAAO,eAAe,CAAC;AAClF,UAAM,UAAU,SAAS,SAAS,KAAK,CAAC,MAAM,EAAE,eAAe,OAAO,UAAU;AAEhF,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,oBAAoB,sBAAsB,OAAO,UAAU,EAAE;AAAA,IACzE;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cAAc,QAce;AACjC,UAAM,OAA6B;AAAA,MACjC,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,MACvB,aAAa,OAAO;AAAA,MACpB,OAAO,OAAO;AAAA,MACd,cAAc,OAAO;AAAA,MACrB,cAAc,OAAO;AAAA,MACrB,aAAa,OAAO;AAAA,MACpB,oBAAoB,OAAO;AAAA,MAC3B,UAAU,OAAO;AAAA,MACjB,kBAAkB,OAAO;AAAA,MACzB,cAAc,OAAO;AAAA,MACrB,QAAQ,OAAO;AAAA,MACf,UAAU,OAAO;AAAA,IACnB;AAEA,WAAO,KAAK,YAAmC,gBAAgB,OAAO,UAAU,IAAI;AAAA,MAClF,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,QAGe;AACjC,UAAM,QAAQ,IAAI,gBAAgB;AAAA,MAChC,QAAQ,KAAK;AAAA,MACb,gBAAgB,OAAO;AAAA,IACzB,CAAC;AAED,WAAO,KAAK;AAAA,MACV,gBAAgB,mBAAmB,OAAO,UAAU,CAAC,IAAI,MAAM,SAAS,CAAC;AAAA,MACzE,EAAE,QAAQ,SAAS;AAAA,IACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,oBAAoB,QAIe;AACvC,UAAM,MAAM,MAAM,KAAK;AAAA,MACrB;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,QAAQ,KAAK;AAAA,UACb,gBAAgB,OAAO;AAAA,UACvB,aAAa,OAAO;AAAA,UACpB,KAAK,OAAO;AAAA,QACd;AAAA,MACF;AAAA,IACF;AACA,WAAO,EAAE,OAAO,IAAI,OAAO,WAAW,IAAI,WAAW;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,YAAY,QAAyD;AACzE,UAAM,iBACJ,OAAO,cAAc,YAAY,OAAO,cAAc,WAClD,OAAO,iBACP;AAEN,WAAO,KAAK,YAAiC,qBAAqB;AAAA,MAChE,QAAQ;AAAA,MACR,MAAM;AAAA,QACJ,GAAG;AAAA,QACH,QAAQ,KAAK;AAAA,MACf;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,2BACZ,cACwB;AACxB,UAAM,SAAS,MAAM,KAAK,YAAY;AAAA,MACpC,WAAW;AAAA,MACX,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,IACpB,CAAC;AAED,UAAM,SAAS,OAAO,UAAU,CAAC,GAAG;AAAA,MAClC,CAAC,UAAU,MAAM,SAAS;AAAA,IAC5B;AAEA,WAAO,OAAO,YAAY;AAAA,EAC5B;AAAA,EAEQ,4BACN,OACgC;AAChC,WAAO,MACJ,OAAO,CAAC,SAAS,KAAK,KAAK,WAAW,aAAa,KAAK,KAAK,KAAK,SAAS,KAAK,CAAC,EACjF,IAAI,CAAC,SAAS;AACb,YAAM,UAAU,KAAK,WAAW;AAChC,YAAM,aAAa,QAAQ,QAAQ,SAAS,IAAI;AAEhD,UAAI,WAAW,WAAW,OAAO,GAAG;AAClC,cAAM,WAAW,WAAW,QAAQ,WAAW,CAAC;AAChD,YAAI,aAAa,IAAI;AACnB,gBAAM,cAAc,WAAW,MAAM,GAAG,QAAQ;AAChD,gBAAM,WAAmC,CAAC;AAC1C,qBAAW,QAAQ,YAAY,MAAM,IAAI,GAAG;AAC1C,kBAAM,iBAAiB,KAAK,QAAQ,GAAG;AACvC,gBAAI,mBAAmB,GAAI;AAC3B,kBAAM,MAAM,KAAK,MAAM,GAAG,cAAc,EAAE,KAAK;AAC/C,kBAAM,QAAQ,KAAK,MAAM,iBAAiB,CAAC,EAAE,KAAK;AAClD,gBAAI,OAAO,OAAO;AAChB,uBAAS,GAAG,IAAI;AAAA,YAClB;AAAA,UACF;AAEA,iBAAO;AAAA,YACL,OAAO,SAAS,UAAU,KAAK,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK,KAAK;AAAA,YAC7D,aAAa,SAAS,eAAe;AAAA,YACrC,MAAM,KAAK;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAEA,YAAM,QAAQ,QAAQ,MAAM,OAAO;AACnC,YAAM,YAAY,MAAM,KAAK,CAAC,SAAS,KAAK,WAAW,IAAI,CAAC;AAC5D,YAAM,QAAQ,YAAY,UAAU,QAAQ,SAAS,EAAE,EAAE,KAAK,IAAI,KAAK,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK,KAAK;AACrG,YAAM,cACJ,MACG,MAAM,CAAC,EACP,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,KAAK,CAAC,SAAS,KAAK,SAAS,KAAK,CAAC,KAAK,WAAW,GAAG,CAAC,KAAK;AAEjE,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,MAAM,KAAK;AAAA,MACb;AAAA,IACF,CAAC,EACA,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAAA,EAChD;AAAA,EAEA,MAAM,gBAAgB,QAEmB;AACvC,UAAM,UAAU,MAAM,KAAK,2BAA2B,OAAO,cAAc;AAC3E,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,QACL,UAAU;AAAA,QACV,YAAY,CAAC;AAAA,MACf;AAAA,IACF;AAEA,UAAM,aAAa,MAAM,KAAK,YAAY;AAAA,MACxC,WAAW;AAAA,MACX,gBAAgB,OAAO;AAAA,MACvB,UAAU;AAAA,MACV,MAAM;AAAA,IACR,CAAC;AAED,UAAM,kBAAkB,WAAW,QAAQ,CAAC,GACzC,OAAO,CAAC,SAAS,KAAK,SAAS,UAAU,KAAK,KAAK,WAAW,aAAa,KAAK,KAAK,KAAK,SAAS,KAAK,CAAC,EACzG,IAAI,CAAC,SAAS,KAAK,IAAI;AAE1B,QAAI,eAAe,WAAW,GAAG;AAC/B,aAAO;AAAA,QACL,UAAU;AAAA,QACV,YAAY,CAAC;AAAA,MACf;AAAA,IACF;AAEA,UAAM,cAAc,MAAM,KAAK,YAAY;AAAA,MACzC,WAAW;AAAA,MACX,gBAAgB,OAAO;AAAA,MACvB,UAAU;AAAA,MACV,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,IACf,CAAC;AAED,WAAO;AAAA,MACL,UAAU;AAAA,MACV,YAAY,KAAK,4BAA4B,YAAY,SAAS,CAAC,CAAC;AAAA,IACtE;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,QAGe;AACpC,UAAM,UAAU,MAAM,KAAK,2BAA2B,OAAO,cAAc;AAC3E,UAAM,gBAAgB,OAAO,MAAM,KAAK,KAAK;AAE7C,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,IACF;AAEA,QAAI,kBAAkB,YAAY;AAChC,YAAMA,UAAS,MAAM,KAAK,YAAY;AAAA,QACpC,WAAW;AAAA,QACX,gBAAgB,OAAO;AAAA,QACvB,UAAU;AAAA,QACV,MAAM;AAAA,MACR,CAAC;AAED,aAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM;AAAA,QACN,SAASA,QAAO,gBAAgB;AAAA,MAClC;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,KAAK,YAAY;AAAA,MACpC,WAAW;AAAA,MACX,gBAAgB,OAAO;AAAA,MACvB,UAAU;AAAA,MACV,MAAM;AAAA,MACN,OAAO,CAAC,aAAa;AAAA,MACrB,aAAa;AAAA,IACf,CAAC;AAED,UAAM,QAAQ,OAAO,SAAS,CAAC,GAAG,KAAK,CAAC,UAAU,MAAM,SAAS,aAAa;AAE9E,WAAO;AAAA,MACL,UAAU;AAAA,MACV,MAAM;AAAA,MACN,SAAS,MAAM,WAAW;AAAA,IAC5B;AAAA,EACF;AACF;;;ACr3BO,SAAS,oBACd,gBACA,cACS;AAET,MAAI,CAAC,kBAAkB,CAAC,cAAc;AACpC,WAAO;AAAA,EACT;AAGA,MAAI,eAAe,WAAW,aAAa,QAAQ;AACjD,WAAO;AAAA,EACT;AAEA,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK;AAC9C,cAAU,eAAe,WAAW,CAAC,IAAI,aAAa,WAAW,CAAC;AAAA,EACpE;AAEA,SAAO,WAAW;AACpB;","names":["result"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/utils.ts","../src/client.ts","../src/webhook-verification.ts"],"sourcesContent":["/**\n * Base error for Kronos API failures\n */\nexport class KronosError extends Error {\n constructor(\n message: string,\n public readonly status?: number,\n public readonly code?: string,\n public readonly body?: unknown\n ) {\n super(message);\n this.name = 'KronosError';\n Object.setPrototypeOf(this, KronosError.prototype);\n }\n}\n\n/**\n * 400 Bad Request - invalid or missing parameters\n */\nexport class KronosBadRequestError extends KronosError {\n constructor(message: string, body?: unknown) {\n super(message, 400, 'bad_request', body);\n this.name = 'KronosBadRequestError';\n Object.setPrototypeOf(this, KronosBadRequestError.prototype);\n }\n}\n\n/**\n * 401 Unauthorized - invalid or missing API key\n */\nexport class KronosUnauthorizedError extends KronosError {\n constructor(message: string, body?: unknown) {\n super(message, 401, 'unauthorized', body);\n this.name = 'KronosUnauthorizedError';\n Object.setPrototypeOf(this, KronosUnauthorizedError.prototype);\n }\n}\n\n/**\n * 403 Forbidden - valid auth but insufficient permissions\n */\nexport class KronosForbiddenError extends KronosError {\n constructor(message: string, body?: unknown) {\n super(message, 403, 'forbidden', body);\n this.name = 'KronosForbiddenError';\n Object.setPrototypeOf(this, KronosForbiddenError.prototype);\n }\n}\n\n/**\n * 404 Not Found - resource does not exist\n */\nexport class KronosNotFoundError extends KronosError {\n constructor(message: string, body?: unknown) {\n super(message, 404, 'not_found', body);\n this.name = 'KronosNotFoundError';\n Object.setPrototypeOf(this, KronosNotFoundError.prototype);\n }\n}\n\n/**\n * 5xx or network/unknown errors\n */\nexport class KronosServerError extends KronosError {\n constructor(message: string, status?: number, body?: unknown) {\n super(message, status, 'server_error', body);\n this.name = 'KronosServerError';\n Object.setPrototypeOf(this, KronosServerError.prototype);\n }\n}\n","/**\n * Generate an idempotency key for ingest requests.\n * Uses crypto.randomUUID() when available; falls back to a timestamp-based value.\n * Callers can pass their own key via the ingest options to achieve true idempotency.\n */\nexport function generateIdempotencyKey(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return `idem_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;\n}\n","import type {\n KronosClientConfig,\n IngestRequest,\n IngestResponse,\n IngestStatusResponse,\n CreateMCPServerRequest,\n CreateMCPServerResponse,\n UpdateMCPServerRequest,\n ListMCPServersResponse,\n GetMCPServerResponse,\n ConnectMCPServerRequest,\n ConnectMCPServerResponse,\n RotateMCPServerTokenResponse,\n MemoryStatsResponse,\n ScratchsheetResponse,\n ListScopesResponse,\n GetScopeResponse,\n CreateScopeRequest,\n CreateScopeResponse,\n UpdateScopeResponse,\n CreateTriggerRequest,\n CreateTriggerResponse,\n CreateFrontendTokenResponse,\n ListTriggersResponse,\n ScopeSpec,\n UpdateTriggerRequest,\n UpdateTriggerResponse,\n DeleteTriggerResponse,\n TriggerRecord,\n SkillManageParams,\n SkillManageResponse,\n ContextGraphSummaryResponse,\n ContextGraphReadResponse,\n ContextGraphProcedureSummary,\n} from './types';\nimport {\n KronosError,\n KronosBadRequestError,\n KronosUnauthorizedError,\n KronosForbiddenError,\n KronosNotFoundError,\n KronosServerError,\n} from './errors';\nimport { generateIdempotencyKey } from './utils';\n\nconst PRODUCTION_WORKER_URL = 'https://api.kronos.ai';\nconst PRODUCTION_MASTRA_URL = 'https://mastra.kronos.ai';\nconst DEV_WORKER_URL = 'http://localhost:8787';\nconst DEV_MASTRA_URL = 'http://localhost:4111';\nconst INTERNAL_CONTEXT_GRAPH_SKILL_NAME = '__internal_context_graph__';\n\nfunction defaultWorkerUrl(): string {\n return process.env.NODE_ENV === 'production' ? PRODUCTION_WORKER_URL : DEV_WORKER_URL;\n}\nfunction defaultMastraUrl(): string {\n return process.env.NODE_ENV === 'production' ? PRODUCTION_MASTRA_URL : DEV_MASTRA_URL;\n}\n\nexport class KronosClient {\n private readonly workerUrl: string;\n private readonly mastraUrl: string;\n private readonly apiKey: string;\n private readonly appId: string;\n\n constructor(config: KronosClientConfig) {\n if (!config.apiKey) {\n throw new Error('KronosClient: apiKey is required in constructor');\n }\n if (!config.appId) {\n throw new Error('KronosClient: appId is required in constructor');\n }\n this.workerUrl = (config.workerUrl ?? process.env.KRONOS_WORKER_URL ?? defaultWorkerUrl()).replace(/\\/$/, '');\n this.mastraUrl = (config.mastraUrl ?? process.env.KRONOS_MASTRA_URL ?? defaultMastraUrl()).replace(/\\/$/, '');\n this.apiKey = config.apiKey;\n this.appId = config.appId;\n \n console.log('[KronosClient] ✅ KronosClient initialized:', {\n appId: this.appId,\n workerUrl: this.workerUrl,\n mastraUrl: this.mastraUrl,\n hasApiKey: !!this.apiKey,\n });\n \n // Perform async health check (fire and forget)\n this.healthCheck().catch(() => {\n // Health check failed, but don't block initialization\n });\n }\n \n /**\n * Perform a health check to verify the client can connect to the Kronos worker\n * This is called automatically during initialization\n */\n private async healthCheck(): Promise<void> {\n try {\n const response = await fetch(`${this.workerUrl}/health`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n \n if (response.ok) {\n const data = await response.json();\n if (data.status === 'ok') {\n console.log('[KronosClient] ✅ Health check passed - Client is connected and working');\n } else {\n console.warn('[KronosClient] ⚠️ Health check returned unexpected status:', data);\n }\n } else {\n console.warn(`[KronosClient] ⚠️ Health check failed with status ${response.status}. Client may not be working correctly.`);\n }\n } catch (error: any) {\n console.warn('[KronosClient] ⚠️ Health check failed - Unable to connect to Kronos worker:', error.message);\n console.warn('[KronosClient] Please verify that:');\n console.warn('[KronosClient] 1. The worker URL is correct:', this.workerUrl);\n console.warn('[KronosClient] 2. The worker is running and accessible');\n console.warn('[KronosClient] 3. Network connectivity is available');\n }\n }\n\n // ---------------------------------------------------------------------------\n // Worker request helper (uses Bearer auth)\n // ---------------------------------------------------------------------------\n private async workerFetch<T>(\n path: string,\n options: { method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; json?: object; idempotencyKey?: string } = {}\n ): Promise<T> {\n const { json, idempotencyKey, method } = options;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n };\n if (idempotencyKey) headers['Idempotency-Key'] = idempotencyKey;\n const res = await fetch(`${this.workerUrl}${path}`, {\n method: method ?? (json ? 'POST' : 'GET'),\n headers,\n body: json ? JSON.stringify(json) : undefined,\n });\n return this.handleResponse<T>(res);\n }\n\n // ---------------------------------------------------------------------------\n // Mastra request helper (no Bearer auth per current API)\n // ---------------------------------------------------------------------------\n private async mastraFetch<T>(\n path: string,\n options: { method?: 'GET' | 'POST'; json?: object } = {}\n ): Promise<T> {\n const { json, method } = options;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n const res = await fetch(`${this.mastraUrl}${path}`, {\n method: method ?? (json ? 'POST' : 'GET'),\n headers,\n body: json ? JSON.stringify(json) : undefined,\n });\n return this.handleResponse<T>(res);\n }\n\n private async handleResponse<T>(res: Response): Promise<T> {\n const text = await res.text();\n let body: unknown = null;\n try {\n body = text ? JSON.parse(text) : null;\n } catch {\n body = text;\n }\n\n if (!res.ok) {\n const errBody = body as { error?: string } | null;\n const message = (errBody && typeof errBody.error === 'string')\n ? errBody.error\n : `Request failed with status ${res.status}`;\n\n switch (res.status) {\n case 400:\n throw new KronosBadRequestError(message, body);\n case 401:\n throw new KronosUnauthorizedError(message, body);\n case 403:\n throw new KronosForbiddenError(message, body);\n case 404:\n throw new KronosNotFoundError(message, body);\n default:\n if (res.status >= 500) {\n throw new KronosServerError(message, res.status, body);\n }\n throw new KronosError(message, res.status, undefined, body);\n }\n }\n\n return (body ?? null) as T;\n }\n\n // ---------------------------------------------------------------------------\n // Ingest API\n // ---------------------------------------------------------------------------\n\n /**\n * Submit a document for ingestion.\n * @param params - source_type, content, optional metadata, addToMemory, and idempotencyKey\n * @returns ingest_id\n */\n async ingest(params: {\n tenant_user_id: string;\n source_type: string;\n priority?: 'low' | 'medium' | 'high';\n addToMemory?: boolean;\n content: { type: 'text'; text: string };\n metadata?: Record<string, unknown>;\n idempotencyKey?: string;\n }): Promise<IngestResponse> {\n const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();\n const body: IngestRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n source_type: params.source_type,\n priority: params.priority,\n addToMemory: params.addToMemory,\n content: params.content,\n metadata: params.metadata,\n };\n return this.workerFetch<IngestResponse>('/v1/ingest', {\n method: 'POST',\n json: body,\n idempotencyKey,\n });\n }\n\n /**\n * Get the status of an ingest.\n */\n async getIngestStatus(ingestId: string): Promise<IngestStatusResponse> {\n return this.workerFetch<IngestStatusResponse>(`/v1/ingest/${ingestId}`, {\n method: 'GET',\n });\n }\n\n // ---------------------------------------------------------------------------\n // MCP Server API\n // ---------------------------------------------------------------------------\n\n /**\n * Create an MCP server scoped to the given scopes.\n * Use connectMCPServer() to get a short-lived access token for MCP auth.\n */\n async createMCPServer(params: {\n tenant_user_id: string;\n name: string;\n /** Omit or pass [] for all-memory access. */\n scope_ids?: string[] | null;\n description?: string;\n options?: {\n /** Expose `search_skills` and `read_skill`. Defaults to true. */\n exposeSkillsTool?: boolean;\n /** Expose the read-only `context_graph` tool. Defaults to false. */\n exposeContextGraphTool?: boolean;\n };\n }): Promise<CreateMCPServerResponse> {\n const body: CreateMCPServerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n scope_ids: params.scope_ids ?? [],\n name: params.name,\n description: params.description,\n options: {\n exposeSkillsTool: params.options?.exposeSkillsTool ?? true,\n exposeContextGraphTool: params.options?.exposeContextGraphTool ?? false,\n },\n };\n const res = await this.workerFetch<{\n mcp_server_id: string;\n url: string;\n status: 'active' | 'disabled';\n name: string;\n description: string | null;\n scope_ids: string[];\n tool_capabilities: { skills: boolean; context_graph: boolean };\n }>('/v1/mcp-servers', { method: 'POST', json: body });\n return {\n mcp_server_id: res.mcp_server_id,\n url: res.url.startsWith('http') ? res.url : `${this.workerUrl}${res.url}`,\n status: res.status,\n name: res.name,\n description: res.description,\n scope_ids: res.scope_ids,\n tool_capabilities: res.tool_capabilities ?? {\n skills: true,\n context_graph: false,\n },\n };\n }\n\n /**\n * List MCP servers for a user. Returns metadata only (no token).\n */\n async listMCPServers(params: {\n tenant_user_id: string;\n }): Promise<ListMCPServersResponse> {\n const path = `/v1/mcp-servers?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<ListMCPServersResponse>(path, { method: 'GET' });\n }\n\n /**\n * Get MCP server details for a user by server ID. Returns metadata only (no token).\n */\n async getMCPServer(params: {\n tenant_user_id: string;\n serverId: string;\n }): Promise<GetMCPServerResponse> {\n const path = `/v1/mcp-servers/${params.serverId}?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<GetMCPServerResponse>(path, { method: 'GET' });\n }\n\n async updateMCPServer(params: {\n tenant_user_id: string;\n serverId: string;\n tool_capabilities: {\n skills: boolean;\n context_graph: boolean;\n };\n }): Promise<GetMCPServerResponse> {\n const body: UpdateMCPServerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n tool_capabilities: params.tool_capabilities,\n };\n\n return this.workerFetch<GetMCPServerResponse>(`/v1/mcp-servers/${params.serverId}`, {\n method: 'PUT',\n json: body,\n });\n }\n\n /**\n * Connect to an MCP server by ID and receive a short-lived access token.\n * Use the returned access_token as Bearer token when calling the MCP endpoint.\n */\n async connectMCPServer(params: {\n tenant_user_id: string;\n serverId: string;\n }): Promise<ConnectMCPServerResponse> {\n const body: ConnectMCPServerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n };\n const res = await this.workerFetch<ConnectMCPServerResponse>(\n `/v1/mcp-servers/${params.serverId}/connect`,\n { method: 'POST', json: body }\n );\n return {\n ...res,\n url: res.url.startsWith('http') ? res.url : `${this.workerUrl}${res.url}`,\n };\n }\n\n /**\n * Rotate the token for an MCP server. The new token is returned only on rotate.\n */\n async rotateMCPServerToken(params: {\n tenant_user_id: string;\n serverId: string;\n }): Promise<RotateMCPServerTokenResponse> {\n return this.workerFetch<RotateMCPServerTokenResponse>(\n `/v1/mcp-servers/${params.serverId}/rotate-token`,\n {\n method: 'POST',\n json: { app_id: this.appId, tenant_user_id: params.tenant_user_id },\n }\n );\n }\n\n /**\n * Get memory stats for a user (total claim count across entire memory graph).\n * Worker caches the response for 5 minutes per user.\n */\n async getMemoryStats(params: {\n tenant_user_id: string;\n }): Promise<MemoryStatsResponse> {\n const path = `/v1/memory-stats?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<MemoryStatsResponse>(path, { method: 'GET' });\n }\n\n /**\n * Read the current scratchsheet document for a user.\n */\n async getScratchsheet(params: {\n tenant_user_id: string;\n }): Promise<ScratchsheetResponse> {\n const path = `/v1/scratchsheet?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<ScratchsheetResponse>(path, { method: 'GET' });\n }\n\n /**\n * List scopes for a user. Returns full scope details. Cached 5 min per user.\n */\n async listScopes(params: {\n tenant_user_id: string;\n }): Promise<ListScopesResponse> {\n const path = `/v1/scopes?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<ListScopesResponse>(path, { method: 'GET' });\n }\n\n /**\n * Get a single scope by ID. Returns full scope details.\n */\n async getScope(params: {\n tenant_user_id: string;\n scope_id: string;\n }): Promise<GetScopeResponse> {\n const path = `/v1/scopes/${encodeURIComponent(params.scope_id)}?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<GetScopeResponse>(path, { method: 'GET' });\n }\n\n // ---------------------------------------------------------------------------\n // Scope API (Mastra)\n // ---------------------------------------------------------------------------\n\n /**\n * Create a scope. A backfill job runs asynchronously to populate it.\n * If spec.allowed_source_types is omitted, it defaults to ['all'].\n * Uses the Worker so the scopes list cache is invalidated after create.\n */\n async createScope(params: {\n tenant_user_id: string;\n spec: ScopeSpec;\n created_by: string;\n description?: string;\n }): Promise<CreateScopeResponse> {\n const spec = {\n ...params.spec,\n allowed_source_types: params.spec.allowed_source_types ?? ['all'],\n };\n const body: CreateScopeRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n spec,\n created_by: params.created_by,\n description: params.description,\n };\n return this.workerFetch<CreateScopeResponse>('/v1/scopes', {\n method: 'POST',\n json: body,\n });\n }\n\n /**\n * Update a scope. Only provided fields are updated.\n * If include_query, exclude_query, match_mode, time_range, or allowed_source_types change,\n * a backfill job runs to recompute membership (response includes backfill_job_id).\n * Otherwise only DB and Neo4j metadata are updated.\n */\n async updateScope(params: {\n tenant_user_id: string;\n scope_id: string;\n name?: string;\n description?: string | null;\n include_query?: string;\n exclude_query?: string | null;\n match_mode?: 'strict' | 'broad';\n time_range?: { start?: string; end?: string };\n allowed_source_types?: string[] | 'all';\n }): Promise<UpdateScopeResponse> {\n const { scope_id, tenant_user_id, ...patch } = params;\n const body: Record<string, unknown> = {};\n if (patch.name !== undefined) body.name = patch.name;\n if (patch.description !== undefined) body.description = patch.description;\n if (patch.include_query !== undefined) body.include_query = patch.include_query;\n if (patch.exclude_query !== undefined) body.exclude_query = patch.exclude_query;\n if (patch.match_mode !== undefined) body.match_mode = patch.match_mode;\n if (patch.time_range !== undefined) body.time_range = patch.time_range;\n if (patch.allowed_source_types !== undefined) body.allowed_source_types = patch.allowed_source_types;\n\n const path = `/v1/scopes/${encodeURIComponent(scope_id)}?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id,\n }).toString()}`;\n return this.workerFetch<UpdateScopeResponse>(path, {\n method: 'PATCH',\n json: body,\n });\n }\n\n /**\n * Soft-delete a scope. Invalidates the scopes list cache for that user.\n */\n async deleteScope(params: {\n tenant_user_id: string;\n scope_id: string;\n }): Promise<{ deleted: boolean }> {\n const path = `/v1/scopes/${encodeURIComponent(params.scope_id)}?${new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n }).toString()}`;\n return this.workerFetch<{ deleted: boolean }>(path, { method: 'DELETE' });\n }\n\n // ---------------------------------------------------------------------------\n // Webhook Verification API (Worker)\n // ---------------------------------------------------------------------------\n\n /**\n * Verify a webhook secret for a trigger.\n * This method calls the Kronos worker API to verify the webhook secret.\n * \n * @param params - app_id, tenant_user_id, trigger_id and received_secret to verify\n * @returns true if secret is valid, false otherwise\n */\n async verifyWebhookSecret(params: {\n tenant_user_id: string;\n trigger_id: string;\n received_secret: string;\n }): Promise<boolean> {\n const body = {\n trigger_id: params.trigger_id,\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n received_secret: params.received_secret,\n };\n \n try {\n const response = await this.workerFetch<{ valid: boolean }>('/v1/triggers/verify-webhook', {\n method: 'POST',\n json: body,\n });\n \n return response.valid;\n } catch (error: any) {\n // If verification fails (e.g., trigger not found), return false\n console.error('[KronosClient] Webhook verification error:', error);\n return false;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Trigger Management API (Worker)\n // ---------------------------------------------------------------------------\n\n /**\n * List triggers for a tenant user.\n */\n async listTriggers(params: {\n tenant_user_id: string;\n }): Promise<ListTriggersResponse> {\n const query = new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n });\n \n return this.workerFetch<ListTriggersResponse>(`/v1/triggers?${query.toString()}`, {\n method: 'GET',\n });\n }\n\n /**\n * Create a trigger.\n * Supports NL creation (trigger_description) or manual creation (trigger_type/trigger_spec).\n *\n * @returns CreateTriggerResponse (accepted for NL, trigger_id for manual)\n */\n async createTrigger(params: {\n tenant_user_id: string;\n webhook_url: string;\n webhook_secret: string;\n title?: string | null;\n action_description?: string;\n skill_id?: string;\n skill_version_id?: string;\n trigger_description?: string;\n trigger_type?: CreateTriggerRequest['trigger_type'];\n trigger_spec?: CreateTriggerRequest['trigger_spec'];\n next_run_at?: string;\n on_triggered?: CreateTriggerRequest['on_triggered'];\n metadata?: Record<string, unknown>;\n idempotencyKey?: string;\n }): Promise<CreateTriggerResponse> {\n const body: CreateTriggerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n webhook_url: params.webhook_url,\n webhook_secret: params.webhook_secret,\n title: params.title,\n action_description: params.action_description,\n skill_id: params.skill_id,\n skill_version_id: params.skill_version_id,\n trigger_description: params.trigger_description,\n trigger_type: params.trigger_type,\n trigger_spec: params.trigger_spec,\n next_run_at: params.next_run_at,\n on_triggered: params.on_triggered,\n metadata: params.metadata,\n };\n\n return this.workerFetch<CreateTriggerResponse>('/v1/triggers', {\n method: 'POST',\n json: body,\n idempotencyKey: params.idempotencyKey,\n });\n }\n\n /**\n * Get details for a specific trigger.\n * Uses listTriggers and filters by trigger_id.\n */\n async getTriggerDetails(params: {\n tenant_user_id: string;\n trigger_id: string;\n }): Promise<TriggerRecord> {\n const response = await this.listTriggers({ tenant_user_id: params.tenant_user_id });\n const trigger = response.triggers.find((t) => t.trigger_id === params.trigger_id);\n\n if (!trigger) {\n throw new KronosNotFoundError(`Trigger not found: ${params.trigger_id}`);\n }\n\n return trigger;\n }\n\n /**\n * Update a trigger.\n * Updates the webhook_url, action_description, status, or metadata of an existing trigger.\n * \n * @param params - app_id, tenant_user_id, trigger_id and fields to update\n * @returns UpdateTriggerResponse with success status\n */\n async updateTrigger(params: {\n tenant_user_id: string;\n trigger_id: string;\n webhook_url?: string;\n title?: string | null;\n trigger_type?: UpdateTriggerRequest['trigger_type'];\n trigger_spec?: UpdateTriggerRequest['trigger_spec'];\n next_run_at?: UpdateTriggerRequest['next_run_at'];\n action_description?: string;\n skill_id?: string | null;\n skill_version_id?: string | null;\n on_triggered?: UpdateTriggerRequest['on_triggered'];\n status?: string;\n metadata?: Record<string, unknown>;\n }): Promise<UpdateTriggerResponse> {\n const body: UpdateTriggerRequest = {\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n webhook_url: params.webhook_url,\n title: params.title,\n trigger_type: params.trigger_type,\n trigger_spec: params.trigger_spec,\n next_run_at: params.next_run_at,\n action_description: params.action_description,\n skill_id: params.skill_id,\n skill_version_id: params.skill_version_id,\n on_triggered: params.on_triggered,\n status: params.status,\n metadata: params.metadata,\n };\n \n return this.workerFetch<UpdateTriggerResponse>(`/v1/triggers/${params.trigger_id}`, {\n method: 'PUT',\n json: body,\n });\n }\n\n /**\n * Delete a trigger.\n */\n async deleteTrigger(params: {\n tenant_user_id: string;\n trigger_id: string;\n }): Promise<DeleteTriggerResponse> {\n const query = new URLSearchParams({\n app_id: this.appId,\n tenant_user_id: params.tenant_user_id,\n });\n\n return this.workerFetch<DeleteTriggerResponse>(\n `/v1/triggers/${encodeURIComponent(params.trigger_id)}?${query.toString()}`,\n { method: 'DELETE' }\n );\n }\n\n // ---------------------------------------------------------------------------\n // Frontend Tokens (Server-side only)\n // ---------------------------------------------------------------------------\n\n /**\n * Issue a short-lived, user-scoped frontend token.\n * The browser can use this token directly against the Kronos worker for\n * allowed operations (e.g. trigger CRUD) without needing the app API key.\n *\n * This method must be called from a trusted server environment.\n */\n async createFrontendToken(params: {\n tenantUserId: string;\n ttlSeconds?: number;\n ops?: string[];\n }): Promise<CreateFrontendTokenResponse> {\n const res = await this.workerFetch<{ token: string; expires_at: string }>(\n '/v1/frontend-tokens',\n {\n method: 'POST',\n json: {\n app_id: this.appId,\n tenant_user_id: params.tenantUserId,\n ttl_seconds: params.ttlSeconds,\n ops: params.ops,\n },\n },\n );\n return { token: res.token, expiresAt: res.expires_at };\n }\n\n // ---------------------------------------------------------------------------\n // Skills API (Worker)\n // ---------------------------------------------------------------------------\n\n /**\n * Canonical skills API with operation-based contract.\n */\n async manageSkill(params: SkillManageParams): Promise<SkillManageResponse> {\n const idempotencyKey =\n params.operation === 'create' || params.operation === 'update'\n ? params.idempotencyKey\n : undefined;\n\n return this.workerFetch<SkillManageResponse>('/v1/skills/manage', {\n method: 'POST',\n json: {\n ...params,\n app_id: this.appId,\n },\n idempotencyKey,\n });\n }\n\n private async resolveContextGraphSkillId(\n tenantUserId: string\n ): Promise<string | null> {\n const listed = await this.manageSkill({\n operation: 'list',\n tenant_user_id: tenantUserId,\n include_internal: true,\n });\n\n const match = (listed.skills ?? []).find(\n (skill) => skill.name === INTERNAL_CONTEXT_GRAPH_SKILL_NAME\n );\n\n return match?.skill_id ?? null;\n }\n\n private parseContextGraphProcedures(\n files: Array<{ path: string; content?: string }>\n ): ContextGraphProcedureSummary[] {\n return files\n .filter((file) => file.path.startsWith('procedures/') && file.path.endsWith('.md'))\n .map((file) => {\n const content = file.content ?? '';\n const normalized = content.replace(/\\r\\n/g, '\\n');\n\n if (normalized.startsWith('---\\n')) {\n const endIndex = normalized.indexOf('\\n---\\n', 4);\n if (endIndex !== -1) {\n const frontmatter = normalized.slice(4, endIndex);\n const metadata: Record<string, string> = {};\n for (const line of frontmatter.split('\\n')) {\n const separatorIndex = line.indexOf(':');\n if (separatorIndex === -1) continue;\n const key = line.slice(0, separatorIndex).trim();\n const value = line.slice(separatorIndex + 1).trim();\n if (key && value) {\n metadata[key] = value;\n }\n }\n\n return {\n title: metadata.title || (file.path.split('/').pop() ?? file.path),\n description: metadata.description || '',\n path: file.path,\n };\n }\n }\n\n const lines = content.split(/\\r?\\n/);\n const titleLine = lines.find((line) => line.startsWith('# '));\n const title = titleLine ? titleLine.replace(/^#\\s+/, '').trim() : file.path.split('/').pop() ?? file.path;\n const description =\n lines\n .slice(1)\n .map((line) => line.trim())\n .find((line) => line.length > 0 && !line.startsWith('#')) ?? '';\n\n return {\n title,\n description,\n path: file.path,\n };\n })\n .sort((a, b) => a.path.localeCompare(b.path));\n }\n\n async getContextGraph(params: {\n tenant_user_id: string;\n }): Promise<ContextGraphSummaryResponse> {\n const skillId = await this.resolveContextGraphSkillId(params.tenant_user_id);\n if (!skillId) {\n return {\n skill_id: null,\n procedures: [],\n };\n }\n\n const treeResult = await this.manageSkill({\n operation: 'read',\n tenant_user_id: params.tenant_user_id,\n skill_id: skillId,\n mode: 'tree',\n });\n\n const procedurePaths = (treeResult.tree ?? [])\n .filter((node) => node.kind === 'file' && node.path.startsWith('procedures/') && node.path.endsWith('.md'))\n .map((node) => node.path);\n\n if (procedurePaths.length === 0) {\n return {\n skill_id: skillId,\n procedures: [],\n };\n }\n\n const filesResult = await this.manageSkill({\n operation: 'read',\n tenant_user_id: params.tenant_user_id,\n skill_id: skillId,\n mode: 'files',\n files: procedurePaths,\n fileContent: 'full',\n });\n\n return {\n skill_id: skillId,\n procedures: this.parseContextGraphProcedures(filesResult.files ?? []),\n };\n }\n\n async readContextGraph(params: {\n tenant_user_id: string;\n path?: string;\n }): Promise<ContextGraphReadResponse> {\n const skillId = await this.resolveContextGraphSkillId(params.tenant_user_id);\n const requestedPath = params.path?.trim() || 'SKILL.md';\n\n if (!skillId) {\n return {\n skill_id: null,\n path: requestedPath,\n content: null,\n };\n }\n\n if (requestedPath === 'SKILL.md') {\n const result = await this.manageSkill({\n operation: 'read',\n tenant_user_id: params.tenant_user_id,\n skill_id: skillId,\n mode: 'instructions',\n });\n\n return {\n skill_id: skillId,\n path: 'SKILL.md',\n content: result.instructions ?? null,\n };\n }\n\n const result = await this.manageSkill({\n operation: 'read',\n tenant_user_id: params.tenant_user_id,\n skill_id: skillId,\n mode: 'files',\n files: [requestedPath],\n fileContent: 'full',\n });\n\n const file = (result.files ?? []).find((entry) => entry.path === requestedPath);\n\n return {\n skill_id: skillId,\n path: requestedPath,\n content: file?.content ?? null,\n };\n }\n}\n","/**\n * Webhook verification utilities for Kronos triggers\n * Provides secure constant-time comparison for webhook secrets\n */\n\n/**\n * Verify a webhook secret using constant-time comparison to prevent timing attacks.\n * \n * @param receivedSecret - The secret received in the webhook header\n * @param storedSecret - The secret stored in the database for the trigger\n * @returns true if secrets match, false otherwise\n * \n * @example\n * ```typescript\n * import { verifyWebhookSecret } from '@gdrl/kronos-lib/webhook-verification';\n * \n * const isValid = verifyWebhookSecret(\n * request.headers.get('X-Kronos-Webhook-Secret'),\n * trigger.webhook_secret\n * );\n * \n * if (!isValid) {\n * return new Response('Unauthorized', { status: 401 });\n * }\n * ```\n */\nexport function verifyWebhookSecret(\n receivedSecret: string | null | undefined,\n storedSecret: string | null | undefined\n): boolean {\n // If either is missing, they don't match\n if (!receivedSecret || !storedSecret) {\n return false;\n }\n\n // Constant-time comparison to prevent timing attacks\n if (receivedSecret.length !== storedSecret.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < receivedSecret.length; i++) {\n result |= receivedSecret.charCodeAt(i) ^ storedSecret.charCodeAt(i);\n }\n\n return result === 0;\n}\n"],"mappings":"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","names":["result"]}
|
package/dist/react/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as ListTriggersResponse, T as TriggerRecord, k as UpdateTriggerResponse, D as DeleteTriggerResponse, M as MemoryStatsResponse, A as ScopeDetail, G as GetMCPServerResponse, b as ConnectMCPServerResponse, U as UpdateScopeResponse, X as SkillSummaryRecord, P as SkillFileInput, J as SkillReadMode, N as SkillFileContentMode, n as SkillManageResponse, o as ContextGraphSummaryResponse, p as ContextGraphReadResponse } from '../types-
|
|
1
|
+
import { g as ListTriggersResponse, T as TriggerRecord, k as UpdateTriggerResponse, D as DeleteTriggerResponse, M as MemoryStatsResponse, A as ScopeDetail, G as GetMCPServerResponse, b as ConnectMCPServerResponse, U as UpdateScopeResponse, X as SkillSummaryRecord, P as SkillFileInput, J as SkillReadMode, N as SkillFileContentMode, n as SkillManageResponse, o as ContextGraphSummaryResponse, p as ContextGraphReadResponse } from '../types-Cn8Lsqkz.mjs';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as ListTriggersResponse, T as TriggerRecord, k as UpdateTriggerResponse, D as DeleteTriggerResponse, M as MemoryStatsResponse, A as ScopeDetail, G as GetMCPServerResponse, b as ConnectMCPServerResponse, U as UpdateScopeResponse, X as SkillSummaryRecord, P as SkillFileInput, J as SkillReadMode, N as SkillFileContentMode, n as SkillManageResponse, o as ContextGraphSummaryResponse, p as ContextGraphReadResponse } from '../types-
|
|
1
|
+
import { g as ListTriggersResponse, T as TriggerRecord, k as UpdateTriggerResponse, D as DeleteTriggerResponse, M as MemoryStatsResponse, A as ScopeDetail, G as GetMCPServerResponse, b as ConnectMCPServerResponse, U as UpdateScopeResponse, X as SkillSummaryRecord, P as SkillFileInput, J as SkillReadMode, N as SkillFileContentMode, n as SkillManageResponse, o as ContextGraphSummaryResponse, p as ContextGraphReadResponse } from '../types-Cn8Lsqkz.js';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
|
|
@@ -359,6 +359,16 @@ interface KronosClientConfig {
|
|
|
359
359
|
apiKey: string;
|
|
360
360
|
/** App ID - used for API key validation and request scoping */
|
|
361
361
|
appId: string;
|
|
362
|
+
/**
|
|
363
|
+
* Override Worker URL (e.g. for local dev: http://localhost:8787).
|
|
364
|
+
* Defaults to KRONOS_WORKER_URL env or https://api.kronos.ai.
|
|
365
|
+
*/
|
|
366
|
+
workerUrl?: string;
|
|
367
|
+
/**
|
|
368
|
+
* Override Mastra URL (e.g. for local dev: http://localhost:4001).
|
|
369
|
+
* Defaults to KRONOS_MASTRA_URL env or https://mastra.kronos.ai.
|
|
370
|
+
*/
|
|
371
|
+
mastraUrl?: string;
|
|
362
372
|
}
|
|
363
373
|
|
|
364
374
|
export type { ScopeDetail as A, CreateScopeRequest as B, CreateMCPServerResponse as C, DeleteTriggerResponse as D, TriggerType as E, CreateFrontendTokenRequest as F, GetMCPServerResponse as G, SkillFileType as H, IngestResponse as I, SkillReadMode as J, KronosClientConfig as K, ListMCPServersResponse as L, MemoryStatsResponse as M, SkillFileContentMode as N, OnTriggered as O, SkillFileInput as P, SkillFileRecord as Q, RotateMCPServerTokenResponse as R, ScratchsheetResponse as S, TriggerRecord as T, UpdateScopeResponse as U, SkillTreeNode as V, SkillMetadataRecord as W, SkillSummaryRecord as X, ContextGraphProcedureSummary as Y, IngestStatusResponse as a, ConnectMCPServerResponse as b, ListScopesResponse as c, GetScopeResponse as d, ScopeSpec as e, CreateScopeResponse as f, ListTriggersResponse as g, CreateTriggerRequest as h, CreateTriggerResponse as i, UpdateTriggerRequest as j, UpdateTriggerResponse as k, CreateFrontendTokenResponse as l, SkillManageParams as m, SkillManageResponse as n, ContextGraphSummaryResponse as o, ContextGraphReadResponse as p, IngestStatus as q, IngestMemoryDisposition as r, IngestRequest as s, CreateMCPServerRequest as t, MCPServerStatus as u, MCPServerToolCapabilities as v, MCPServerDetails as w, ConnectMCPServerRequest as x, RotateMCPServerTokenRequest as y, ScopeSummary as z };
|
|
@@ -359,6 +359,16 @@ interface KronosClientConfig {
|
|
|
359
359
|
apiKey: string;
|
|
360
360
|
/** App ID - used for API key validation and request scoping */
|
|
361
361
|
appId: string;
|
|
362
|
+
/**
|
|
363
|
+
* Override Worker URL (e.g. for local dev: http://localhost:8787).
|
|
364
|
+
* Defaults to KRONOS_WORKER_URL env or https://api.kronos.ai.
|
|
365
|
+
*/
|
|
366
|
+
workerUrl?: string;
|
|
367
|
+
/**
|
|
368
|
+
* Override Mastra URL (e.g. for local dev: http://localhost:4001).
|
|
369
|
+
* Defaults to KRONOS_MASTRA_URL env or https://mastra.kronos.ai.
|
|
370
|
+
*/
|
|
371
|
+
mastraUrl?: string;
|
|
362
372
|
}
|
|
363
373
|
|
|
364
374
|
export type { ScopeDetail as A, CreateScopeRequest as B, CreateMCPServerResponse as C, DeleteTriggerResponse as D, TriggerType as E, CreateFrontendTokenRequest as F, GetMCPServerResponse as G, SkillFileType as H, IngestResponse as I, SkillReadMode as J, KronosClientConfig as K, ListMCPServersResponse as L, MemoryStatsResponse as M, SkillFileContentMode as N, OnTriggered as O, SkillFileInput as P, SkillFileRecord as Q, RotateMCPServerTokenResponse as R, ScratchsheetResponse as S, TriggerRecord as T, UpdateScopeResponse as U, SkillTreeNode as V, SkillMetadataRecord as W, SkillSummaryRecord as X, ContextGraphProcedureSummary as Y, IngestStatusResponse as a, ConnectMCPServerResponse as b, ListScopesResponse as c, GetScopeResponse as d, ScopeSpec as e, CreateScopeResponse as f, ListTriggersResponse as g, CreateTriggerRequest as h, CreateTriggerResponse as i, UpdateTriggerRequest as j, UpdateTriggerResponse as k, CreateFrontendTokenResponse as l, SkillManageParams as m, SkillManageResponse as n, ContextGraphSummaryResponse as o, ContextGraphReadResponse as p, IngestStatus as q, IngestMemoryDisposition as r, IngestRequest as s, CreateMCPServerRequest as t, MCPServerStatus as u, MCPServerToolCapabilities as v, MCPServerDetails as w, ConnectMCPServerRequest as x, RotateMCPServerTokenRequest as y, ScopeSummary as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gdrl/kronos-lib",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Lightweight TypeScript SDK for the Kronos Knowledge Graph API",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"scripts": {
|
|
25
25
|
"build": "tsup",
|
|
26
26
|
"dev": "tsup --watch",
|
|
27
|
-
"prepublishOnly": "
|
|
27
|
+
"prepublishOnly": "npm run build"
|
|
28
28
|
},
|
|
29
29
|
"keywords": [
|
|
30
30
|
"kronos",
|
|
@@ -38,7 +38,6 @@
|
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/node": "^25.0.10",
|
|
40
40
|
"@types/react": "^19.2.14",
|
|
41
|
-
"dotenv": "^17.2.3",
|
|
42
41
|
"react": "^19.0.0",
|
|
43
42
|
"tsup": "^8.3.5",
|
|
44
43
|
"typescript": "^5.7.2"
|