@lakitu/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/README.md +166 -0
  2. package/convex/_generated/api.d.ts +45 -0
  3. package/convex/_generated/api.js +23 -0
  4. package/convex/_generated/dataModel.d.ts +58 -0
  5. package/convex/_generated/server.d.ts +143 -0
  6. package/convex/_generated/server.js +93 -0
  7. package/convex/cloud/CLAUDE.md +238 -0
  8. package/convex/cloud/_generated/api.ts +84 -0
  9. package/convex/cloud/_generated/component.ts +861 -0
  10. package/convex/cloud/_generated/dataModel.ts +60 -0
  11. package/convex/cloud/_generated/server.ts +156 -0
  12. package/convex/cloud/convex.config.ts +16 -0
  13. package/convex/cloud/index.ts +29 -0
  14. package/convex/cloud/intentSchema/generate.ts +447 -0
  15. package/convex/cloud/intentSchema/index.ts +16 -0
  16. package/convex/cloud/intentSchema/types.ts +418 -0
  17. package/convex/cloud/ksaPolicy.ts +554 -0
  18. package/convex/cloud/mail.ts +92 -0
  19. package/convex/cloud/schema.ts +322 -0
  20. package/convex/cloud/utils/kanbanContext.ts +229 -0
  21. package/convex/cloud/workflows/agentBoard.ts +451 -0
  22. package/convex/cloud/workflows/agentPrompt.ts +272 -0
  23. package/convex/cloud/workflows/agentThread.ts +374 -0
  24. package/convex/cloud/workflows/compileSandbox.ts +146 -0
  25. package/convex/cloud/workflows/crudBoard.ts +217 -0
  26. package/convex/cloud/workflows/crudKSAs.ts +262 -0
  27. package/convex/cloud/workflows/crudLorobeads.ts +371 -0
  28. package/convex/cloud/workflows/crudSkills.ts +205 -0
  29. package/convex/cloud/workflows/crudThreads.ts +708 -0
  30. package/convex/cloud/workflows/lifecycleSandbox.ts +1396 -0
  31. package/convex/cloud/workflows/sandboxConvex.ts +1046 -0
  32. package/convex/sandbox/README.md +90 -0
  33. package/convex/sandbox/_generated/api.d.ts +2934 -0
  34. package/convex/sandbox/_generated/api.js +23 -0
  35. package/convex/sandbox/_generated/dataModel.d.ts +60 -0
  36. package/convex/sandbox/_generated/server.d.ts +143 -0
  37. package/convex/sandbox/_generated/server.js +93 -0
  38. package/convex/sandbox/actions/bash.ts +130 -0
  39. package/convex/sandbox/actions/browser.ts +282 -0
  40. package/convex/sandbox/actions/file.ts +336 -0
  41. package/convex/sandbox/actions/lsp.ts +325 -0
  42. package/convex/sandbox/actions/pdf.ts +119 -0
  43. package/convex/sandbox/agent/codeExecLoop.ts +535 -0
  44. package/convex/sandbox/agent/decisions.ts +284 -0
  45. package/convex/sandbox/agent/index.ts +515 -0
  46. package/convex/sandbox/agent/subagents.ts +651 -0
  47. package/convex/sandbox/brandResearch/index.ts +417 -0
  48. package/convex/sandbox/context/index.ts +7 -0
  49. package/convex/sandbox/context/session.ts +402 -0
  50. package/convex/sandbox/convex.config.ts +17 -0
  51. package/convex/sandbox/index.ts +51 -0
  52. package/convex/sandbox/nodeActions/codeExec.ts +130 -0
  53. package/convex/sandbox/planning/beads.ts +187 -0
  54. package/convex/sandbox/planning/index.ts +8 -0
  55. package/convex/sandbox/planning/sync.ts +194 -0
  56. package/convex/sandbox/prompts/codeExec.ts +852 -0
  57. package/convex/sandbox/prompts/modes.ts +231 -0
  58. package/convex/sandbox/prompts/system.ts +142 -0
  59. package/convex/sandbox/schema.ts +510 -0
  60. package/convex/sandbox/state/artifacts.ts +99 -0
  61. package/convex/sandbox/state/checkpoints.ts +341 -0
  62. package/convex/sandbox/state/files.ts +383 -0
  63. package/convex/sandbox/state/index.ts +10 -0
  64. package/convex/sandbox/state/verification.actions.ts +268 -0
  65. package/convex/sandbox/state/verification.ts +101 -0
  66. package/convex/sandbox/tsconfig.json +25 -0
  67. package/convex/sandbox/utils/codeExecHelpers.ts +52 -0
  68. package/dist/cli/commands/build.d.ts +19 -0
  69. package/dist/cli/commands/build.d.ts.map +1 -0
  70. package/dist/cli/commands/build.js +223 -0
  71. package/dist/cli/commands/init.d.ts +16 -0
  72. package/dist/cli/commands/init.d.ts.map +1 -0
  73. package/dist/cli/commands/init.js +148 -0
  74. package/dist/cli/commands/publish.d.ts +12 -0
  75. package/dist/cli/commands/publish.d.ts.map +1 -0
  76. package/dist/cli/commands/publish.js +33 -0
  77. package/dist/cli/index.d.ts +14 -0
  78. package/dist/cli/index.d.ts.map +1 -0
  79. package/dist/cli/index.js +40 -0
  80. package/dist/sdk/builders.d.ts +104 -0
  81. package/dist/sdk/builders.d.ts.map +1 -0
  82. package/dist/sdk/builders.js +214 -0
  83. package/dist/sdk/index.d.ts +29 -0
  84. package/dist/sdk/index.d.ts.map +1 -0
  85. package/dist/sdk/index.js +38 -0
  86. package/dist/sdk/types.d.ts +107 -0
  87. package/dist/sdk/types.d.ts.map +1 -0
  88. package/dist/sdk/types.js +6 -0
  89. package/ksa/README.md +263 -0
  90. package/ksa/_generated/REFERENCE.md +2954 -0
  91. package/ksa/_generated/registry.ts +257 -0
  92. package/ksa/_shared/configReader.ts +302 -0
  93. package/ksa/_shared/configSchemas.ts +649 -0
  94. package/ksa/_shared/gateway.ts +175 -0
  95. package/ksa/_shared/ksaBehaviors.ts +411 -0
  96. package/ksa/_shared/ksaProxy.ts +248 -0
  97. package/ksa/_shared/localDb.ts +302 -0
  98. package/ksa/index.ts +134 -0
  99. package/package.json +93 -0
  100. package/runtime/browser/agent-browser.ts +330 -0
  101. package/runtime/entrypoint.ts +194 -0
  102. package/runtime/lsp/manager.ts +366 -0
  103. package/runtime/pdf/pdf-generator.ts +50 -0
  104. package/runtime/pdf/renderer.ts +357 -0
  105. package/runtime/pdf/schema.ts +97 -0
  106. package/runtime/services/file-watcher.ts +191 -0
  107. package/template/build.ts +307 -0
  108. package/template/e2b/Dockerfile +69 -0
  109. package/template/e2b/e2b.toml +13 -0
  110. package/template/e2b/prebuild.sh +68 -0
  111. package/template/e2b/start.sh +14 -0
@@ -0,0 +1,248 @@
1
+ /**
2
+ * KSA Proxy - Framework-Level Instrumentation
3
+ *
4
+ * This is the core of the local DB integration framework.
5
+ * Wraps KSA modules with a Proxy that automatically applies behaviors
6
+ * like caching, file tracking, and call logging.
7
+ *
8
+ * Usage:
9
+ * ```typescript
10
+ * import * as fileRaw from "./file";
11
+ * import { createKSAProxy } from "./_shared/ksaProxy";
12
+ *
13
+ * export const file = createKSAProxy("file", fileRaw);
14
+ * ```
15
+ *
16
+ * The proxy is transparent to agents - they import and use KSAs normally,
17
+ * and the framework automatically applies behaviors based on config.
18
+ */
19
+
20
+ import { getBehavior, type HookContext, type BeforeHookResult } from "./ksaBehaviors";
21
+ import { getFrameworkConfigForKSA } from "./configReader";
22
+ import type { FrameworkConfig } from "./configSchemas";
23
+
24
+ // ============================================================================
25
+ // Types
26
+ // ============================================================================
27
+
28
+ /** Any object that can be proxied (KSA module) */
29
+ type ProxiableModule = Record<string, unknown>;
30
+
31
+ /** Options for creating a KSA proxy */
32
+ export interface ProxyOptions {
33
+ /** Override framework config (for testing) */
34
+ config?: Partial<FrameworkConfig>;
35
+ /** Disable all behaviors (passthrough mode) */
36
+ disabled?: boolean;
37
+ }
38
+
39
+ // ============================================================================
40
+ // Proxy Factory
41
+ // ============================================================================
42
+
43
+ /**
44
+ * Create a proxied version of a KSA module.
45
+ *
46
+ * The proxy wraps all exported functions and automatically applies
47
+ * before/after hooks based on the KSA's behavior configuration.
48
+ *
49
+ * @param ksaName - Name of the KSA (e.g., "file", "web")
50
+ * @param ksaModule - The raw KSA module
51
+ * @param options - Optional configuration overrides
52
+ * @returns Proxied module with automatic behaviors
53
+ *
54
+ * @example
55
+ * // In ksa/index.ts
56
+ * import * as fileRaw from "./file";
57
+ * export const file = createKSAProxy("file", fileRaw);
58
+ *
59
+ * // Agent code (unchanged)
60
+ * import { file } from "./ksa";
61
+ * const content = await file.read("/path/to/file.txt");
62
+ * // Automatically tracked in local DB!
63
+ */
64
+ export function createKSAProxy<T extends ProxiableModule>(
65
+ ksaName: string,
66
+ ksaModule: T,
67
+ options?: ProxyOptions
68
+ ): T {
69
+ // In passthrough mode, return the raw module
70
+ if (options?.disabled) {
71
+ return ksaModule;
72
+ }
73
+
74
+ // Get framework config for this KSA
75
+ const config = {
76
+ ...getFrameworkConfigForKSA(ksaName),
77
+ ...options?.config,
78
+ };
79
+
80
+ return new Proxy(ksaModule, {
81
+ get(target, prop: string | symbol) {
82
+ const original = target[prop as keyof T];
83
+
84
+ // Only wrap functions
85
+ if (typeof original !== "function") {
86
+ return original;
87
+ }
88
+
89
+ // Don't wrap internal properties
90
+ if (typeof prop === "symbol" || prop.startsWith("_")) {
91
+ return original;
92
+ }
93
+
94
+ // Return wrapped function
95
+ return createWrappedFunction(ksaName, prop, original as Function, config);
96
+ },
97
+ });
98
+ }
99
+
100
+ /**
101
+ * Create a wrapped version of a KSA function with automatic behaviors.
102
+ */
103
+ function createWrappedFunction(
104
+ ksaName: string,
105
+ funcName: string,
106
+ original: Function,
107
+ config: FrameworkConfig
108
+ ): (...args: unknown[]) => Promise<unknown> {
109
+ return async function wrappedFunction(...args: unknown[]): Promise<unknown> {
110
+ const startTime = Date.now();
111
+
112
+ // Build hook context
113
+ const ctx: HookContext = {
114
+ ksaName,
115
+ funcName,
116
+ args,
117
+ config,
118
+ startTime,
119
+ };
120
+
121
+ // Get behaviors for this function
122
+ const { before, after } = getBehavior(ksaName, funcName);
123
+
124
+ // Execute before hook (may return cached result)
125
+ if (before) {
126
+ try {
127
+ const beforeResult = await before(ctx);
128
+ if (beforeResult && beforeResult.skipExecution) {
129
+ // Return cached result
130
+ return beforeResult.cachedResult;
131
+ }
132
+ } catch (e) {
133
+ // Before hook failed, continue with execution
134
+ console.warn(`[KSA Proxy] Before hook failed for ${ksaName}.${funcName}:`, e);
135
+ }
136
+ }
137
+
138
+ // Execute original function
139
+ let result: unknown;
140
+ let error: Error | undefined;
141
+
142
+ try {
143
+ result = await original.apply(null, args);
144
+ } catch (e) {
145
+ error = e instanceof Error ? e : new Error(String(e));
146
+ throw error;
147
+ } finally {
148
+ // Execute after hook (fire-and-forget for performance)
149
+ if (after) {
150
+ try {
151
+ // Don't await - fire and forget
152
+ Promise.resolve(after(ctx, result, error)).catch((e) => {
153
+ console.warn(`[KSA Proxy] After hook failed for ${ksaName}.${funcName}:`, e);
154
+ });
155
+ } catch (e) {
156
+ console.warn(`[KSA Proxy] After hook failed for ${ksaName}.${funcName}:`, e);
157
+ }
158
+ }
159
+ }
160
+
161
+ return result;
162
+ };
163
+ }
164
+
165
+ // ============================================================================
166
+ // Bulk Proxy Creation
167
+ // ============================================================================
168
+
169
+ /**
170
+ * Create proxies for multiple KSA modules at once.
171
+ *
172
+ * @param modules - Map of KSA name to raw module
173
+ * @param options - Optional configuration overrides
174
+ * @returns Map of KSA name to proxied module
175
+ *
176
+ * @example
177
+ * import * as file from "./file";
178
+ * import * as web from "./web";
179
+ *
180
+ * const proxied = createKSAProxies({ file, web });
181
+ * export const { file: fileProxy, web: webProxy } = proxied;
182
+ */
183
+ export function createKSAProxies<T extends Record<string, ProxiableModule>>(
184
+ modules: T,
185
+ options?: ProxyOptions
186
+ ): T {
187
+ const result = {} as T;
188
+
189
+ for (const [name, module] of Object.entries(modules)) {
190
+ result[name as keyof T] = createKSAProxy(name, module, options) as T[keyof T];
191
+ }
192
+
193
+ return result;
194
+ }
195
+
196
+ // ============================================================================
197
+ // Passthrough Mode
198
+ // ============================================================================
199
+
200
+ /**
201
+ * Check if proxy behaviors should be disabled.
202
+ *
203
+ * Behaviors are disabled when:
204
+ * - LAKITU_PROXY_DISABLED=true environment variable is set
205
+ * - Running in test mode (NODE_ENV=test)
206
+ */
207
+ export function isProxyDisabled(): boolean {
208
+ return (
209
+ process.env.LAKITU_PROXY_DISABLED === "true" ||
210
+ process.env.NODE_ENV === "test"
211
+ );
212
+ }
213
+
214
+ /**
215
+ * Create a KSA proxy with automatic passthrough detection.
216
+ * Uses isProxyDisabled() to determine if behaviors should be applied.
217
+ */
218
+ export function createKSAProxyAuto<T extends ProxiableModule>(
219
+ ksaName: string,
220
+ ksaModule: T,
221
+ options?: Omit<ProxyOptions, "disabled">
222
+ ): T {
223
+ return createKSAProxy(ksaName, ksaModule, {
224
+ ...options,
225
+ disabled: isProxyDisabled(),
226
+ });
227
+ }
228
+
229
+ // ============================================================================
230
+ // Debug Utilities
231
+ // ============================================================================
232
+
233
+ /**
234
+ * Get debug info about the proxy configuration for a KSA.
235
+ */
236
+ export function getProxyDebugInfo(ksaName: string): {
237
+ config: FrameworkConfig;
238
+ isDisabled: boolean;
239
+ hasBehaviors: boolean;
240
+ } {
241
+ const config = getFrameworkConfigForKSA(ksaName);
242
+
243
+ return {
244
+ config,
245
+ isDisabled: isProxyDisabled(),
246
+ hasBehaviors: true, // All KSAs have at least default behaviors
247
+ };
248
+ }
@@ -0,0 +1,302 @@
1
+ /**
2
+ * Local DB Client - Sandbox Convex Integration
3
+ *
4
+ * Shared client for calling the local Convex backend running in the E2B sandbox.
5
+ * This is the foundation for automatic state tracking, caching, and session persistence.
6
+ *
7
+ * Key differences from gateway.ts:
8
+ * - Calls LOCAL Convex at http://localhost:3210 (not cloud)
9
+ * - No JWT required (sandbox is trusted)
10
+ * - Designed for high-frequency, low-latency operations
11
+ *
12
+ * @example
13
+ * import { localDb, getSessionId } from './_shared/localDb';
14
+ *
15
+ * // Blocking query
16
+ * const files = await localDb.query('state/files:getByThread', { threadId });
17
+ *
18
+ * // Blocking mutation
19
+ * const id = await localDb.mutate('planning/beads:create', { title: 'Task' });
20
+ *
21
+ * // Fire-and-forget (non-blocking)
22
+ * localDb.fire('state/files:trackFileAccess', { path, operation: 'read' });
23
+ */
24
+
25
+ import { readFileSync, existsSync } from "fs";
26
+
27
+ // ============================================================================
28
+ // Environment Loading
29
+ // ============================================================================
30
+
31
+ function loadEnvFile(): Record<string, string> {
32
+ const envPath = "/home/user/.env";
33
+ if (!existsSync(envPath)) return {};
34
+
35
+ try {
36
+ const content = readFileSync(envPath, "utf-8");
37
+ const envVars: Record<string, string> = {};
38
+ for (const line of content.split("\n")) {
39
+ const match = line.match(/^export\s+(\w+)="([^"]*)"/);
40
+ if (match) {
41
+ envVars[match[1]] = match[2];
42
+ }
43
+ }
44
+ return envVars;
45
+ } catch {
46
+ return {};
47
+ }
48
+ }
49
+
50
+ const envFile = loadEnvFile();
51
+
52
+ // Local Convex URL (sandbox backend, NOT cloud gateway)
53
+ const LOCAL_CONVEX_URL = process.env.CONVEX_URL || envFile.CONVEX_URL || "http://localhost:3210";
54
+
55
+ // Session identifiers
56
+ export const SESSION_ID = process.env.SESSION_ID || envFile.SESSION_ID || `session_${Date.now()}`;
57
+ export const THREAD_ID = process.env.THREAD_ID || envFile.THREAD_ID;
58
+ export const CARD_ID = process.env.CARD_ID || envFile.CARD_ID;
59
+
60
+ // ============================================================================
61
+ // Path Conversion
62
+ // ============================================================================
63
+
64
+ /**
65
+ * Convert dot-notation path to Convex HTTP API format.
66
+ * "planning.beads.create" -> "planning/beads:create"
67
+ */
68
+ function toConvexPath(dotPath: string): string {
69
+ const parts = dotPath.split(".");
70
+ const funcName = parts.pop()!;
71
+ const modulePath = parts.join("/");
72
+ return `${modulePath}:${funcName}`;
73
+ }
74
+
75
+ // ============================================================================
76
+ // Core Client Functions
77
+ // ============================================================================
78
+
79
+ /**
80
+ * Execute a query on local Convex (blocking).
81
+ *
82
+ * @param path - Dot-notation path (e.g., 'state/files.getByPath')
83
+ * @param args - Query arguments
84
+ * @returns Query result
85
+ */
86
+ async function query<T = unknown>(
87
+ path: string,
88
+ args: Record<string, unknown> = {}
89
+ ): Promise<T> {
90
+ const convexPath = toConvexPath(path);
91
+
92
+ const response = await fetch(`${LOCAL_CONVEX_URL}/api/query`, {
93
+ method: "POST",
94
+ headers: { "Content-Type": "application/json" },
95
+ body: JSON.stringify({ path: convexPath, args, format: "json" }),
96
+ });
97
+
98
+ if (!response.ok) {
99
+ const text = await response.text();
100
+ throw new Error(`Local Convex query error (${response.status}): ${text}`);
101
+ }
102
+
103
+ const result = await response.json();
104
+ return result.value as T;
105
+ }
106
+
107
+ /**
108
+ * Execute a mutation on local Convex (blocking).
109
+ *
110
+ * @param path - Dot-notation path (e.g., 'state/files.trackFileAccess')
111
+ * @param args - Mutation arguments
112
+ * @returns Mutation result
113
+ */
114
+ async function mutate<T = unknown>(
115
+ path: string,
116
+ args: Record<string, unknown> = {}
117
+ ): Promise<T> {
118
+ const convexPath = toConvexPath(path);
119
+
120
+ const response = await fetch(`${LOCAL_CONVEX_URL}/api/mutation`, {
121
+ method: "POST",
122
+ headers: { "Content-Type": "application/json" },
123
+ body: JSON.stringify({ path: convexPath, args, format: "json" }),
124
+ });
125
+
126
+ if (!response.ok) {
127
+ const text = await response.text();
128
+ throw new Error(`Local Convex mutation error (${response.status}): ${text}`);
129
+ }
130
+
131
+ const result = await response.json();
132
+ return result.value as T;
133
+ }
134
+
135
+ /**
136
+ * Execute an action on local Convex (blocking).
137
+ *
138
+ * @param path - Dot-notation path
139
+ * @param args - Action arguments
140
+ * @returns Action result
141
+ */
142
+ async function action<T = unknown>(
143
+ path: string,
144
+ args: Record<string, unknown> = {}
145
+ ): Promise<T> {
146
+ const convexPath = toConvexPath(path);
147
+
148
+ const response = await fetch(`${LOCAL_CONVEX_URL}/api/action`, {
149
+ method: "POST",
150
+ headers: { "Content-Type": "application/json" },
151
+ body: JSON.stringify({ path: convexPath, args, format: "json" }),
152
+ });
153
+
154
+ if (!response.ok) {
155
+ const text = await response.text();
156
+ throw new Error(`Local Convex action error (${response.status}): ${text}`);
157
+ }
158
+
159
+ const result = await response.json();
160
+ return result.value as T;
161
+ }
162
+
163
+ /**
164
+ * Fire-and-forget mutation (non-blocking).
165
+ * Use for non-critical tracking operations where latency matters.
166
+ *
167
+ * @param path - Dot-notation path
168
+ * @param args - Mutation arguments
169
+ */
170
+ function fire(
171
+ path: string,
172
+ args: Record<string, unknown> = {}
173
+ ): void {
174
+ const convexPath = toConvexPath(path);
175
+
176
+ fetch(`${LOCAL_CONVEX_URL}/api/mutation`, {
177
+ method: "POST",
178
+ headers: { "Content-Type": "application/json" },
179
+ body: JSON.stringify({ path: convexPath, args, format: "json" }),
180
+ }).catch(() => {
181
+ // Intentionally ignore errors - fire and forget
182
+ });
183
+ }
184
+
185
+ /**
186
+ * Fire-and-forget query (non-blocking).
187
+ * Rarely needed, but available for completeness.
188
+ */
189
+ function fireQuery(
190
+ path: string,
191
+ args: Record<string, unknown> = {}
192
+ ): void {
193
+ const convexPath = toConvexPath(path);
194
+
195
+ fetch(`${LOCAL_CONVEX_URL}/api/query`, {
196
+ method: "POST",
197
+ headers: { "Content-Type": "application/json" },
198
+ body: JSON.stringify({ path: convexPath, args, format: "json" }),
199
+ }).catch(() => {
200
+ // Intentionally ignore errors
201
+ });
202
+ }
203
+
204
+ // ============================================================================
205
+ // Exported Client
206
+ // ============================================================================
207
+
208
+ /**
209
+ * Local Convex database client for sandbox operations.
210
+ *
211
+ * Use this for all local DB operations in the KSA framework.
212
+ * The fire() method is optimized for high-frequency tracking calls.
213
+ */
214
+ export const localDb = {
215
+ query,
216
+ mutate,
217
+ action,
218
+ fire,
219
+ fireQuery,
220
+ };
221
+
222
+ // ============================================================================
223
+ // Helper Functions
224
+ // ============================================================================
225
+
226
+ /**
227
+ * Get the current session ID.
228
+ * Used for session-scoped caching and memory.
229
+ */
230
+ export function getSessionId(): string {
231
+ return SESSION_ID;
232
+ }
233
+
234
+ /**
235
+ * Get the current thread ID (if available).
236
+ * Used for thread-scoped operations.
237
+ */
238
+ export function getThreadId(): string | undefined {
239
+ return THREAD_ID;
240
+ }
241
+
242
+ /**
243
+ * Get the current card ID (if available).
244
+ * Used for kanban card-scoped operations.
245
+ */
246
+ export function getCardId(): string | undefined {
247
+ return CARD_ID;
248
+ }
249
+
250
+ /**
251
+ * Check if local Convex is available.
252
+ * Useful for graceful degradation.
253
+ */
254
+ export async function isLocalDbAvailable(): Promise<boolean> {
255
+ try {
256
+ const response = await fetch(`${LOCAL_CONVEX_URL}/version`, {
257
+ method: "GET",
258
+ signal: AbortSignal.timeout(1000),
259
+ });
260
+ return response.ok;
261
+ } catch {
262
+ return false;
263
+ }
264
+ }
265
+
266
+ /**
267
+ * Get local Convex connection info.
268
+ * Useful for debugging.
269
+ */
270
+ export function getLocalDbConfig() {
271
+ return {
272
+ url: LOCAL_CONVEX_URL,
273
+ sessionId: SESSION_ID,
274
+ threadId: THREAD_ID,
275
+ cardId: CARD_ID,
276
+ };
277
+ }
278
+
279
+ // ============================================================================
280
+ // Cache Helpers
281
+ // ============================================================================
282
+
283
+ /**
284
+ * Generate a cache key from function name and arguments.
285
+ */
286
+ export function cacheKey(ksaName: string, funcName: string, args: unknown[]): string {
287
+ const argsHash = JSON.stringify(args);
288
+ return `${ksaName}.${funcName}:${argsHash}`;
289
+ }
290
+
291
+ /**
292
+ * Simple hash function for cache keys.
293
+ */
294
+ export function simpleHash(str: string): string {
295
+ let hash = 0;
296
+ for (let i = 0; i < str.length; i++) {
297
+ const char = str.charCodeAt(i);
298
+ hash = (hash << 5) - hash + char;
299
+ hash = hash & hash;
300
+ }
301
+ return hash.toString(16);
302
+ }
package/ksa/index.ts ADDED
@@ -0,0 +1,134 @@
1
+ /**
2
+ * KSA Index - Knowledge, Skills, and Abilities
3
+ *
4
+ * This module re-exports from the Lakitu SDK and definitions.
5
+ *
6
+ * ## Architecture
7
+ *
8
+ * KSAs are now defined in `convex/lakitu/definitions/` using the TypeScript SDK
9
+ * from `packages/lakitu/sdk/`. This file provides backward compatibility.
10
+ *
11
+ * ## Usage
12
+ *
13
+ * ```typescript
14
+ * // Import the SDK for defining custom KSAs
15
+ * import { defineKSA, fn, service, primitive } from '@lakitu/sdk';
16
+ *
17
+ * // Import KSA definitions
18
+ * import { fileKSA, webKSA } from 'convex/lakitu/definitions';
19
+ *
20
+ * // Execute KSA functions
21
+ * import { executeFunction, createKSAProxy } from '@lakitu/sdk';
22
+ * ```
23
+ */
24
+
25
+ // ============================================================================
26
+ // Re-export SDK
27
+ // ============================================================================
28
+
29
+ export {
30
+ // Types
31
+ type KSADef,
32
+ type KSADefinition,
33
+ type FunctionDef,
34
+ type ParamDef,
35
+ type ParamType,
36
+ type Implementation,
37
+ type ServiceImpl,
38
+ type PrimitiveImpl,
39
+ type CompositeImpl,
40
+ type ExecutionContext,
41
+ type ExecutionResult,
42
+
43
+ // Builders
44
+ defineKSA,
45
+ fn,
46
+ service,
47
+ primitive,
48
+ composite,
49
+
50
+ // Runtime
51
+ executeFunction,
52
+ createKSAProxy,
53
+ createKSAProxies,
54
+
55
+ // Primitives
56
+ file,
57
+ shell,
58
+ browser,
59
+ getPrimitive,
60
+ hasPrimitive,
61
+ PRIMITIVES,
62
+
63
+ // Gateway
64
+ callGateway,
65
+ callGatewayBatch,
66
+ fireAndForget,
67
+ } from "../sdk";
68
+
69
+ // ============================================================================
70
+ // Re-export Gateway (for backward compatibility)
71
+ // ============================================================================
72
+
73
+ export {
74
+ callGateway as callGatewayLegacy,
75
+ callGatewayBatch as callGatewayBatchLegacy,
76
+ fireAndForget as fireAndForgetLegacy,
77
+ THREAD_ID,
78
+ CARD_ID,
79
+ WORKSPACE_ID,
80
+ getGatewayConfig,
81
+ } from "./_shared/gateway";
82
+
83
+ // ============================================================================
84
+ // Re-export from Generated Registry (for backward compatibility)
85
+ // ============================================================================
86
+
87
+ export type { KSAInfo, KSACategory, KSAGroup } from "./_generated/registry";
88
+
89
+ export {
90
+ KSA_REGISTRY,
91
+ CORE_KSAS as CORE_KSA_NAMES,
92
+ getAllKSAs,
93
+ getKSA as getKSALegacy,
94
+ getKSAsByCategory as getKSAsByCategoryLegacy,
95
+ getKSAsByNames,
96
+ searchKSAs,
97
+ getServicePathsForKSAs,
98
+ isServicePathAllowed,
99
+ } from "./_generated/registry";
100
+
101
+ // ============================================================================
102
+ // Re-export Config Schemas (for backward compatibility)
103
+ // ============================================================================
104
+
105
+ export type { ConfigField, PresetDefinition } from "./_shared/configSchemas";
106
+
107
+ export {
108
+ CONFIG_SCHEMAS,
109
+ CONFIG_DEFAULTS,
110
+ KSA_PRESETS,
111
+ getConfigSchema,
112
+ getConfigDefaults,
113
+ getPreset,
114
+ getPresetsForKSA,
115
+ resolvePreset,
116
+ FRAMEWORK_CONFIG_SCHEMA,
117
+ FRAMEWORK_DEFAULTS,
118
+ getFrameworkConfig,
119
+ } from "./_shared/configSchemas";
120
+
121
+ export type { FrameworkConfig } from "./_shared/configSchemas";
122
+
123
+ // ============================================================================
124
+ // Re-export Local DB (for backward compatibility)
125
+ // ============================================================================
126
+
127
+ export {
128
+ localDb,
129
+ getSessionId,
130
+ getThreadId,
131
+ getCardId,
132
+ isLocalDbAvailable,
133
+ getLocalDbConfig,
134
+ } from "./_shared/localDb";