kly 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/dist/bin/config-builder-D5EtwOB3.mjs +3 -0
- package/dist/bin/kly.mjs +65 -18
- package/dist/bin/kly.mjs.map +1 -1
- package/dist/bin/launcher-Ex3ynZdE.mjs +3 -0
- package/dist/bin/permissions-C_WgoA3t.mjs +3 -0
- package/dist/bin/permissions-extractor-BfUPS0Tr.mjs +29 -0
- package/dist/bin/permissions-extractor-BfUPS0Tr.mjs.map +1 -0
- package/dist/types.d.mts +18 -1
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/bin/launcher-vTpgdO9n.mjs +0 -3
- package/dist/bin/permissions-2r_7ZqaH.mjs +0 -3
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { a as getAppIdentifier, c as listPermissions, d as savePermissions, i as clearAllPermissions, l as loadPermissions, o as getAppName, r as checkApiKeyPermission, s as getAppSandboxConfig, u as revokePermission } from "./kly.mjs";
|
|
2
|
+
|
|
3
|
+
export { checkApiKeyPermission, getAppIdentifier, getAppSandboxConfig };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/remote/permissions-extractor.ts
|
|
2
|
+
/**
|
|
3
|
+
* Extract declared permissions from a remote app
|
|
4
|
+
*
|
|
5
|
+
* This function safely loads the app definition to read its declared permissions
|
|
6
|
+
* WITHOUT executing the actual tool logic.
|
|
7
|
+
*
|
|
8
|
+
* @param entryPath - Absolute path to the app entry point
|
|
9
|
+
* @returns Declared permissions or undefined if not specified
|
|
10
|
+
*/
|
|
11
|
+
async function extractAppPermissions(entryPath) {
|
|
12
|
+
try {
|
|
13
|
+
const prevProgrammatic = process.env.KLY_PROGRAMMATIC;
|
|
14
|
+
process.env.KLY_PROGRAMMATIC = "true";
|
|
15
|
+
const appModule = await import(entryPath);
|
|
16
|
+
if (prevProgrammatic === void 0) delete process.env.KLY_PROGRAMMATIC;
|
|
17
|
+
else process.env.KLY_PROGRAMMATIC = prevProgrammatic;
|
|
18
|
+
if (appModule.default?.definition) return appModule.default.definition.permissions;
|
|
19
|
+
if (appModule.definition) return appModule.definition.permissions;
|
|
20
|
+
return;
|
|
21
|
+
} catch (error) {
|
|
22
|
+
console.warn(`⚠️ Could not extract permissions from app (${error instanceof Error ? error.message : "unknown error"})`);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
export { extractAppPermissions };
|
|
29
|
+
//# sourceMappingURL=permissions-extractor-BfUPS0Tr.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions-extractor-BfUPS0Tr.mjs","names":[],"sources":["../../src/remote/permissions-extractor.ts"],"sourcesContent":["import type { AppPermissions } from \"../types\";\n\n/**\n * Extract declared permissions from a remote app\n *\n * This function safely loads the app definition to read its declared permissions\n * WITHOUT executing the actual tool logic.\n *\n * @param entryPath - Absolute path to the app entry point\n * @returns Declared permissions or undefined if not specified\n */\nexport async function extractAppPermissions(\n entryPath: string,\n): Promise<AppPermissions | undefined> {\n try {\n // Temporarily mark as programmatic mode to avoid triggering CLI logic\n const prevProgrammatic = process.env.KLY_PROGRAMMATIC;\n process.env.KLY_PROGRAMMATIC = \"true\";\n\n // Dynamic import to load the app module\n const appModule = await import(entryPath);\n\n // Restore environment\n if (prevProgrammatic === undefined) {\n delete process.env.KLY_PROGRAMMATIC;\n } else {\n process.env.KLY_PROGRAMMATIC = prevProgrammatic;\n }\n\n // The app module should export a KlyApp instance\n // which has a definition.permissions field\n if (appModule.default?.definition) {\n return appModule.default.definition.permissions;\n }\n\n // Some apps might export the app directly\n if (appModule.definition) {\n return appModule.definition.permissions;\n }\n\n return undefined;\n } catch (error) {\n // If we can't extract permissions, return undefined\n // The calling code will fall back to asking for all permissions\n console.warn(\n `⚠️ Could not extract permissions from app (${error instanceof Error ? error.message : \"unknown error\"})`,\n );\n return undefined;\n }\n}\n"],"mappings":";;;;;;;;;;AAWA,eAAsB,sBACpB,WACqC;AACrC,KAAI;EAEF,MAAM,mBAAmB,QAAQ,IAAI;AACrC,UAAQ,IAAI,mBAAmB;EAG/B,MAAM,YAAY,MAAM,OAAO;AAG/B,MAAI,qBAAqB,OACvB,QAAO,QAAQ,IAAI;MAEnB,SAAQ,IAAI,mBAAmB;AAKjC,MAAI,UAAU,SAAS,WACrB,QAAO,UAAU,QAAQ,WAAW;AAItC,MAAI,UAAU,WACZ,QAAO,UAAU,WAAW;AAG9B;UACO,OAAO;AAGd,UAAQ,KACN,+CAA+C,iBAAiB,QAAQ,MAAM,UAAU,gBAAgB,GACzG;AACD"}
|
package/dist/types.d.mts
CHANGED
|
@@ -2,6 +2,10 @@ import { SandboxRuntimeConfig } from "@anthropic-ai/sandbox-runtime";
|
|
|
2
2
|
|
|
3
3
|
//#region src/types.d.ts
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Deep partial type - makes all properties optional recursively
|
|
7
|
+
*/
|
|
8
|
+
type DeepPartial<T> = { [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P] };
|
|
5
9
|
/**
|
|
6
10
|
* Standard Schema V1 interface (inlined to avoid external dependency)
|
|
7
11
|
* @see https://github.com/standard-schema/standard-schema
|
|
@@ -212,6 +216,10 @@ interface AppPermissions {
|
|
|
212
216
|
* - Filesystem: Current directory read/write only
|
|
213
217
|
* - Protected: ~/.kly, ~/.ssh, ~/.aws, ~/.gnupg always denied
|
|
214
218
|
*
|
|
219
|
+
* Special markers for filesystem paths:
|
|
220
|
+
* - "*": User's home directory (allows access to all non-sensitive files)
|
|
221
|
+
* Use this for apps that need broad filesystem access (like project generators)
|
|
222
|
+
*
|
|
215
223
|
* @example
|
|
216
224
|
* ```typescript
|
|
217
225
|
* // Minimal: just need GitHub API access
|
|
@@ -221,6 +229,15 @@ interface AppPermissions {
|
|
|
221
229
|
* }
|
|
222
230
|
* }
|
|
223
231
|
*
|
|
232
|
+
* // Allow access to all non-sensitive directories
|
|
233
|
+
* permissions: {
|
|
234
|
+
* sandbox: {
|
|
235
|
+
* filesystem: {
|
|
236
|
+
* allowWrite: ["*"] // Expands to user's home directory at runtime
|
|
237
|
+
* }
|
|
238
|
+
* }
|
|
239
|
+
* }
|
|
240
|
+
*
|
|
224
241
|
* // Full control
|
|
225
242
|
* permissions: {
|
|
226
243
|
* apiKeys: true, // LLM domains added automatically
|
|
@@ -236,7 +253,7 @@ interface AppPermissions {
|
|
|
236
253
|
* }
|
|
237
254
|
* ```
|
|
238
255
|
*/
|
|
239
|
-
sandbox?:
|
|
256
|
+
sandbox?: DeepPartial<SandboxRuntimeConfig>;
|
|
240
257
|
}
|
|
241
258
|
interface AppDefinition<TTools extends AnyTool[] = AnyTool[]> extends AppMetadata {
|
|
242
259
|
/** Array of tools */
|
package/dist/types.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"sourcesContent":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/types.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.mjs","names":["issues: ReadonlyArray<StandardSchemaV1.Issue>"],"sources":["../src/types.ts"],"sourcesContent":["import type { SandboxRuntimeConfig } from \"@anthropic-ai/sandbox-runtime\";\n\n/**\n * Standard Schema V1 interface (inlined to avoid external dependency)\n * @see https://github.com/standard-schema/standard-schema\n */\nexport interface StandardSchemaV1<Input = unknown, Output = Input> {\n readonly \"~standard\": StandardSchemaV1.Props<Input, Output>;\n}\n\nexport declare namespace StandardSchemaV1 {\n interface Props<Input = unknown, Output = Input> {\n readonly version: 1;\n readonly vendor: string;\n readonly validate: (\n value: unknown,\n ) => Result<Output> | Promise<Result<Output>>;\n readonly types?: Types<Input, Output>;\n }\n\n type Result<Output> = SuccessResult<Output> | FailureResult;\n\n interface SuccessResult<Output> {\n readonly value: Output;\n readonly issues?: undefined;\n }\n\n interface FailureResult {\n readonly issues: ReadonlyArray<Issue>;\n }\n\n interface Issue {\n readonly message: string;\n readonly path?: ReadonlyArray<PropertyKey | PathSegment>;\n }\n\n interface PathSegment {\n readonly key: PropertyKey;\n }\n\n interface Types<Input = unknown, Output = Input> {\n readonly input: Input;\n readonly output: Output;\n }\n}\n\n/**\n * Extract output type from a Standard Schema\n */\nexport type InferOutput<TSchema> =\n TSchema extends StandardSchemaV1<unknown, infer Output> ? Output : never;\n\n/**\n * Runtime execution mode\n */\nexport type RuntimeMode = \"cli\" | \"mcp\" | \"programmatic\";\n\n/**\n * Model configuration information (basic info without secrets)\n */\nexport interface ModelInfo {\n /** Model configuration name */\n name: string;\n /** Provider (openai, anthropic, etc.) */\n provider: string;\n /** Model name (e.g., gpt-4, claude-3-opus) */\n model?: string;\n /** Whether this is the current active model */\n isCurrent: boolean;\n}\n\n/**\n * Full model configuration including API keys\n */\nexport interface ModelConfig {\n /** Provider (openai, anthropic, etc.) */\n provider: string;\n /** Model name (e.g., gpt-4, claude-3-opus) */\n model?: string;\n /** API key */\n apiKey?: string;\n /** Base URL */\n baseURL?: string;\n}\n\n/**\n * Models management interface\n * Provides access to configured LLM models and their credentials\n */\nexport interface ModelsContext {\n /**\n * List all configured models (without API keys)\n */\n list(): ModelInfo[];\n\n /**\n * Get the current active model info\n */\n getCurrent(): ModelInfo | null;\n\n /**\n * Get a specific model info by name\n */\n get(name: string): ModelInfo | null;\n\n /**\n * Get full configuration for a model (including API key)\n *\n * ⚠️ SECURITY: This method requires user permission\n * The first time this is called, the user will be prompted to grant permission.\n * Permission can be granted for:\n * - One time only\n * - Always for this app\n * - Denied\n *\n * @param name - Model name (if not specified, returns current model)\n * @returns Full config or null if not found/configured\n * @throws Error if permission is denied\n *\n * @example\n * ```typescript\n * const config = await context.models.getConfigAsync();\n * if (config) {\n * // Use config.provider, config.apiKey, config.model etc.\n * }\n * ```\n */\n getConfigAsync(name?: string): Promise<ModelConfig | null>;\n}\n\n/**\n * Context passed to the execute function\n */\nexport interface ExecuteContext {\n /** Current runtime mode */\n mode: RuntimeMode;\n /** Abort signal for cancellation */\n abortSignal?: AbortSignal;\n /**\n * Models management\n * Access configured LLM models and their credentials\n * @example\n * ```typescript\n * const config = context.models.getConfig();\n * if (config) {\n * // Use config.provider, config.apiKey, config.model etc.\n * // to create your own AI SDK provider instance\n * }\n * ```\n */\n models: ModelsContext;\n}\n\n/**\n * Tool definition (Vercel AI SDK style)\n * Core building block that can be used standalone or within defineApp\n */\nexport interface ToolDefinition<\n TInput extends StandardSchemaV1,\n TResult = unknown,\n> {\n /** Description of what the tool does (used by LLM for tool selection) */\n description?: string;\n /** Input schema (Standard Schema compliant: Zod, Valibot, ArkType, etc.) */\n inputSchema: TInput;\n /** Execute function that performs the tool's action */\n execute: (\n args: InferOutput<TInput>,\n context: ExecuteContext,\n ) => Promise<TResult>;\n}\n\n/**\n * Tool instance returned by tool()\n * Each tool has a name for CLI subcommand and MCP registration\n */\nexport interface Tool<TInput extends StandardSchemaV1, TResult = unknown>\n extends ToolDefinition<TInput, TResult> {\n /** Tool name (used as subcommand in CLI, tool name in MCP) */\n name: string;\n /** Type brand for tool identification */\n readonly _brand: \"Tool\";\n}\n\n/**\n * Any tool type for collections\n */\nexport type AnyTool = Tool<StandardSchemaV1, unknown>;\n\n/**\n * Base app metadata\n */\nexport interface AppMetadata {\n /** App name */\n name: string;\n /** Semantic version */\n version: string;\n /** App description */\n description: string;\n}\n\n/**\n * App definition with tools array\n *\n * @example\n * ```typescript\n * defineApp({\n * name: \"my-app\",\n * version: \"0.1.0\",\n * description: \"My CLI app\",\n * tools: [greetTool, farewellTool],\n * instructions: \"When user expresses greeting intent, prefer the greet tool\",\n * })\n * ```\n */\n/**\n * App permissions declaration\n * Simplified user-friendly interface for declaring app permissions\n */\nexport interface AppPermissions {\n /**\n * API Keys access - needed to call LLM APIs\n *\n * When enabled:\n * - Grants access to models.getConfigAsync() to retrieve API keys\n * - Automatically allows network access to common LLM API domains:\n * • api.openai.com\n * • *.anthropic.com\n * • generativelanguage.googleapis.com\n * • api.deepseek.com\n *\n * @default false\n */\n apiKeys?: boolean;\n\n /**\n * Sandbox configuration\n * Uses @anthropic-ai/sandbox-runtime configuration directly\n *\n * Defaults when not specified:\n * - Network: No access (apiKeys=true adds LLM APIs automatically)\n * - Filesystem: Current directory read/write only\n * - Protected: ~/.kly, ~/.ssh, ~/.aws, ~/.gnupg always denied\n *\n * @example\n * ```typescript\n * // Minimal: just need GitHub API access\n * permissions: {\n * sandbox: {\n * network: { allowedDomains: [\"api.github.com\"] }\n * }\n * }\n *\n * // Full control\n * permissions: {\n * apiKeys: true, // LLM domains added automatically\n * sandbox: {\n * network: {\n * allowedDomains: [\"api.github.com\"] // Add more domains\n * },\n * filesystem: {\n * allowWrite: [\"./output\", \"/tmp\"],\n * denyRead: [\"/etc\"]\n * }\n * }\n * }\n * ```\n */\n sandbox?:
|
|
1
|
+
{"version":3,"file":"types.mjs","names":["issues: ReadonlyArray<StandardSchemaV1.Issue>"],"sources":["../src/types.ts"],"sourcesContent":["import type { SandboxRuntimeConfig } from \"@anthropic-ai/sandbox-runtime\";\n\n/**\n * Deep partial type - makes all properties optional recursively\n */\ntype DeepPartial<T> = {\n [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];\n};\n\n/**\n * Standard Schema V1 interface (inlined to avoid external dependency)\n * @see https://github.com/standard-schema/standard-schema\n */\nexport interface StandardSchemaV1<Input = unknown, Output = Input> {\n readonly \"~standard\": StandardSchemaV1.Props<Input, Output>;\n}\n\nexport declare namespace StandardSchemaV1 {\n interface Props<Input = unknown, Output = Input> {\n readonly version: 1;\n readonly vendor: string;\n readonly validate: (\n value: unknown,\n ) => Result<Output> | Promise<Result<Output>>;\n readonly types?: Types<Input, Output>;\n }\n\n type Result<Output> = SuccessResult<Output> | FailureResult;\n\n interface SuccessResult<Output> {\n readonly value: Output;\n readonly issues?: undefined;\n }\n\n interface FailureResult {\n readonly issues: ReadonlyArray<Issue>;\n }\n\n interface Issue {\n readonly message: string;\n readonly path?: ReadonlyArray<PropertyKey | PathSegment>;\n }\n\n interface PathSegment {\n readonly key: PropertyKey;\n }\n\n interface Types<Input = unknown, Output = Input> {\n readonly input: Input;\n readonly output: Output;\n }\n}\n\n/**\n * Extract output type from a Standard Schema\n */\nexport type InferOutput<TSchema> =\n TSchema extends StandardSchemaV1<unknown, infer Output> ? Output : never;\n\n/**\n * Runtime execution mode\n */\nexport type RuntimeMode = \"cli\" | \"mcp\" | \"programmatic\";\n\n/**\n * Model configuration information (basic info without secrets)\n */\nexport interface ModelInfo {\n /** Model configuration name */\n name: string;\n /** Provider (openai, anthropic, etc.) */\n provider: string;\n /** Model name (e.g., gpt-4, claude-3-opus) */\n model?: string;\n /** Whether this is the current active model */\n isCurrent: boolean;\n}\n\n/**\n * Full model configuration including API keys\n */\nexport interface ModelConfig {\n /** Provider (openai, anthropic, etc.) */\n provider: string;\n /** Model name (e.g., gpt-4, claude-3-opus) */\n model?: string;\n /** API key */\n apiKey?: string;\n /** Base URL */\n baseURL?: string;\n}\n\n/**\n * Models management interface\n * Provides access to configured LLM models and their credentials\n */\nexport interface ModelsContext {\n /**\n * List all configured models (without API keys)\n */\n list(): ModelInfo[];\n\n /**\n * Get the current active model info\n */\n getCurrent(): ModelInfo | null;\n\n /**\n * Get a specific model info by name\n */\n get(name: string): ModelInfo | null;\n\n /**\n * Get full configuration for a model (including API key)\n *\n * ⚠️ SECURITY: This method requires user permission\n * The first time this is called, the user will be prompted to grant permission.\n * Permission can be granted for:\n * - One time only\n * - Always for this app\n * - Denied\n *\n * @param name - Model name (if not specified, returns current model)\n * @returns Full config or null if not found/configured\n * @throws Error if permission is denied\n *\n * @example\n * ```typescript\n * const config = await context.models.getConfigAsync();\n * if (config) {\n * // Use config.provider, config.apiKey, config.model etc.\n * }\n * ```\n */\n getConfigAsync(name?: string): Promise<ModelConfig | null>;\n}\n\n/**\n * Context passed to the execute function\n */\nexport interface ExecuteContext {\n /** Current runtime mode */\n mode: RuntimeMode;\n /** Abort signal for cancellation */\n abortSignal?: AbortSignal;\n /**\n * Models management\n * Access configured LLM models and their credentials\n * @example\n * ```typescript\n * const config = context.models.getConfig();\n * if (config) {\n * // Use config.provider, config.apiKey, config.model etc.\n * // to create your own AI SDK provider instance\n * }\n * ```\n */\n models: ModelsContext;\n}\n\n/**\n * Tool definition (Vercel AI SDK style)\n * Core building block that can be used standalone or within defineApp\n */\nexport interface ToolDefinition<\n TInput extends StandardSchemaV1,\n TResult = unknown,\n> {\n /** Description of what the tool does (used by LLM for tool selection) */\n description?: string;\n /** Input schema (Standard Schema compliant: Zod, Valibot, ArkType, etc.) */\n inputSchema: TInput;\n /** Execute function that performs the tool's action */\n execute: (\n args: InferOutput<TInput>,\n context: ExecuteContext,\n ) => Promise<TResult>;\n}\n\n/**\n * Tool instance returned by tool()\n * Each tool has a name for CLI subcommand and MCP registration\n */\nexport interface Tool<TInput extends StandardSchemaV1, TResult = unknown>\n extends ToolDefinition<TInput, TResult> {\n /** Tool name (used as subcommand in CLI, tool name in MCP) */\n name: string;\n /** Type brand for tool identification */\n readonly _brand: \"Tool\";\n}\n\n/**\n * Any tool type for collections\n */\nexport type AnyTool = Tool<StandardSchemaV1, unknown>;\n\n/**\n * Base app metadata\n */\nexport interface AppMetadata {\n /** App name */\n name: string;\n /** Semantic version */\n version: string;\n /** App description */\n description: string;\n}\n\n/**\n * App definition with tools array\n *\n * @example\n * ```typescript\n * defineApp({\n * name: \"my-app\",\n * version: \"0.1.0\",\n * description: \"My CLI app\",\n * tools: [greetTool, farewellTool],\n * instructions: \"When user expresses greeting intent, prefer the greet tool\",\n * })\n * ```\n */\n/**\n * App permissions declaration\n * Simplified user-friendly interface for declaring app permissions\n */\nexport interface AppPermissions {\n /**\n * API Keys access - needed to call LLM APIs\n *\n * When enabled:\n * - Grants access to models.getConfigAsync() to retrieve API keys\n * - Automatically allows network access to common LLM API domains:\n * • api.openai.com\n * • *.anthropic.com\n * • generativelanguage.googleapis.com\n * • api.deepseek.com\n *\n * @default false\n */\n apiKeys?: boolean;\n\n /**\n * Sandbox configuration\n * Uses @anthropic-ai/sandbox-runtime configuration directly\n *\n * Defaults when not specified:\n * - Network: No access (apiKeys=true adds LLM APIs automatically)\n * - Filesystem: Current directory read/write only\n * - Protected: ~/.kly, ~/.ssh, ~/.aws, ~/.gnupg always denied\n *\n * Special markers for filesystem paths:\n * - \"*\": User's home directory (allows access to all non-sensitive files)\n * Use this for apps that need broad filesystem access (like project generators)\n *\n * @example\n * ```typescript\n * // Minimal: just need GitHub API access\n * permissions: {\n * sandbox: {\n * network: { allowedDomains: [\"api.github.com\"] }\n * }\n * }\n *\n * // Allow access to all non-sensitive directories\n * permissions: {\n * sandbox: {\n * filesystem: {\n * allowWrite: [\"*\"] // Expands to user's home directory at runtime\n * }\n * }\n * }\n *\n * // Full control\n * permissions: {\n * apiKeys: true, // LLM domains added automatically\n * sandbox: {\n * network: {\n * allowedDomains: [\"api.github.com\"] // Add more domains\n * },\n * filesystem: {\n * allowWrite: [\"./output\", \"/tmp\"],\n * denyRead: [\"/etc\"]\n * }\n * }\n * }\n * ```\n */\n sandbox?: DeepPartial<SandboxRuntimeConfig>;\n}\n\nexport interface AppDefinition<TTools extends AnyTool[] = AnyTool[]>\n extends AppMetadata {\n /** Array of tools */\n tools: TTools;\n /**\n * AI instructions for Skill mode\n * Hints for AI routing when this app is composed with others\n */\n instructions?: string;\n /**\n * Permissions required by this app\n * Declare upfront what your app needs to access\n * @example\n * ```typescript\n * permissions: {\n * apiKeys: true,\n * network: { allow: \"llm-apis\" }\n * }\n * ```\n */\n permissions?: AppPermissions;\n}\n\n/**\n * Kly app instance returned by defineApp\n */\nexport interface KlyApp<TTools extends AnyTool[] = AnyTool[]> {\n /** Original app configuration */\n readonly definition: AppDefinition<TTools>;\n /** Execute a specific tool by name */\n execute(toolName: string, args?: Record<string, unknown>): Promise<unknown>;\n /** Get all available tools */\n readonly tools: Map<string, AnyTool>;\n}\n\n/**\n * Validation error with structured issues\n */\nexport class ValidationError extends Error {\n constructor(public readonly issues: ReadonlyArray<StandardSchemaV1.Issue>) {\n const message = issues\n .map((issue) => {\n const path = issue.path\n ?.map((p) => (typeof p === \"object\" ? p.key : p))\n .join(\".\");\n return path ? `${path}: ${issue.message}` : issue.message;\n })\n .join(\"\\n\");\n super(message);\n this.name = \"ValidationError\";\n }\n}\n"],"mappings":";;;;AAyUA,IAAa,kBAAb,cAAqC,MAAM;CACzC,YAAY,AAAgBA,QAA+C;EACzE,MAAM,UAAU,OACb,KAAK,UAAU;GACd,MAAM,OAAO,MAAM,MACf,KAAK,MAAO,OAAO,MAAM,WAAW,EAAE,MAAM,EAAG,CAChD,KAAK,IAAI;AACZ,UAAO,OAAO,GAAG,KAAK,IAAI,MAAM,YAAY,MAAM;IAClD,CACD,KAAK,KAAK;AACb,QAAM,QAAQ;EATY;AAU1B,OAAK,OAAO"}
|
package/package.json
CHANGED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { a as getAppSandboxConfig, c as revokePermission, i as getAppName, l as savePermissions, n as clearAllPermissions, o as listPermissions, r as getAppIdentifier, s as loadPermissions, t as checkApiKeyPermission } from "./kly.mjs";
|
|
2
|
-
|
|
3
|
-
export { checkApiKeyPermission, getAppIdentifier, getAppSandboxConfig };
|