@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,223 @@
1
+ /**
2
+ * lakitu build
3
+ *
4
+ * Build E2B sandbox template with pre-deployed Convex functions.
5
+ *
6
+ * Strategy:
7
+ * 1. Start local convex-backend
8
+ * 2. Deploy sandbox functions with `convex dev --once`
9
+ * 3. Capture the state directory
10
+ * 4. Build E2B template with pre-built state baked in
11
+ */
12
+ import { Template, defaultBuildLogger, waitForPort } from "e2b";
13
+ import { mkdirSync, rmSync, cpSync, writeFileSync, readFileSync } from "fs";
14
+ import { join, dirname } from "path";
15
+ import { execSync, spawn } from "child_process";
16
+ import { fileURLToPath } from "url";
17
+ const __dirname = dirname(fileURLToPath(import.meta.url));
18
+ const PACKAGE_ROOT = join(__dirname, "../..");
19
+ async function getApiKey() {
20
+ if (process.env.E2B_API_KEY)
21
+ return process.env.E2B_API_KEY;
22
+ // Check .env.local files
23
+ const envPaths = [
24
+ join(process.cwd(), ".env.local"),
25
+ join(process.cwd(), ".env"),
26
+ ];
27
+ for (const path of envPaths) {
28
+ try {
29
+ const content = readFileSync(path, "utf-8");
30
+ const match = content.match(/E2B_API_KEY=(.+)/);
31
+ if (match)
32
+ return match[1].trim();
33
+ }
34
+ catch { /* not found */ }
35
+ }
36
+ // Check E2B config
37
+ const homeDir = process.env.HOME || process.env.USERPROFILE || "";
38
+ try {
39
+ const configPath = join(homeDir, ".e2b/config.json");
40
+ const config = JSON.parse(readFileSync(configPath, "utf-8"));
41
+ if (config.teamApiKey)
42
+ return config.teamApiKey;
43
+ if (config.accessToken)
44
+ return config.accessToken;
45
+ }
46
+ catch { /* not found */ }
47
+ throw new Error("E2B_API_KEY not found. Set in .env.local or run 'e2b auth login'");
48
+ }
49
+ async function sleep(ms) {
50
+ return new Promise(resolve => setTimeout(resolve, ms));
51
+ }
52
+ /**
53
+ * Pre-build Convex locally: start backend, deploy functions, capture state
54
+ */
55
+ async function prebuildConvex() {
56
+ const stateDir = "/tmp/lakitu-convex-state";
57
+ const sandboxConvexDir = join(PACKAGE_ROOT, "convex/sandbox");
58
+ console.log("=== Pre-building Convex locally ===");
59
+ // Clean up any existing state
60
+ rmSync(stateDir, { recursive: true, force: true });
61
+ mkdirSync(stateDir, { recursive: true });
62
+ // Kill any existing convex-backend
63
+ try {
64
+ execSync("pkill -f convex-backend", { stdio: "ignore" });
65
+ await sleep(1000);
66
+ }
67
+ catch { /* not running */ }
68
+ console.log("Starting local convex-backend...");
69
+ // Start convex-backend in background
70
+ const backend = spawn("convex-backend", [
71
+ join(stateDir, "convex_local_backend.sqlite3"),
72
+ "--port", "3210",
73
+ "--site-proxy-port", "3211",
74
+ "--local-storage", stateDir,
75
+ ], {
76
+ cwd: stateDir,
77
+ stdio: "pipe",
78
+ });
79
+ // Wait for backend to be ready
80
+ console.log("Waiting for backend to be ready...");
81
+ for (let i = 0; i < 30; i++) {
82
+ try {
83
+ const res = await fetch("http://127.0.0.1:3210/version");
84
+ if (res.ok) {
85
+ console.log(`Backend ready after ${i + 1} seconds`);
86
+ break;
87
+ }
88
+ }
89
+ catch { /* not ready yet */ }
90
+ if (i === 29) {
91
+ backend.kill();
92
+ throw new Error("Backend failed to start after 30 seconds");
93
+ }
94
+ await sleep(1000);
95
+ }
96
+ // Deploy functions using convex dev --once
97
+ console.log("Deploying functions with convex dev --once...");
98
+ const tempEnvFile = "/tmp/lakitu-convex-env";
99
+ writeFileSync(tempEnvFile, `CONVEX_SELF_HOSTED_URL=http://127.0.0.1:3210
100
+ CONVEX_SELF_HOSTED_ADMIN_KEY=0135d8598650f8f5cb0f30c34ec2e2bb62793bc28717c8eb6fb577996d50be5f4281b59181095065c5d0f86a2c31ddbe9b597ec62b47ded69782cd
101
+ `);
102
+ try {
103
+ execSync(`npx convex dev --once --typecheck disable --env-file ${tempEnvFile}`, {
104
+ cwd: sandboxConvexDir,
105
+ stdio: "inherit",
106
+ env: { ...process.env, CONVEX_DEPLOYMENT: undefined },
107
+ });
108
+ console.log("Functions deployed successfully!");
109
+ }
110
+ catch (error) {
111
+ backend.kill();
112
+ throw new Error("Convex deploy failed");
113
+ }
114
+ // Give backend a moment to flush state
115
+ await sleep(2000);
116
+ // Stop backend gracefully
117
+ console.log("Stopping backend...");
118
+ backend.kill("SIGTERM");
119
+ await sleep(1000);
120
+ console.log("=== Pre-build complete ===\n");
121
+ return stateDir;
122
+ }
123
+ // Base template: Ubuntu + Bun + Convex Backend + Node.js
124
+ const baseTemplate = Template()
125
+ .fromImage("e2bdev/code-interpreter:latest")
126
+ .runCmd("sudo apt-get update && sudo apt-get install -y git curl sqlite3 libsqlite3-dev build-essential unzip")
127
+ .runCmd(`export HOME=/home/user && curl -fsSL https://bun.sh/install | bash`)
128
+ .runCmd(`curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash - && sudo apt-get install -y nodejs`)
129
+ .runCmd(`
130
+ curl -L -o /tmp/convex.zip "https://github.com/get-convex/convex-backend/releases/download/precompiled-2026-01-08-272e7f4/convex-local-backend-x86_64-unknown-linux-gnu.zip" && \
131
+ unzip /tmp/convex.zip -d /tmp && \
132
+ sudo mv /tmp/convex-local-backend /usr/local/bin/convex-backend && \
133
+ sudo chmod +x /usr/local/bin/convex-backend && \
134
+ rm /tmp/convex.zip
135
+ `)
136
+ .runCmd(`mkdir -p /home/user/workspace /home/user/.convex/convex-backend-state/lakitu /home/user/artifacts && chown -R user:user /home/user`)
137
+ .setEnvs({
138
+ HOME: "/home/user",
139
+ PATH: "/home/user/.bun/bin:/usr/local/bin:/usr/bin:/bin",
140
+ CONVEX_URL: "http://localhost:3210",
141
+ });
142
+ // Custom template: Add Lakitu code + PRE-BUILT Convex state + AUTO-START backend
143
+ function customTemplate(baseId, buildDir) {
144
+ return Template()
145
+ .fromTemplate(baseId)
146
+ .copy(`${buildDir}/lakitu`, "/home/user/lakitu")
147
+ .copy(`${buildDir}/start.sh`, "/home/user/start.sh")
148
+ .copy(`${buildDir}/convex-state`, "/home/user/.convex/convex-backend-state/lakitu")
149
+ .runCmd(`
150
+ sudo chown -R user:user /home/user/lakitu /home/user/start.sh /home/user/.convex && \
151
+ chmod +x /home/user/start.sh && \
152
+ export HOME=/home/user && \
153
+ export PATH="/home/user/.bun/bin:/usr/local/bin:/usr/bin:/bin" && \
154
+ cd /home/user/lakitu && bun install && \
155
+ echo '#!/bin/bash\nbun run /home/user/lakitu/runtime/pdf/pdf-generator.ts "$@"' | sudo tee /usr/local/bin/generate-pdf && \
156
+ sudo chmod +x /usr/local/bin/generate-pdf && \
157
+ cp -r /home/user/lakitu/ksa /home/user/ksa && \
158
+ chown -R user:user /home/user/ksa
159
+ `)
160
+ .setEnvs({
161
+ HOME: "/home/user",
162
+ PATH: "/home/user/.bun/bin:/usr/local/bin:/usr/bin:/bin",
163
+ CONVEX_URL: "http://localhost:3210",
164
+ CONVEX_LOCAL_STORAGE: "/home/user/.convex/convex-backend-state/lakitu",
165
+ })
166
+ .setStartCmd("/home/user/start.sh", waitForPort(3210));
167
+ }
168
+ async function buildBase(apiKey) {
169
+ console.log("🔧 Building Lakitu base template...\n");
170
+ const result = await Template.build(baseTemplate, {
171
+ alias: "lakitu-base",
172
+ apiKey,
173
+ onBuildLogs: defaultBuildLogger(),
174
+ });
175
+ console.log(`\n✅ Base template: ${result.templateId}`);
176
+ return result.templateId;
177
+ }
178
+ async function buildCustom(apiKey, baseId) {
179
+ const buildDir = "/tmp/lakitu-build";
180
+ // Step 1: Pre-build Convex locally
181
+ const stateDir = await prebuildConvex();
182
+ // Step 2: Prepare build context
183
+ console.log("📦 Preparing build context...");
184
+ rmSync(buildDir, { recursive: true, force: true });
185
+ mkdirSync(buildDir, { recursive: true });
186
+ // Copy lakitu source (excluding node_modules, .git, template, cli)
187
+ const excludes = ["node_modules", ".git", "template", "cli", "dist"];
188
+ cpSync(PACKAGE_ROOT, join(buildDir, "lakitu"), {
189
+ recursive: true,
190
+ filter: (src) => !excludes.some(ex => src.includes(`/${ex}`)),
191
+ });
192
+ // Copy start script
193
+ cpSync(join(PACKAGE_ROOT, "template/e2b/start.sh"), join(buildDir, "start.sh"));
194
+ // Copy pre-built Convex state
195
+ cpSync(stateDir, join(buildDir, "convex-state"), { recursive: true });
196
+ console.log(" ✓ Build context ready\n");
197
+ // Step 3: Build E2B template with pre-built state
198
+ console.log(`🔧 Building Lakitu custom template on ${baseId}...\n`);
199
+ const result = await Template.build(customTemplate(baseId, buildDir), {
200
+ alias: "lakitu",
201
+ apiKey,
202
+ onBuildLogs: defaultBuildLogger(),
203
+ });
204
+ console.log(`\n✅ Custom template: ${result.templateId}`);
205
+ console.log(" Functions are PRE-DEPLOYED - sandbox starts instantly!");
206
+ return result.templateId;
207
+ }
208
+ export async function build(options) {
209
+ console.log("🍄 Lakitu Template Builder\n");
210
+ const apiKey = await getApiKey();
211
+ if (options.base) {
212
+ await buildBase(apiKey);
213
+ }
214
+ else if (options.custom) {
215
+ await buildCustom(apiKey, options.baseId || "lakitu-base");
216
+ }
217
+ else {
218
+ // Build both
219
+ const baseId = await buildBase(apiKey);
220
+ await buildCustom(apiKey, baseId);
221
+ }
222
+ console.log("\n🎉 Build complete!");
223
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * lakitu init
3
+ *
4
+ * Initialize lakitu in a Convex project:
5
+ * 1. Install @lakitu/sdk as a dependency
6
+ * 2. Create convex/lakitu.config.ts
7
+ * 3. Add lakitu component to convex.config.ts
8
+ * 4. Create example KSA file
9
+ */
10
+ interface InitOptions {
11
+ dir: string;
12
+ skipInstall?: boolean;
13
+ }
14
+ export declare function init(options: InitOptions): Promise<void>;
15
+ export {};
16
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../cli/commands/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,UAAU,WAAW;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAuED,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW,iBA6E9C"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * lakitu init
3
+ *
4
+ * Initialize lakitu in a Convex project:
5
+ * 1. Install @lakitu/sdk as a dependency
6
+ * 2. Create convex/lakitu.config.ts
7
+ * 3. Add lakitu component to convex.config.ts
8
+ * 4. Create example KSA file
9
+ */
10
+ import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
11
+ import { join } from "path";
12
+ import { execSync } from "child_process";
13
+ const LAKITU_CONFIG = `/**
14
+ * Lakitu Configuration
15
+ *
16
+ * Configure your AI agent's capabilities here.
17
+ */
18
+
19
+ import { Lakitu } from "@lakitu/sdk";
20
+
21
+ export default Lakitu.configure({
22
+ // E2B template to use (build with: npx lakitu build)
23
+ template: "lakitu",
24
+
25
+ // Default model for agent
26
+ model: "anthropic/claude-sonnet-4-20250514",
27
+
28
+ // KSA modules to enable
29
+ ksas: [
30
+ // Built-in KSAs
31
+ "file",
32
+ "shell",
33
+ "browser",
34
+ "beads",
35
+
36
+ // Custom KSAs (define in convex/lakitu/)
37
+ // "./example",
38
+ ],
39
+
40
+ // Sandbox pool settings
41
+ pool: {
42
+ min: 0,
43
+ max: 5,
44
+ idleTimeout: 300_000, // 5 minutes
45
+ },
46
+ });
47
+ `;
48
+ const EXAMPLE_KSA = `/**
49
+ * Example Custom KSA
50
+ *
51
+ * KSAs (Knowledge, Skills, Abilities) are capability modules
52
+ * that the AI agent can use via code execution.
53
+ */
54
+
55
+ import { defineKSA, fn, service } from "@lakitu/sdk";
56
+
57
+ export const exampleKSA = defineKSA("example")
58
+ .description("Example KSA showing how to define custom capabilities")
59
+ .category("skills")
60
+
61
+ // Simple function that calls a Convex service
62
+ .fn("greet", fn()
63
+ .description("Generate a greeting")
64
+ .param("name", { type: "string", required: true })
65
+ .impl(service("myService.greet")
66
+ .mapArgs(({ name }) => ({ userName: name }))
67
+ )
68
+ )
69
+
70
+ .build();
71
+
72
+ export default exampleKSA;
73
+ `;
74
+ const CONVEX_CONFIG_ADDITION = `
75
+ // Lakitu agent component
76
+ import lakitu from "@lakitu/sdk/component";
77
+ app.use(lakitu);
78
+ `;
79
+ export async function init(options) {
80
+ const cwd = process.cwd();
81
+ const convexDir = join(cwd, options.dir);
82
+ console.log("🍄 Initializing Lakitu...\n");
83
+ // Check if convex directory exists
84
+ if (!existsSync(convexDir)) {
85
+ console.error(`❌ Convex directory not found: ${convexDir}`);
86
+ console.log(" Run this command from a Convex project root.");
87
+ process.exit(1);
88
+ }
89
+ // Step 1: Install dependency
90
+ if (!options.skipInstall) {
91
+ console.log("📦 Installing @lakitu/sdk...");
92
+ try {
93
+ // Detect package manager
94
+ const useBun = existsSync(join(cwd, "bun.lockb"));
95
+ const usePnpm = existsSync(join(cwd, "pnpm-lock.yaml"));
96
+ const useYarn = existsSync(join(cwd, "yarn.lock"));
97
+ const pm = useBun ? "bun" : usePnpm ? "pnpm" : useYarn ? "yarn" : "npm";
98
+ const addCmd = pm === "yarn" ? "add" : "install";
99
+ execSync(`${pm} ${addCmd} @lakitu/sdk`, { stdio: "inherit" });
100
+ console.log(" ✓ Installed\n");
101
+ }
102
+ catch (error) {
103
+ console.warn(" ⚠ Could not auto-install. Run: npm install @lakitu/sdk\n");
104
+ }
105
+ }
106
+ // Step 2: Create convex/lakitu/ directory and config
107
+ const lakituDir = join(convexDir, "lakitu");
108
+ if (!existsSync(lakituDir)) {
109
+ mkdirSync(lakituDir, { recursive: true });
110
+ }
111
+ const configPath = join(lakituDir, "config.ts");
112
+ if (!existsSync(configPath)) {
113
+ console.log("📝 Creating convex/lakitu/config.ts...");
114
+ writeFileSync(configPath, LAKITU_CONFIG);
115
+ console.log(" ✓ Created\n");
116
+ }
117
+ else {
118
+ console.log("📝 convex/lakitu/config.ts already exists, skipping.\n");
119
+ }
120
+ // Step 3: Create example KSA in convex/lakitu/
121
+ const examplePath = join(lakituDir, "example.ts");
122
+ if (!existsSync(examplePath)) {
123
+ console.log("📝 Creating example KSA...");
124
+ if (!existsSync(lakituDir)) {
125
+ mkdirSync(lakituDir, { recursive: true });
126
+ }
127
+ writeFileSync(examplePath, EXAMPLE_KSA);
128
+ console.log(" ✓ Created convex/lakitu/example.ts\n");
129
+ }
130
+ // Step 4: Check convex.config.ts
131
+ const convexConfigPath = join(convexDir, "convex.config.ts");
132
+ if (existsSync(convexConfigPath)) {
133
+ const content = readFileSync(convexConfigPath, "utf-8");
134
+ if (!content.includes("@lakitu/sdk")) {
135
+ console.log("📝 Add this to your convex.config.ts:\n");
136
+ console.log(" " + CONVEX_CONFIG_ADDITION.trim().split("\n").join("\n "));
137
+ console.log("");
138
+ }
139
+ }
140
+ // Done
141
+ console.log("✅ Lakitu initialized!\n");
142
+ console.log("Next steps:");
143
+ console.log(" 1. Add lakitu component to convex.config.ts (see above)");
144
+ console.log(" 2. Define KSAs in convex/lakitu/");
145
+ console.log(" 3. Build template: npx lakitu build");
146
+ console.log(" 4. Publish to E2B: npx lakitu publish");
147
+ console.log("");
148
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * lakitu publish
3
+ *
4
+ * Publish your built template to E2B.
5
+ * This is mostly a convenience wrapper - the build command already publishes.
6
+ */
7
+ interface PublishOptions {
8
+ alias?: string;
9
+ }
10
+ export declare function publish(options: PublishOptions): Promise<void>;
11
+ export {};
12
+ //# sourceMappingURL=publish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../../cli/commands/publish.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,UAAU,cAAc;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,iBA2BpD"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * lakitu publish
3
+ *
4
+ * Publish your built template to E2B.
5
+ * This is mostly a convenience wrapper - the build command already publishes.
6
+ */
7
+ import { execSync } from "child_process";
8
+ export async function publish(options) {
9
+ console.log("🍄 Publishing Lakitu template to E2B...\n");
10
+ const alias = options.alias || "lakitu";
11
+ // The build command already publishes, so this is mainly for
12
+ // re-publishing or updating an existing template
13
+ console.log(`Template alias: ${alias}`);
14
+ console.log("");
15
+ console.log("To publish a new template, run:");
16
+ console.log(" npx lakitu build");
17
+ console.log("");
18
+ console.log("To manage templates directly:");
19
+ console.log(" e2b template list");
20
+ console.log(" e2b template delete <template-id>");
21
+ console.log("");
22
+ // Check if e2b CLI is available
23
+ try {
24
+ const templates = execSync("e2b template list", { encoding: "utf-8" });
25
+ console.log("Your E2B templates:");
26
+ console.log(templates);
27
+ }
28
+ catch {
29
+ console.log("💡 Install E2B CLI for more template management:");
30
+ console.log(" npm install -g @e2b/cli");
31
+ console.log(" e2b auth login");
32
+ }
33
+ }
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Lakitu CLI
4
+ *
5
+ * Self-hosted AI agent framework for Convex + E2B.
6
+ *
7
+ * Commands:
8
+ * init - Initialize lakitu in a Convex project
9
+ * build - Build E2B sandbox template
10
+ * publish - Publish template to E2B
11
+ * dev - Start local development
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../cli/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG"}
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Lakitu CLI
4
+ *
5
+ * Self-hosted AI agent framework for Convex + E2B.
6
+ *
7
+ * Commands:
8
+ * init - Initialize lakitu in a Convex project
9
+ * build - Build E2B sandbox template
10
+ * publish - Publish template to E2B
11
+ * dev - Start local development
12
+ */
13
+ import { Command } from "commander";
14
+ import { init } from "./commands/init.js";
15
+ import { build } from "./commands/build.js";
16
+ import { publish } from "./commands/publish.js";
17
+ const program = new Command();
18
+ program
19
+ .name("lakitu")
20
+ .description("Self-hosted AI agent framework for Convex + E2B")
21
+ .version("0.1.0");
22
+ program
23
+ .command("init")
24
+ .description("Initialize lakitu in your Convex project")
25
+ .option("-d, --dir <path>", "Convex directory", "convex")
26
+ .option("--skip-install", "Skip npm install")
27
+ .action(init);
28
+ program
29
+ .command("build")
30
+ .description("Build E2B sandbox template")
31
+ .option("--base", "Build base template only")
32
+ .option("--custom", "Build custom template only")
33
+ .option("--base-id <id>", "Base template ID for custom build", "lakitu-base")
34
+ .action(build);
35
+ program
36
+ .command("publish")
37
+ .description("Publish template to E2B")
38
+ .option("--alias <name>", "Template alias", "lakitu")
39
+ .action(publish);
40
+ program.parse();
@@ -0,0 +1,104 @@
1
+ /**
2
+ * KSA SDK Builders
3
+ *
4
+ * Fluent API for defining KSAs with full TypeScript type safety.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { defineKSA, fn, service, primitive } from '@lakitu/sdk';
9
+ *
10
+ * export const webKSA = defineKSA('web')
11
+ * .description('Web search and content extraction')
12
+ * .category('skills')
13
+ * .group('research')
14
+ * .fn('search', fn()
15
+ * .description('Search the web')
16
+ * .param('query', { type: 'string', required: true })
17
+ * .param('maxResults', { type: 'number', default: 10 })
18
+ * .returns<SearchResult[]>()
19
+ * .impl(service('services.Valyu.internal.search')
20
+ * .mapArgs(({ query, maxResults }) => ({ query, maxResults, fastMode: true }))
21
+ * .mapResult(r => r.results || [])
22
+ * )
23
+ * )
24
+ * .build();
25
+ * ```
26
+ */
27
+ import type { KSADef, KSACategory, FunctionDef, ParamDef, ParamType, Implementation, ServiceImpl, PrimitiveImpl, CompositeImpl, StepContext } from "./types";
28
+ export declare class ServiceBuilder<TArgs = Record<string, unknown>, TResult = unknown> {
29
+ private _path;
30
+ private _mapArgs?;
31
+ private _mapResult?;
32
+ constructor(path: string);
33
+ /** Map input arguments to service arguments */
34
+ mapArgs<T extends TArgs>(mapper: (args: T) => Record<string, unknown>): ServiceBuilder<T, TResult>;
35
+ /** Map service result to function return type */
36
+ mapResult<T>(mapper: (result: unknown) => T): ServiceBuilder<TArgs, T>;
37
+ build(): ServiceImpl<TArgs, TResult>;
38
+ }
39
+ /** Create a service implementation */
40
+ export declare function service(path: string): ServiceBuilder;
41
+ /** Create a primitive implementation */
42
+ export declare function primitive(name: string): PrimitiveImpl;
43
+ export declare class CompositeBuilder {
44
+ private _steps;
45
+ /** Call another KSA function */
46
+ call(fnPath: string, args?: Record<string, unknown> | ((ctx: StepContext) => Record<string, unknown>), as?: string): CompositeBuilder;
47
+ /** Return a value */
48
+ return(value: unknown | ((ctx: StepContext) => unknown)): CompositeBuilder;
49
+ build(): CompositeImpl;
50
+ }
51
+ /** Create a composite implementation */
52
+ export declare function composite(): CompositeBuilder;
53
+ export declare class FunctionBuilder<TParams extends Record<string, ParamDef> = Record<string, never>, TResult = unknown> {
54
+ private _description;
55
+ private _params;
56
+ private _impl?;
57
+ private _returns?;
58
+ /** Set function description */
59
+ description(desc: string): this;
60
+ /** Add a parameter */
61
+ param<K extends string, T extends ParamType>(name: K, def: ParamDef & {
62
+ type: T;
63
+ }): FunctionBuilder<TParams & Record<K, ParamDef & {
64
+ type: T;
65
+ }>, TResult>;
66
+ /** Set return type info */
67
+ returns<T>(typeInfo?: {
68
+ type: string;
69
+ description?: string;
70
+ }): FunctionBuilder<TParams, T>;
71
+ /** Set implementation */
72
+ impl(implementation: Implementation | ServiceBuilder | CompositeBuilder): this;
73
+ build(name: string): FunctionDef;
74
+ }
75
+ /** Create a function builder */
76
+ export declare function fn(): FunctionBuilder;
77
+ export declare class KSABuilder {
78
+ private _name;
79
+ private _description;
80
+ private _category;
81
+ private _group?;
82
+ private _icon?;
83
+ private _functions;
84
+ constructor(name: string);
85
+ /** Set KSA description */
86
+ description(desc: string): this;
87
+ /** Set KSA category */
88
+ category(cat: KSACategory): this;
89
+ /** Set KSA group (subcategory) */
90
+ group(grp: string): this;
91
+ /** Set KSA icon (MDI icon name) */
92
+ icon(ico: string): this;
93
+ /** Add a function to the KSA */
94
+ fn(name: string, builder: FunctionBuilder): this;
95
+ /** Build the KSA definition */
96
+ build(): KSADef;
97
+ }
98
+ /** Create a KSA builder */
99
+ export declare function defineKSA(name: string): KSABuilder;
100
+ /** Create a registry from KSA definitions */
101
+ export declare function createRegistry(...ksas: KSADef[]): Map<string, KSADef>;
102
+ /** Get a function from a registry */
103
+ export declare function getFunction(registry: Map<string, KSADef>, ksaName: string, fnName: string): FunctionDef | undefined;
104
+ //# sourceMappingURL=builders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../../sdk/builders.ts"],"names":[],"mappings":"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"}