@kraken-ai/platform 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-HGJSK6MW.js → chunk-PPT6GGYL.js} +99 -2
- package/dist/chunk-PPT6GGYL.js.map +1 -0
- package/dist/cli.js +47 -19
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +3 -449
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -369
- package/dist/index.d.ts +14 -369
- package/dist/index.js +92 -611
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +498 -6
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +19 -2
- package/dist/server.d.ts +19 -2
- package/dist/server.js +451 -2
- package/dist/server.js.map +1 -1
- package/dist/types-CkknNKNr.d.cts +451 -0
- package/dist/types-CkknNKNr.d.ts +451 -0
- package/package.json +12 -12
- package/dist/chunk-HGJSK6MW.js.map +0 -1
- package/dist/connector-CumEDPfS.d.cts +0 -103
- package/dist/connector-CumEDPfS.d.ts +0 -103
|
@@ -283,12 +283,109 @@ var startConnectorServer = async (connector, options) => {
|
|
|
283
283
|
};
|
|
284
284
|
};
|
|
285
285
|
|
|
286
|
+
// src/agents/types/action.ts
|
|
287
|
+
import * as z2 from "zod";
|
|
288
|
+
var ACTION_NAME_REGEX = /^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$/;
|
|
289
|
+
var isValidActionName = (name) => name.length === 1 ? /^[a-z0-9]$/.test(name) : ACTION_NAME_REGEX.test(name);
|
|
290
|
+
var actionVariantConfigSchema = z2.object({
|
|
291
|
+
schema: z2.record(z2.string(), z2.unknown()),
|
|
292
|
+
webhook: z2.string().url().optional(),
|
|
293
|
+
hasHandler: z2.boolean()
|
|
294
|
+
});
|
|
295
|
+
var actionsConfigSchema = z2.object({
|
|
296
|
+
variants: z2.record(z2.string(), actionVariantConfigSchema)
|
|
297
|
+
}).strict();
|
|
298
|
+
|
|
299
|
+
// src/agents/define-actions.ts
|
|
300
|
+
import * as z3 from "zod";
|
|
301
|
+
var defineAction = (input) => input;
|
|
302
|
+
var defineActions = (variants) => {
|
|
303
|
+
const entries = Object.entries(variants);
|
|
304
|
+
if (entries.length === 0) {
|
|
305
|
+
throw new Error("defineActions() requires at least one action variant");
|
|
306
|
+
}
|
|
307
|
+
if (entries.length > 20) {
|
|
308
|
+
throw new Error("defineActions() supports a maximum of 20 action variants");
|
|
309
|
+
}
|
|
310
|
+
const serialized = {};
|
|
311
|
+
const zodSchemas = {};
|
|
312
|
+
const handlers = {};
|
|
313
|
+
for (const [name, variant] of entries) {
|
|
314
|
+
if (!isValidActionName(name)) {
|
|
315
|
+
throw new Error(
|
|
316
|
+
`Invalid action name "${name}": must be lowercase alphanumeric with hyphens, 1-64 chars`
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
const v = variant;
|
|
320
|
+
serialized[name] = {
|
|
321
|
+
schema: z3.toJSONSchema(v.schema, { target: "draft-2020-12" }),
|
|
322
|
+
webhook: v.webhook,
|
|
323
|
+
hasHandler: !!v.handler
|
|
324
|
+
};
|
|
325
|
+
zodSchemas[name] = v.schema;
|
|
326
|
+
if (v.handler) {
|
|
327
|
+
handlers[name] = v.handler;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return Object.freeze({
|
|
331
|
+
__type: "PlatformActions",
|
|
332
|
+
config: Object.freeze({ variants: Object.freeze(serialized) }),
|
|
333
|
+
zodSchemas: Object.freeze(zodSchemas),
|
|
334
|
+
handlers: Object.freeze(handlers)
|
|
335
|
+
});
|
|
336
|
+
};
|
|
337
|
+
var buildActionOutputSchema = (actions) => {
|
|
338
|
+
const entries = Object.entries(actions.zodSchemas);
|
|
339
|
+
if (entries.length === 0) {
|
|
340
|
+
throw new Error("Cannot build output schema from empty action definitions");
|
|
341
|
+
}
|
|
342
|
+
const variants = entries.map(
|
|
343
|
+
([name, schema]) => z3.object({ action: z3.literal(name) }).extend(schema.shape)
|
|
344
|
+
);
|
|
345
|
+
const [first, ...rest] = variants;
|
|
346
|
+
if (!first) {
|
|
347
|
+
throw new Error("Cannot build output schema from empty action definitions");
|
|
348
|
+
}
|
|
349
|
+
return z3.discriminatedUnion("action", [first, ...rest]);
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
// src/cli/log.ts
|
|
353
|
+
var supportsColor = !("NO_COLOR" in process.env) && process.env.FORCE_COLOR !== "0" && (process.stderr.isTTY ?? false);
|
|
354
|
+
var code = (open, close) => {
|
|
355
|
+
const openStr = `\x1B[${open}m`;
|
|
356
|
+
const closeStr = `\x1B[${close}m`;
|
|
357
|
+
return (s) => supportsColor ? `${openStr}${s}${closeStr}` : s;
|
|
358
|
+
};
|
|
359
|
+
var bold = code(1, 22);
|
|
360
|
+
var dim = code(2, 22);
|
|
361
|
+
var red = code(31, 39);
|
|
362
|
+
var yellow = code(33, 39);
|
|
363
|
+
var green = code(32, 39);
|
|
364
|
+
var cyan = code(36, 39);
|
|
365
|
+
|
|
366
|
+
// src/cli/validate.ts
|
|
367
|
+
var ENTITY_NAME_REGEX = /^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$/;
|
|
368
|
+
var isValidEntityName = (name) => name.length === 1 ? /^[a-z0-9]$/.test(name) : ENTITY_NAME_REGEX.test(name);
|
|
369
|
+
|
|
286
370
|
export {
|
|
287
371
|
SecurityError,
|
|
288
372
|
ConnectorError,
|
|
289
373
|
wrapToolResult,
|
|
290
374
|
wrapToolError,
|
|
291
375
|
mcpResult,
|
|
292
|
-
startConnectorServer
|
|
376
|
+
startConnectorServer,
|
|
377
|
+
ACTION_NAME_REGEX,
|
|
378
|
+
isValidActionName,
|
|
379
|
+
actionVariantConfigSchema,
|
|
380
|
+
actionsConfigSchema,
|
|
381
|
+
defineAction,
|
|
382
|
+
defineActions,
|
|
383
|
+
buildActionOutputSchema,
|
|
384
|
+
dim,
|
|
385
|
+
yellow,
|
|
386
|
+
green,
|
|
387
|
+
cyan,
|
|
388
|
+
ENTITY_NAME_REGEX,
|
|
389
|
+
isValidEntityName
|
|
293
390
|
};
|
|
294
|
-
//# sourceMappingURL=chunk-
|
|
391
|
+
//# sourceMappingURL=chunk-PPT6GGYL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/agents/errors.ts","../src/agents/connector-wrap.ts","../src/agents/connector-server.ts","../src/agents/types/action.ts","../src/agents/define-actions.ts","../src/cli/log.ts","../src/cli/validate.ts"],"sourcesContent":["// Copyright (c) Optima Engineering LLC\n// SPDX-License-Identifier: BUSL-1.1\n\nexport class SecurityError extends Error {\n readonly code = \"SECURITY_VIOLATION\";\n\n constructor(message: string) {\n super(message);\n this.name = \"SecurityError\";\n }\n}\n\nexport class ConnectorError extends Error {\n readonly code = \"CONNECTOR_ERROR\";\n\n constructor(message: string) {\n super(message);\n this.name = \"ConnectorError\";\n }\n}\n","// Copyright (c) Optima Engineering LLC\n// SPDX-License-Identifier: BUSL-1.1\n\nimport { ConnectorError } from \"./errors\";\nimport type { McpContent } from \"./types/connector\";\n\nconst MAX_TOOL_RESULT_SIZE = 10 * 1024 * 1024; // 10MB\n\ninterface ToolResultContent {\n readonly type: string;\n [key: string]: unknown;\n}\n\ninterface ToolResult {\n readonly content: ReadonlyArray<ToolResultContent>;\n readonly isError?: boolean;\n}\n\nconst isMcpContent = (val: unknown): val is McpContent =>\n typeof val === \"object\" &&\n val !== null &&\n \"__mcpPassThrough\" in val &&\n (val as McpContent).__mcpPassThrough === true;\n\n/** Wrap a handler return value into MCP CallToolResult format */\nexport const wrapToolResult = (value: unknown): ToolResult => {\n if (value === null || value === undefined) {\n return { content: [] };\n }\n\n if (typeof value === \"string\") {\n return { content: [{ type: \"text\", text: value }] };\n }\n\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return { content: [{ type: \"text\", text: String(value) }] };\n }\n\n if (isMcpContent(value)) {\n const result: ToolResult = { content: value.content };\n if (value.isError) {\n return { ...result, isError: true };\n }\n return result;\n }\n\n const json = JSON.stringify(value, null, 2);\n if (json.length > MAX_TOOL_RESULT_SIZE) {\n return {\n content: [{ type: \"text\", text: `[Result truncated: ${json.length} bytes]` }],\n isError: true,\n };\n }\n return { content: [{ type: \"text\", text: json }] };\n};\n\n/** Wrap a thrown error into MCP CallToolResult format with isError: true */\nexport const wrapToolError = (error: unknown): ToolResult => {\n if (error instanceof ConnectorError) {\n return {\n content: [{ type: \"text\", text: error.message }],\n isError: true,\n };\n }\n\n if (error instanceof Error) {\n console.error(\"[connector] Internal handler error:\", error.message, error.stack);\n } else {\n console.error(\"[connector] Internal handler error:\", String(error));\n }\n\n return {\n content: [{ type: \"text\", text: \"Internal handler error\" }],\n isError: true,\n };\n};\n\n/** Create an explicit MCP content pass-through result */\nexport const mcpResult = (content: McpContent[\"content\"], isError?: boolean): McpContent => ({\n __mcpPassThrough: true as const,\n content,\n isError,\n});\n","// Copyright (c) Optima Engineering LLC\n// SPDX-License-Identifier: BUSL-1.1\n\nimport { randomUUID } from \"node:crypto\";\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\n\nimport * as z from \"zod\";\nimport { wrapToolError, wrapToolResult } from \"./connector-wrap\";\nimport type { ConnectorPromptDef, PlatformConnector } from \"./types/connector\";\n\nconst DEFAULT_HANDLER_TIMEOUT_MS = 30_000;\nconst MAX_BODY_SIZE = 10 * 1024 * 1024; // 10MB\n\nexport interface ConnectorServerOptions {\n readonly port?: number;\n readonly host?: string;\n readonly handlerTimeoutMs?: number;\n}\n\nexport interface ConnectorServerHandle {\n readonly port: number;\n readonly close: () => Promise<void>;\n}\n\nconst withTimeout = <T>(promise: Promise<T>, ms: number): Promise<T> =>\n Promise.race([\n promise,\n new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error(`Handler timed out after ${ms}ms`)), ms),\n ),\n ]);\n\nconst readBody = (req: IncomingMessage, maxSize: number): Promise<string> =>\n new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let size = 0;\n req.on(\"data\", (chunk: Buffer) => {\n size += chunk.length;\n if (size > maxSize) {\n req.destroy();\n reject(new Error(\"Request body too large\"));\n return;\n }\n chunks.push(chunk);\n });\n req.on(\"end\", () => resolve(Buffer.concat(chunks).toString()));\n req.on(\"error\", reject);\n });\n\n/** Convert ConnectorPromptDef.arguments array to a raw shape for MCP SDK */\nconst buildPromptArgsSchema = (\n def: ConnectorPromptDef,\n): Record<string, z.ZodString | z.ZodOptional<z.ZodString>> | undefined => {\n if (!def.arguments?.length) return undefined;\n const shape: Record<string, z.ZodString | z.ZodOptional<z.ZodString>> = {};\n for (const arg of def.arguments) {\n shape[arg.name] = arg.required ? z.string() : z.string().optional();\n }\n return shape;\n};\n\nexport const startConnectorServer = async (\n connector: PlatformConnector,\n options?: ConnectorServerOptions,\n): Promise<ConnectorServerHandle> => {\n const mcpServerModule = await import(\"@modelcontextprotocol/sdk/server/mcp.js\").catch(() => {\n throw new Error(\n \"@modelcontextprotocol/sdk is required for startConnectorServer. \" +\n \"Install it: pnpm add @modelcontextprotocol/sdk\",\n );\n });\n const transportModule = await import(\"@modelcontextprotocol/sdk/server/streamableHttp.js\").catch(\n () => {\n throw new Error(\n \"@modelcontextprotocol/sdk is required for startConnectorServer. \" +\n \"Install it: pnpm add @modelcontextprotocol/sdk\",\n );\n },\n );\n\n const { McpServer } = mcpServerModule;\n const { StreamableHTTPServerTransport } = transportModule;\n\n const timeoutMs = options?.handlerTimeoutMs ?? DEFAULT_HANDLER_TIMEOUT_MS;\n\n const mcpServer = new McpServer(\n { name: connector.name, version: \"0.0.0\" },\n { capabilities: { tools: {}, resources: {}, prompts: {} } },\n );\n\n const tools = connector.tools ?? {};\n const toolEntries = Object.entries(tools);\n\n if (toolEntries.length === 0) {\n console.warn(\n `[connector:${connector.name}] No tools defined — server will start with zero tools`,\n );\n }\n\n for (const [name, def] of toolEntries) {\n mcpServer.registerTool(\n name,\n {\n description: def.description,\n inputSchema: def.input,\n ...(def.annotations ? { annotations: def.annotations } : {}),\n },\n async (args: unknown) => {\n try {\n // args is already validated by the MCP SDK against the Zod schema\n const result = await withTimeout(Promise.resolve(def.handler(args)), timeoutMs);\n const wrapped = wrapToolResult(result);\n return {\n content: wrapped.content.map((c) => ({\n type: \"text\" as const,\n text: String(\"text\" in c ? c.text : \"\"),\n })),\n ...(wrapped.isError === true ? { isError: true as const } : {}),\n };\n } catch (error: unknown) {\n const wrapped = wrapToolError(error);\n return {\n content: wrapped.content.map((c) => ({\n type: \"text\" as const,\n text: String(\"text\" in c ? c.text : \"\"),\n })),\n isError: true as const,\n };\n }\n },\n );\n }\n\n const resources = connector.resources ?? {};\n for (const [name, def] of Object.entries(resources)) {\n mcpServer.registerResource(\n name,\n def.uri,\n {\n description: def.description,\n ...(def.mimeType ? { mimeType: def.mimeType } : {}),\n },\n async (_uri: URL, extra: { signal: AbortSignal }) => {\n try {\n const result = await withTimeout(\n Promise.resolve(def.read({ signal: extra.signal })),\n timeoutMs,\n );\n return { contents: [...result.contents] };\n } catch (error: unknown) {\n if (error instanceof Error) {\n console.error(`[connector:${connector.name}] Resource read error:`, error.message);\n }\n throw error;\n }\n },\n );\n }\n\n const prompts = connector.prompts ?? {};\n for (const [name, def] of Object.entries(prompts)) {\n const argsSchema = buildPromptArgsSchema(def);\n mcpServer.registerPrompt(\n name,\n {\n description: def.description,\n ...(argsSchema ? { argsSchema } : {}),\n },\n async (args: Record<string, string | undefined>, extra: { signal: AbortSignal }) => {\n try {\n const cleanArgs: Record<string, string> = {};\n for (const [k, v] of Object.entries(args)) {\n if (v !== undefined) cleanArgs[k] = v;\n }\n const result = await withTimeout(\n Promise.resolve(def.get(cleanArgs, { signal: extra.signal })),\n timeoutMs,\n );\n return { messages: [...result.messages] };\n } catch (error: unknown) {\n if (error instanceof Error) {\n console.error(`[connector:${connector.name}] Prompt get error:`, error.message);\n }\n throw error;\n }\n },\n );\n }\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n });\n\n const host = options?.host ?? \"127.0.0.1\";\n const port = options?.port ?? 0;\n\n const httpServer = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n if (req.url === \"/health\" && req.method === \"GET\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ status: \"ok\" }));\n return;\n }\n\n if (\n req.url === \"/mcp\" &&\n (req.method === \"POST\" || req.method === \"GET\" || req.method === \"DELETE\")\n ) {\n if (req.method === \"POST\") {\n // Check Content-Length before reading body (fast reject for oversized payloads)\n const contentLength = parseInt(req.headers[\"content-length\"] ?? \"0\", 10);\n if (contentLength > MAX_BODY_SIZE) {\n req.resume(); // drain the request body to prevent EPIPE\n res.writeHead(413, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Request body too large\" }));\n return;\n }\n\n try {\n const body = await readBody(req, MAX_BODY_SIZE);\n const parsed: unknown = JSON.parse(body);\n await transport.handleRequest(req, res, parsed);\n } catch (err: unknown) {\n if (!res.headersSent) {\n const isTooLarge = err instanceof Error && err.message === \"Request body too large\";\n res.writeHead(isTooLarge ? 413 : 400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: isTooLarge ? \"Request body too large\" : \"Invalid request body\",\n }),\n );\n }\n }\n return;\n }\n\n // GET (SSE) and DELETE (session end)\n try {\n await transport.handleRequest(req, res);\n } catch {\n if (!res.headersSent) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Internal server error\" }));\n }\n }\n return;\n }\n\n res.writeHead(404);\n res.end(\"Not found\");\n });\n\n // Connect MCP server to transport AFTER tool registration\n await mcpServer.connect(transport);\n\n await new Promise<void>((resolve) => {\n httpServer.listen(port, host, () => resolve());\n });\n\n const addr = httpServer.address();\n if (!addr || typeof addr === \"string\") {\n throw new Error(\"Failed to get server address\");\n }\n\n return {\n port: (addr as AddressInfo).port,\n close: async () => {\n await mcpServer.close();\n await new Promise<void>((resolve, reject) => {\n httpServer.close((err) => (err ? reject(err) : resolve()));\n });\n },\n };\n};\n","// Copyright (c) Optima Engineering LLC\n// SPDX-License-Identifier: BUSL-1.1\n\nimport * as z from \"zod\";\n\n/** Action names follow entity naming convention: lowercase alphanumeric with hyphens, 1-64 chars. */\nexport const ACTION_NAME_REGEX = /^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$/;\n\n/** Validates an action name (allows single-char names like \"a\"). */\nexport const isValidActionName = (name: string): boolean =>\n name.length === 1 ? /^[a-z0-9]$/.test(name) : ACTION_NAME_REGEX.test(name);\n\n/** Input for a single action variant in defineActions(). */\nexport interface ActionVariantInput<\n S extends z.ZodObject<z.ZodRawShape> = z.ZodObject<z.ZodRawShape>,\n> {\n schema: S;\n webhook?: string;\n // Method syntax → bivariant parameter checking, so specific handler args\n // (e.g. { reason: string }) are assignable to the default (z.infer<ZodObject>).\n handler?(payload: z.infer<S>): Promise<void>;\n}\n\n/** Serializable config for a single action variant (stored in manifest/DB). */\nexport interface ActionVariantConfig {\n schema: Record<string, unknown>;\n webhook?: string;\n hasHandler: boolean;\n}\n\n/** Serializable portion of action definitions (stored in agent config). */\nexport interface PlatformActionsConfig {\n variants: Record<string, ActionVariantConfig>;\n}\n\n/** Full action definitions including in-memory schemas and handlers for runtime use. */\nexport interface PlatformActions {\n readonly __type: \"PlatformActions\";\n readonly config: PlatformActionsConfig;\n readonly zodSchemas: Record<string, z.ZodObject<z.ZodRawShape>>;\n readonly handlers: Readonly<Record<string, (payload: unknown) => Promise<void>>>;\n}\n\nexport const actionVariantConfigSchema = z.object({\n schema: z.record(z.string(), z.unknown()),\n webhook: z.string().url().optional(),\n hasHandler: z.boolean(),\n});\n\nexport const actionsConfigSchema = z\n .object({\n variants: z.record(z.string(), actionVariantConfigSchema),\n })\n .strict();\n","// Copyright (c) Optima Engineering LLC\n// SPDX-License-Identifier: BUSL-1.1\n\nimport * as z from \"zod\";\nimport {\n type ActionVariantConfig,\n type ActionVariantInput,\n isValidActionName,\n type PlatformActions,\n} from \"./types/action\";\n\n/**\n * Define an action variant.\n *\n * Infers handler payload types from the schema.\n *\n * @example\n * ```ts\n * defineAction({\n * schema: z.object({ reason: z.string() }),\n * handler: async (payload) => {\n * payload.reason; // string — fully typed\n * },\n * });\n * ```\n */\nexport const defineAction = <S extends z.ZodObject<z.ZodRawShape>>(\n input: ActionVariantInput<S>,\n): ActionVariantInput<S> => input;\n\n/**\n * Define action variants for a platform agent. Actions are typed terminal\n * outputs — the agent's final decision as structured output.\n *\n * Each variant has a name and an object schema. Schemas are serialized\n * to JSON Schema for discovery/storage, and the originals are preserved\n * in-memory for runtime validation.\n *\n * Handler payload types are inferred from the schema automatically:\n *\n * @example\n * ```ts\n * const actions = defineActions({\n * approve: {\n * schema: z.object({ reason: z.string() }),\n * handler: async (payload) => {\n * payload.reason; // string — fully typed\n * },\n * },\n * reject: { schema: z.object({ reason: z.string(), severity: z.number() }) },\n * });\n * ```\n */\nexport const defineActions = <V extends Record<string, ActionVariantInput>>(\n variants: V,\n): PlatformActions => {\n const entries = Object.entries(variants);\n\n if (entries.length === 0) {\n throw new Error(\"defineActions() requires at least one action variant\");\n }\n\n if (entries.length > 20) {\n throw new Error(\"defineActions() supports a maximum of 20 action variants\");\n }\n\n const serialized: Record<string, ActionVariantConfig> = {};\n const zodSchemas: Record<string, z.ZodObject<z.ZodRawShape>> = {};\n const handlers: Record<string, (payload: unknown) => Promise<void>> = {};\n\n for (const [name, variant] of entries) {\n if (!isValidActionName(name)) {\n throw new Error(\n `Invalid action name \"${name}\": must be lowercase alphanumeric with hyphens, 1-64 chars`,\n );\n }\n const v = variant as ActionVariantInput;\n serialized[name] = {\n schema: z.toJSONSchema(v.schema, { target: \"draft-2020-12\" }) as Record<string, unknown>,\n webhook: v.webhook,\n hasHandler: !!v.handler,\n };\n zodSchemas[name] = v.schema;\n if (v.handler) {\n // Safe: runtime validates payload against Zod schema before calling handler\n handlers[name] = v.handler as (payload: unknown) => Promise<void>;\n }\n }\n\n return Object.freeze({\n __type: \"PlatformActions\" as const,\n config: Object.freeze({ variants: Object.freeze(serialized) }),\n zodSchemas: Object.freeze(zodSchemas),\n handlers: Object.freeze(handlers),\n });\n};\n\n/**\n * Build a discriminated-union schema from action definitions.\n * Each variant becomes `z.object({ action: z.literal(name), ...variantSchema })`.\n * Used as the agent's outputSchema to constrain LLM structured output.\n */\nexport const buildActionOutputSchema = (actions: PlatformActions) => {\n const entries = Object.entries(actions.zodSchemas);\n\n if (entries.length === 0) {\n throw new Error(\"Cannot build output schema from empty action definitions\");\n }\n\n const variants = entries.map(([name, schema]) =>\n z.object({ action: z.literal(name) }).extend(schema.shape),\n );\n\n const [first, ...rest] = variants;\n if (!first) {\n throw new Error(\"Cannot build output schema from empty action definitions\");\n }\n return z.discriminatedUnion(\"action\", [first, ...rest]);\n};\n","// Copyright (c) Optima Engineering LLC\n// SPDX-License-Identifier: BUSL-1.1\n\nconst supportsColor =\n !(\"NO_COLOR\" in process.env) &&\n process.env.FORCE_COLOR !== \"0\" &&\n (process.stderr.isTTY ?? false);\n\nconst code = (open: number, close: number) => {\n const openStr = `\\x1b[${open}m`;\n const closeStr = `\\x1b[${close}m`;\n return (s: string): string => (supportsColor ? `${openStr}${s}${closeStr}` : s);\n};\n\nexport const bold = code(1, 22);\nexport const dim = code(2, 22);\nexport const red = code(31, 39);\nexport const yellow = code(33, 39);\nexport const green = code(32, 39);\nexport const cyan = code(36, 39);\n\nexport const info = (msg: string): void => {\n process.stderr.write(` ${dim(\"[kraken-ai:\")} ${cyan(\"info\")}${dim(\"]\")} ${msg}\\n`);\n};\n\nexport const warn = (msg: string): void => {\n process.stderr.write(` ${dim(\"[kraken-ai:\")} ${yellow(\"warn\")}${dim(\"]\")} ${msg}\\n`);\n};\n\nexport const error = (msg: string): void => {\n process.stderr.write(` ${dim(\"[kraken-ai:\")} ${red(\"error\")}${dim(\"]\")} ${msg}\\n`);\n};\n\nexport const success = (msg: string): void => {\n process.stderr.write(` ${dim(\"[kraken-ai:\")} ${green(\"ok\")}${dim(\"]\")} ${msg}\\n`);\n};\n","// Copyright (c) Optima Engineering LLC\n// SPDX-License-Identifier: BUSL-1.1\n\nimport type { SchemaBundle } from \"./codegen\";\n\n// ─── Entity Name Validation ───\n\nexport const ENTITY_NAME_REGEX = /^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$/;\n\n/** Single-char names (e.g. \"a\") are valid — the regex requires min 2 chars, so we also allow /^[a-z0-9]$/ */\nexport const isValidEntityName = (name: string): boolean =>\n name.length === 1 ? /^[a-z0-9]$/.test(name) : ENTITY_NAME_REGEX.test(name);\n\n// ─── Skill Name Validation ───\n\n/** Skill filenames allow uppercase: e.g. someFile-name.md, Research.md */\nexport const SKILL_NAME_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9-]{0,62}[a-zA-Z0-9]$/;\n\nexport const isValidSkillName = (basename: string): boolean =>\n basename.length === 1 ? /^[a-zA-Z0-9]$/.test(basename) : SKILL_NAME_REGEX.test(basename);\n\n/** Skill IDs from remote may include .md extension */\nexport const isValidSkillId = (id: string): boolean => {\n const base = id.endsWith(\".md\") ? id.slice(0, -3) : id;\n return isValidSkillName(base);\n};\n\n// ─── Tool Name Validation ───\n\n/** Tool names allow underscores (e.g., fs_read, fs_write) */\nexport const TOOL_NAME_REGEX = /^[a-z][a-z0-9_-]{0,62}[a-z0-9]$/;\n\nexport const isValidToolName = (name: string): boolean =>\n name.length === 1 ? /^[a-z]$/.test(name) : TOOL_NAME_REGEX.test(name);\n\n// ─── Property Name Validation ───\n\n/** JS/TS property names with 255-char length cap to prevent DoS */\nexport const PROPERTY_NAME_REGEX = /^[a-zA-Z_$][a-zA-Z0-9_$]{0,254}$/;\n\nconst FORBIDDEN_PROPS = new Set([\n \"__proto__\",\n \"constructor\",\n \"prototype\",\n \"__defineGetter__\",\n \"__defineSetter__\",\n \"__lookupGetter__\",\n \"__lookupSetter__\",\n]);\n\nexport const isValidPropertyName = (name: string): boolean =>\n PROPERTY_NAME_REGEX.test(name) && !FORBIDDEN_PROPS.has(name);\n\n// ─── Schema Bundle Validation ───\n\nconst MAX_SCHEMA_DEPTH = 20;\nconst MAX_OBJECT_BREADTH = 200;\n\n/**\n * Validates all identifiers in a SchemaBundle before codegen.\n * Throws on the first invalid identifier — fail-fast.\n *\n * Checks:\n * - Entity names (agent IDs, connector IDs, pipeline names, query names)\n * - Skill IDs (allows .md extension)\n * - Tool names (allows underscores)\n * - Property names in JSON Schema (recursive, with depth/breadth limits)\n * - Column names in query schemas\n * - Rejects `$ref` keys in pipeline schemas\n * - Strips `pattern` keys from pipeline schemas (ReDoS prevention)\n */\nexport const validateSchemaBundle = (bundle: SchemaBundle): void => {\n for (const agent of bundle.agents) {\n assertValidEntity(\"agent id\", agent.id);\n validateJsonSchemaProperties(\"agent input schema\", agent.input, 0);\n validateJsonSchemaProperties(\"agent output schema\", agent.output, 0);\n if (agent.actions) {\n for (const [actionName, actionSchema] of Object.entries(agent.actions)) {\n assertValidEntity(\"agent action name\", actionName);\n validateJsonSchemaProperties(\"agent action schema\", actionSchema, 0);\n }\n }\n }\n\n for (const query of bundle.queries) {\n assertValidEntity(\"query name\", query.name);\n validateJsonSchemaProperties(\"query params schema\", query.params, 0);\n for (const col of query.columns) {\n assertValidProperty(\"query column name\", col.name);\n }\n }\n\n for (const connector of bundle.connectors) {\n assertValidEntity(\"connector id\", connector.id);\n for (const tool of connector.tools) {\n assertValidTool(\"connector tool name\", tool.name);\n validateJsonSchemaProperties(\"connector tool parameters\", tool.parameters, 0);\n }\n }\n\n for (const pipeline of bundle.pipelines) {\n assertValidEntity(\"pipeline name\", pipeline.pipeline);\n for (const query of pipeline.queries) {\n assertValidEntity(\"pipeline query name\", query.name);\n validatePipelineSchema(\"pipeline query params\", query.params, 0);\n validatePipelineSchema(\"pipeline query returns\", query.returns, 0);\n }\n }\n\n for (const skill of bundle.skills) {\n assertValidSkill(\"skill id\", skill.id);\n }\n};\n\n// ─── Internal Assertion Helpers ───\n\nconst assertValidEntity = (entityType: string, value: string): void => {\n if (!isValidEntityName(value)) {\n throw new Error(\n `Invalid remote schema: ${entityType} \"${value}\". Must match ${ENTITY_NAME_REGEX}`,\n );\n }\n};\n\nconst assertValidTool = (entityType: string, value: string): void => {\n if (!isValidToolName(value)) {\n throw new Error(\n `Invalid remote schema: ${entityType} \"${value}\". Must match ${TOOL_NAME_REGEX}`,\n );\n }\n};\n\nconst assertValidProperty = (entityType: string, value: string): void => {\n if (!isValidPropertyName(value)) {\n throw new Error(\n `Invalid remote schema: ${entityType} \"${value}\". Must match ${PROPERTY_NAME_REGEX} and not be a forbidden property`,\n );\n }\n};\n\nconst assertValidSkill = (entityType: string, value: string): void => {\n if (!isValidSkillId(value)) {\n throw new Error(\n `Invalid remote schema: ${entityType} \"${value}\". Must match ${SKILL_NAME_REGEX} (with optional .md extension)`,\n );\n }\n};\n\n/**\n * Validates property names in a JSON Schema node recursively.\n * Used for agent/query/connector schemas where we only need property name validation.\n */\nconst validateJsonSchemaProperties = (\n context: string,\n schema: Record<string, unknown>,\n depth: number,\n): void => {\n if (!schema || typeof schema !== \"object\") return;\n if (depth > MAX_SCHEMA_DEPTH) {\n throw new Error(\n `Invalid remote schema: ${context} exceeds maximum nesting depth of ${MAX_SCHEMA_DEPTH}`,\n );\n }\n\n const props = schema.properties as Record<string, Record<string, unknown>> | undefined;\n if (props) {\n const keys = Object.keys(props);\n if (keys.length > MAX_OBJECT_BREADTH) {\n throw new Error(\n `Invalid remote schema: ${context} has ${keys.length} properties, exceeding limit of ${MAX_OBJECT_BREADTH}`,\n );\n }\n for (const key of keys) {\n assertValidProperty(`${context} property name`, key);\n validateJsonSchemaProperties(context, props[key] ?? {}, depth + 1);\n }\n }\n\n const items = schema.items as Record<string, unknown> | undefined;\n if (items) {\n validateJsonSchemaProperties(context, items, depth + 1);\n }\n\n for (const keyword of [\"anyOf\", \"oneOf\", \"allOf\"] as const) {\n const variants = schema[keyword] as Record<string, unknown>[] | undefined;\n if (variants) {\n for (const variant of variants) {\n validateJsonSchemaProperties(context, variant, depth + 1);\n }\n }\n }\n};\n\n/**\n * Validates pipeline JSON Schema nodes with stricter checks:\n * - All property name validation from validateJsonSchemaProperties\n * - Rejects `$ref` keys (prevents circular reference bypass in z.fromJSONSchema())\n * - Strips `pattern` keys (prevents ReDoS in z.fromJSONSchema() line 328)\n */\nconst validatePipelineSchema = (\n context: string,\n schema: Record<string, unknown>,\n depth: number,\n): void => {\n if (!schema || typeof schema !== \"object\") return;\n if (depth > MAX_SCHEMA_DEPTH) {\n throw new Error(\n `Invalid remote schema: ${context} exceeds maximum nesting depth of ${MAX_SCHEMA_DEPTH}`,\n );\n }\n\n if (\"$ref\" in schema) {\n throw new Error(\n `Invalid remote schema: ${context} contains \"$ref\" which is not supported in pipeline schemas`,\n );\n }\n\n // Strip `pattern` keys to prevent ReDoS in z.fromJSONSchema()\n if (\"pattern\" in schema) {\n delete schema.pattern;\n }\n\n const props = schema.properties as Record<string, Record<string, unknown>> | undefined;\n if (props) {\n const keys = Object.keys(props);\n if (keys.length > MAX_OBJECT_BREADTH) {\n throw new Error(\n `Invalid remote schema: ${context} has ${keys.length} properties, exceeding limit of ${MAX_OBJECT_BREADTH}`,\n );\n }\n for (const key of keys) {\n assertValidProperty(`${context} property name`, key);\n validatePipelineSchema(context, props[key] ?? {}, depth + 1);\n }\n }\n\n const items = schema.items as Record<string, unknown> | undefined;\n if (items) {\n validatePipelineSchema(context, items, depth + 1);\n }\n\n for (const keyword of [\"anyOf\", \"oneOf\", \"allOf\"] as const) {\n const variants = schema[keyword] as Record<string, unknown>[] | undefined;\n if (variants) {\n for (const variant of variants) {\n validatePipelineSchema(context, variant, depth + 1);\n }\n }\n }\n};\n"],"mappings":"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","names":["z","z"]}
|
package/dist/cli.js
CHANGED
|
@@ -246,12 +246,17 @@ var generateAgentsDts = (agents) => {
|
|
|
246
246
|
actions: ${actions}
|
|
247
247
|
}`;
|
|
248
248
|
}).join("\n");
|
|
249
|
-
return
|
|
250
|
-
|
|
251
|
-
export
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
249
|
+
return [
|
|
250
|
+
`// Auto-generated by \`kraken generate\` \u2014 do not edit manually`,
|
|
251
|
+
`export {};`,
|
|
252
|
+
``,
|
|
253
|
+
`declare module "@kraken-ai/platform" {`,
|
|
254
|
+
` interface AgentRegistry {`,
|
|
255
|
+
entries,
|
|
256
|
+
` }`,
|
|
257
|
+
`}`,
|
|
258
|
+
``
|
|
259
|
+
].join("\n");
|
|
255
260
|
};
|
|
256
261
|
var generateActionsType = (actions) => {
|
|
257
262
|
if (!actions || Object.keys(actions).length === 0) {
|
|
@@ -299,7 +304,7 @@ ${entries}
|
|
|
299
304
|
var generateIndexDts = (hasConnectors, hasPipelines, hasPlatformTypes) => {
|
|
300
305
|
let content = `// Auto-generated by \`kraken generate\` \u2014 do not edit manually
|
|
301
306
|
|
|
302
|
-
|
|
307
|
+
/// <reference path="./agents.d.ts" />
|
|
303
308
|
export type { QueryRegistry } from "./queries"
|
|
304
309
|
`;
|
|
305
310
|
if (hasConnectors) {
|
|
@@ -659,13 +664,18 @@ var projectManifestSchema = z10.object({
|
|
|
659
664
|
skills: z10.array(skillEntrySchema),
|
|
660
665
|
connectors: z10.array(connectorEntrySchema)
|
|
661
666
|
});
|
|
667
|
+
var isTsxAvailable = () => process.env.NODE_OPTIONS?.includes("tsx") === true;
|
|
662
668
|
var isPlatformAgentExport = (value) => value != null && typeof value === "object" && value.__type === "PlatformAgent" && "config" in value;
|
|
663
669
|
var discoverAgents = async (projectRoot) => {
|
|
664
|
-
const
|
|
670
|
+
const distAgentsDir = path3.join(projectRoot, "dist", "agents");
|
|
671
|
+
const useDistAgents = fs3.existsSync(distAgentsDir) && fs3.statSync(distAgentsDir).isDirectory();
|
|
672
|
+
const agentsDir = useDistAgents ? distAgentsDir : path3.join(projectRoot, "agents");
|
|
673
|
+
const agentsDirPrefix = useDistAgents ? "dist/agents" : "agents";
|
|
665
674
|
if (!fs3.existsSync(agentsDir) || !fs3.statSync(agentsDir).isDirectory()) {
|
|
666
675
|
return [];
|
|
667
676
|
}
|
|
668
|
-
const
|
|
677
|
+
const tsxEnabled = isTsxAvailable();
|
|
678
|
+
const files = fs3.readdirSync(agentsDir).filter((f) => f.endsWith(".js") || f.endsWith(".mjs") || tsxEnabled && f.endsWith(".ts")).sort();
|
|
669
679
|
const seen = /* @__PURE__ */ new Map();
|
|
670
680
|
for (const file of files) {
|
|
671
681
|
const filePath = path3.join(agentsDir, file);
|
|
@@ -675,11 +685,13 @@ var discoverAgents = async (projectRoot) => {
|
|
|
675
685
|
if (isPlatformAgentExport(exported) && !seen.has(exported.config.agent.name)) {
|
|
676
686
|
seen.set(exported.config.agent.name, {
|
|
677
687
|
config: exported.config,
|
|
678
|
-
entryPoint:
|
|
688
|
+
entryPoint: `${agentsDirPrefix}/${file}`
|
|
679
689
|
});
|
|
680
690
|
}
|
|
681
691
|
} catch (err) {
|
|
682
|
-
warn(
|
|
692
|
+
warn(
|
|
693
|
+
`Skipping ${agentsDirPrefix}/${file}: ${err instanceof Error ? err.message : String(err)}`
|
|
694
|
+
);
|
|
683
695
|
}
|
|
684
696
|
}
|
|
685
697
|
return [...seen.values()];
|
|
@@ -716,7 +728,10 @@ var discoverSkills = (projectRoot) => {
|
|
|
716
728
|
return skills;
|
|
717
729
|
};
|
|
718
730
|
var discoverConnectors = (projectRoot) => {
|
|
719
|
-
const
|
|
731
|
+
const distConnectorsDir = path3.join(projectRoot, "dist", "connectors");
|
|
732
|
+
const useDistConnectors = fs3.existsSync(distConnectorsDir) && fs3.statSync(distConnectorsDir).isDirectory();
|
|
733
|
+
const connectorsDir = useDistConnectors ? distConnectorsDir : path3.join(projectRoot, "connectors");
|
|
734
|
+
const connectorsDirPrefix = useDistConnectors ? "dist/connectors" : "connectors";
|
|
720
735
|
if (!fs3.existsSync(connectorsDir) || !fs3.statSync(connectorsDir).isDirectory()) {
|
|
721
736
|
return [];
|
|
722
737
|
}
|
|
@@ -727,17 +742,20 @@ var discoverConnectors = (projectRoot) => {
|
|
|
727
742
|
const name = entry.name;
|
|
728
743
|
if (!isValidEntityName(name)) {
|
|
729
744
|
warn(
|
|
730
|
-
`Skipping
|
|
745
|
+
`Skipping ${connectorsDirPrefix}/${name}: name must match [a-z0-9-] (lowercase, digits, hyphens only).`
|
|
731
746
|
);
|
|
732
747
|
continue;
|
|
733
748
|
}
|
|
734
749
|
const connDir = path3.join(connectorsDir, name);
|
|
735
750
|
const hasPackageJson = fs3.existsSync(path3.join(connDir, "package.json"));
|
|
736
751
|
const hasDockerfile = fs3.existsSync(path3.join(connDir, "Dockerfile"));
|
|
737
|
-
|
|
752
|
+
const hasIndexJs = fs3.existsSync(path3.join(connDir, "index.js"));
|
|
753
|
+
const hasIndexMjs = fs3.existsSync(path3.join(connDir, "index.mjs"));
|
|
754
|
+
const hasIndexTs = fs3.existsSync(path3.join(connDir, "index.ts"));
|
|
755
|
+
if (!hasPackageJson && !hasDockerfile && !hasIndexJs && !hasIndexMjs && !hasIndexTs) {
|
|
738
756
|
continue;
|
|
739
757
|
}
|
|
740
|
-
connectors.push({ name, path:
|
|
758
|
+
connectors.push({ name, path: `${connectorsDirPrefix}/${name}/` });
|
|
741
759
|
}
|
|
742
760
|
return connectors.sort((a, b) => a.name.localeCompare(b.name));
|
|
743
761
|
};
|
|
@@ -958,8 +976,16 @@ var fetchRemoteSchemas = async (creds, deps) => {
|
|
|
958
976
|
}
|
|
959
977
|
const agents = parseEndpointData(agentsRes, z12.array(agentSchemaValidator), "agents");
|
|
960
978
|
const queries = parseEndpointData(queriesRes, z12.array(querySchemaValidator), "queries");
|
|
961
|
-
const connectors = parseEndpointData(
|
|
962
|
-
|
|
979
|
+
const connectors = parseEndpointData(
|
|
980
|
+
connectorsRes,
|
|
981
|
+
z12.array(connectorSchemaValidator),
|
|
982
|
+
"connectors"
|
|
983
|
+
);
|
|
984
|
+
const pipelines = parseEndpointData(
|
|
985
|
+
pipelinesRes,
|
|
986
|
+
z12.array(pipelineSchemaValidator),
|
|
987
|
+
"pipelines"
|
|
988
|
+
);
|
|
963
989
|
const skills = parseEndpointData(skillsRes, z12.array(skillSchemaValidator), "skills");
|
|
964
990
|
return { agents, queries, connectors, pipelines, skills };
|
|
965
991
|
} finally {
|
|
@@ -1007,7 +1033,9 @@ var handleGenerate = async (parsed, deps) => {
|
|
|
1007
1033
|
try {
|
|
1008
1034
|
remote = await fetchRemoteSchemas(creds, deps);
|
|
1009
1035
|
} catch (err) {
|
|
1010
|
-
deps.log(
|
|
1036
|
+
deps.log(
|
|
1037
|
+
`Error fetching remote schemas: ${err instanceof Error ? err.message : String(err)}`
|
|
1038
|
+
);
|
|
1011
1039
|
return 1;
|
|
1012
1040
|
}
|
|
1013
1041
|
} else {
|
|
@@ -1089,7 +1117,7 @@ var buildDevBootstrap = (fileUrl, file) => [
|
|
|
1089
1117
|
` console.error("Error: " + ${JSON.stringify(file)} + " must export a PlatformAgent as default.");`,
|
|
1090
1118
|
` process.exit(1);`,
|
|
1091
1119
|
` }`,
|
|
1092
|
-
` const { runDev } = await import("@kraken-ai/platform");`,
|
|
1120
|
+
` const { runDev } = await import("@kraken-ai/platform/server");`,
|
|
1093
1121
|
` await runDev(a);`,
|
|
1094
1122
|
`})();`
|
|
1095
1123
|
].join("\n");
|