@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,307 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * E2B Template Builder for Lakitu
4
+ *
5
+ * Strategy: Build Convex LOCALLY first, then upload pre-built state to E2B
6
+ *
7
+ * Steps:
8
+ * 1. Start local convex-backend
9
+ * 2. Deploy functions with `convex dev --once`
10
+ * 3. Stop backend, capture the state directory
11
+ * 4. Build E2B template with pre-built state baked in
12
+ *
13
+ * Usage:
14
+ * bun lakitu # Build the template
15
+ * bun lakitu base # Build base template only
16
+ * bun lakitu custom # Build custom template only
17
+ */
18
+
19
+ import { Template, defaultBuildLogger, waitForPort } from "e2b";
20
+ import { $ } from "bun";
21
+
22
+ const LAKITU_DIR = `${import.meta.dir}/..`;
23
+ const STATE_DIR = "/tmp/lakitu-convex-state";
24
+ const BUILD_DIR = "/tmp/lakitu-build";
25
+
26
+ async function getApiKey(): Promise<string> {
27
+ if (process.env.E2B_API_KEY) return process.env.E2B_API_KEY;
28
+
29
+ // Check .env.local files
30
+ const envPaths = [
31
+ `${import.meta.dir}/.env.local`,
32
+ `${import.meta.dir}/../../.env.local`,
33
+ `${import.meta.dir}/../../../.env.local`,
34
+ `${process.cwd()}/.env.local`,
35
+ ];
36
+ for (const path of envPaths) {
37
+ try {
38
+ const content = await Bun.file(path).text();
39
+ const match = content.match(/E2B_API_KEY=(.+)/);
40
+ if (match) return match[1].trim();
41
+ } catch { /* not found */ }
42
+ }
43
+
44
+ // Check E2B config
45
+ try {
46
+ const config = await Bun.file(`${process.env.HOME}/.e2b/config.json`).json();
47
+ if (config.teamApiKey) return config.teamApiKey;
48
+ if (config.accessToken) return config.accessToken;
49
+ } catch { /* not found */ }
50
+
51
+ throw new Error("E2B_API_KEY not found. Set in .env.local or run 'e2b auth login'");
52
+ }
53
+
54
+ /**
55
+ * Pre-build Convex locally: start backend, deploy functions, capture state
56
+ */
57
+ async function prebuildConvex(): Promise<string> {
58
+ console.log("=== Pre-building Convex locally ===");
59
+
60
+ // Clean up any existing state
61
+ await $`rm -rf ${STATE_DIR}`.quiet();
62
+ await $`mkdir -p ${STATE_DIR}`.quiet();
63
+
64
+ // Kill any existing convex-backend
65
+ await $`pkill -f "convex-backend" || true`.quiet();
66
+ await Bun.sleep(1000);
67
+
68
+ console.log("Starting local convex-backend...");
69
+
70
+ // Start convex-backend in background
71
+ // Run from STATE_DIR so the sqlite db is created there directly
72
+ // Pass explicit sqlite path as first argument
73
+ const backend = Bun.spawn([
74
+ "convex-backend",
75
+ `${STATE_DIR}/convex_local_backend.sqlite3`,
76
+ "--port", "3210",
77
+ "--site-proxy-port", "3211",
78
+ "--local-storage", STATE_DIR,
79
+ ], {
80
+ cwd: STATE_DIR,
81
+ stdout: "pipe",
82
+ stderr: "pipe",
83
+ });
84
+
85
+ // Wait for backend to be ready
86
+ console.log("Waiting for backend to be ready...");
87
+ for (let i = 0; i < 30; i++) {
88
+ try {
89
+ const res = await fetch("http://127.0.0.1:3210/version");
90
+ if (res.ok) {
91
+ console.log(`Backend ready after ${i + 1} seconds`);
92
+ break;
93
+ }
94
+ } catch { /* not ready yet */ }
95
+
96
+ if (i === 29) {
97
+ backend.kill();
98
+ throw new Error("Backend failed to start after 30 seconds");
99
+ }
100
+ await Bun.sleep(1000);
101
+ }
102
+
103
+ // Deploy functions using convex dev --once
104
+ console.log("Deploying functions with convex dev --once...");
105
+
106
+ // Build clean env without CONVEX_DEPLOYMENT (conflicts with CONVEX_SELF_HOSTED_URL)
107
+ const cleanEnv = { ...process.env };
108
+ delete cleanEnv.CONVEX_DEPLOYMENT;
109
+
110
+ // Create a temporary env file for the self-hosted deployment
111
+ // This overrides any .env.local in the project
112
+ const tempEnvFile = "/tmp/lakitu-convex-env";
113
+ await Bun.write(tempEnvFile, `CONVEX_SELF_HOSTED_URL=http://127.0.0.1:3210
114
+ CONVEX_SELF_HOSTED_ADMIN_KEY=0135d8598650f8f5cb0f30c34ec2e2bb62793bc28717c8eb6fb577996d50be5f4281b59181095065c5d0f86a2c31ddbe9b597ec62b47ded69782cd
115
+ `);
116
+
117
+ // Deploy sandbox functions (not the cloud component)
118
+ // Note: convex.json specifies "functions": "convex/sandbox" to target the sandbox directory
119
+ const deploy = await $`cd ${LAKITU_DIR} && ./node_modules/.bin/convex dev --once --typecheck disable --env-file ${tempEnvFile}`
120
+ .env(cleanEnv)
121
+ .nothrow();
122
+
123
+ if (deploy.exitCode !== 0) {
124
+ console.log("Deploy stdout:", deploy.stdout.toString());
125
+ console.log("Deploy stderr:", deploy.stderr.toString());
126
+ backend.kill();
127
+ throw new Error(`Convex deploy failed with exit code ${deploy.exitCode}`);
128
+ }
129
+
130
+ console.log("Functions deployed successfully!");
131
+
132
+ // Give backend a moment to flush state
133
+ await Bun.sleep(2000);
134
+
135
+ // Stop backend gracefully
136
+ console.log("Stopping backend...");
137
+ backend.kill("SIGTERM");
138
+ await Bun.sleep(1000);
139
+
140
+ // Verify state was captured
141
+ const stateFiles = await $`ls -la ${STATE_DIR}`.text();
142
+ console.log("State directory contents:");
143
+ console.log(stateFiles);
144
+
145
+ // Check modules directory has content
146
+ const modulesDir = `${STATE_DIR}/modules`;
147
+ try {
148
+ const moduleFiles = await $`ls ${modulesDir}`.text();
149
+ console.log(`Modules deployed: ${moduleFiles.trim().split('\n').length} files`);
150
+ } catch {
151
+ console.log("Warning: No modules directory found");
152
+ }
153
+
154
+ // Verify sqlite db was copied
155
+ try {
156
+ const sqliteSize = await $`ls -la ${STATE_DIR}/convex_local_backend.sqlite3`.text();
157
+ console.log("SQLite database:", sqliteSize.trim());
158
+ } catch {
159
+ console.log("WARNING: SQLite database not found!");
160
+ }
161
+
162
+ console.log("=== Pre-build complete ===\n");
163
+ return STATE_DIR;
164
+ }
165
+
166
+ // Base template: Ubuntu + Bun + Convex Backend + Node.js
167
+ const baseTemplate = Template()
168
+ .fromImage("e2bdev/code-interpreter:latest")
169
+ .runCmd("sudo apt-get update && sudo apt-get install -y git curl sqlite3 libsqlite3-dev build-essential unzip")
170
+ // Install Bun
171
+ .runCmd(`
172
+ export HOME=/home/user && \
173
+ curl -fsSL https://bun.sh/install | bash
174
+ `)
175
+ // Install Node.js for npx convex
176
+ .runCmd(`
177
+ curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash - && \
178
+ sudo apt-get install -y nodejs
179
+ `)
180
+ // Install Convex local backend
181
+ .runCmd(`
182
+ 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" && \
183
+ unzip /tmp/convex.zip -d /tmp && \
184
+ sudo mv /tmp/convex-local-backend /usr/local/bin/convex-backend && \
185
+ sudo chmod +x /usr/local/bin/convex-backend && \
186
+ rm /tmp/convex.zip
187
+ `)
188
+ // Create directory structure
189
+ .runCmd(`
190
+ mkdir -p /home/user/workspace /home/user/.convex/convex-backend-state/lakitu /home/user/artifacts && \
191
+ chown -R user:user /home/user
192
+ `)
193
+ .setEnvs({
194
+ HOME: "/home/user",
195
+ PATH: "/home/user/.bun/bin:/usr/local/bin:/usr/bin:/bin",
196
+ CONVEX_URL: "http://localhost:3210",
197
+ });
198
+
199
+ // Custom template: Add Lakitu code + PRE-BUILT Convex state + AUTO-START backend
200
+ const customTemplate = (baseId: string, buildDir: string) => Template()
201
+ .fromTemplate(baseId)
202
+ // Copy Lakitu source code
203
+ .copy(`${buildDir}/lakitu`, "/home/user/lakitu")
204
+ .copy(`${buildDir}/start.sh`, "/home/user/start.sh")
205
+ // Copy PRE-BUILT Convex state (functions already deployed!)
206
+ .copy(`${buildDir}/convex-state`, "/home/user/.convex/convex-backend-state/lakitu")
207
+ // Fix permissions and install dependencies (but NO convex deploy needed!)
208
+ .runCmd(`
209
+ sudo chown -R user:user /home/user/lakitu /home/user/start.sh /home/user/.convex && \
210
+ chmod +x /home/user/start.sh && \
211
+ export HOME=/home/user && \
212
+ export PATH="/home/user/.bun/bin:/usr/local/bin:/usr/bin:/bin" && \
213
+ cd /home/user/lakitu && bun install && \
214
+ echo '#!/bin/bash\nbun run /home/user/lakitu/runtime/pdf/pdf-generator.ts "$@"' | sudo tee /usr/local/bin/generate-pdf && \
215
+ sudo chmod +x /usr/local/bin/generate-pdf && \
216
+ cp -r /home/user/lakitu/ksa /home/user/ksa && \
217
+ chown -R user:user /home/user/ksa
218
+ `)
219
+ // Verify state was copied (including sqlite db!)
220
+ .runCmd(`
221
+ echo "=== Verifying pre-built Convex state ===" && \
222
+ ls -la /home/user/.convex/convex-backend-state/lakitu/ && \
223
+ echo "Modules:" && \
224
+ ls /home/user/.convex/convex-backend-state/lakitu/modules/ 2>/dev/null | wc -l && \
225
+ echo "SQLite database:" && \
226
+ ls -la /home/user/.convex/convex-backend-state/lakitu/convex_local_backend.sqlite3 && \
227
+ echo "=== State verified ==="
228
+ `)
229
+ .setEnvs({
230
+ HOME: "/home/user",
231
+ PATH: "/home/user/.bun/bin:/usr/local/bin:/usr/bin:/bin",
232
+ CONVEX_URL: "http://localhost:3210",
233
+ CONVEX_LOCAL_STORAGE: "/home/user/.convex/convex-backend-state/lakitu",
234
+ })
235
+ // AUTO-START: convex-backend starts on sandbox boot, E2B waits for port 3210
236
+ // This eliminates ~1000ms of polling overhead - backend is ready when create() returns
237
+ .setStartCmd("/home/user/start.sh", waitForPort(3210));
238
+
239
+ async function buildBase() {
240
+ const apiKey = await getApiKey();
241
+ console.log("Building Lakitu base template...");
242
+
243
+ const result = await Template.build(baseTemplate, {
244
+ alias: "lakitu-base",
245
+ apiKey,
246
+ onBuildLogs: defaultBuildLogger(),
247
+ });
248
+
249
+ console.log(`Base template: ${result.templateId}`);
250
+ return result.templateId;
251
+ }
252
+
253
+ async function buildCustom(baseId = "lakitu-base") {
254
+ const apiKey = await getApiKey();
255
+
256
+ // Step 1: Pre-build Convex locally
257
+ const stateDir = await prebuildConvex();
258
+
259
+ // Step 2: Prepare build context
260
+ console.log("Preparing build context...");
261
+ await $`rm -rf ${BUILD_DIR}`.quiet();
262
+ await $`mkdir -p ${BUILD_DIR}`.quiet();
263
+
264
+ // Copy lakitu source (excluding node_modules, .git, template)
265
+ await $`rsync -av --exclude='node_modules' --exclude='.git' --exclude='template' ${LAKITU_DIR}/ ${BUILD_DIR}/lakitu/`.quiet();
266
+ await $`cp ${import.meta.dir}/e2b/start.sh ${BUILD_DIR}/`;
267
+
268
+ // Copy pre-built Convex state
269
+ await $`cp -r ${stateDir} ${BUILD_DIR}/convex-state`;
270
+
271
+ console.log("Build context ready:");
272
+ await $`ls -la ${BUILD_DIR}`;
273
+
274
+ // Step 3: Build E2B template with pre-built state
275
+ console.log(`\nBuilding Lakitu custom template on ${baseId}...`);
276
+
277
+ const result = await Template.build(customTemplate(baseId, BUILD_DIR), {
278
+ alias: "lakitu",
279
+ apiKey,
280
+ onBuildLogs: defaultBuildLogger(),
281
+ });
282
+
283
+ console.log(`\n✅ Custom template: ${result.templateId}`);
284
+ console.log("Functions are PRE-DEPLOYED - sandbox just needs to start the backend!");
285
+ return result.templateId;
286
+ }
287
+
288
+ async function buildAll() {
289
+ const baseId = await buildBase();
290
+ await buildCustom(baseId);
291
+ }
292
+
293
+ // CLI
294
+ const cmd = process.argv[2];
295
+
296
+ async function main() {
297
+ if (cmd === "base") await buildBase();
298
+ else if (cmd === "custom") await buildCustom(process.argv[3]);
299
+ else await buildAll();
300
+
301
+ process.exit(0);
302
+ }
303
+
304
+ main().catch(e => {
305
+ console.error("Build failed:", e);
306
+ process.exit(1);
307
+ });
@@ -0,0 +1,69 @@
1
+ # Lakitu E2B Sandbox Template
2
+ # Self-hosted Convex agent with browser automation
3
+
4
+ FROM e2bdev/code-interpreter:latest
5
+
6
+ # System dependencies including Playwright requirements
7
+ RUN apt-get update && apt-get install -y \
8
+ git curl sqlite3 libsqlite3-dev \
9
+ build-essential python3-pip \
10
+ unzip \
11
+ # Playwright dependencies
12
+ libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 \
13
+ libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 \
14
+ libxrandr2 libgbm1 libasound2 libpango-1.0-0 libcairo2 \
15
+ && rm -rf /var/lib/apt/lists/*
16
+
17
+ # Bun runtime
18
+ RUN curl -fsSL https://bun.sh/install | bash
19
+ ENV PATH="/root/.bun/bin:/home/user/.bun/bin:$PATH"
20
+
21
+ # Convex local backend
22
+ RUN curl -L https://github.com/get-convex/convex-backend/releases/latest/download/convex-local-backend-linux-x64.zip -o /tmp/convex.zip && \
23
+ unzip /tmp/convex.zip -d /tmp && \
24
+ mv /tmp/convex-local-backend /usr/local/bin/convex-backend && \
25
+ chmod +x /usr/local/bin/convex-backend && \
26
+ rm /tmp/convex.zip
27
+
28
+ # Node.js for npx convex
29
+ RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
30
+ apt-get install -y nodejs && \
31
+ rm -rf /var/lib/apt/lists/*
32
+
33
+ # LSP servers
34
+ RUN npm install -g typescript typescript-language-server && \
35
+ pip3 install python-lsp-server
36
+
37
+ # Directory structure
38
+ RUN mkdir -p /home/user/workspace /home/user/.convex /home/user/artifacts && \
39
+ chown -R user:user /home/user
40
+
41
+ # Copy lakitu agent code
42
+ COPY --chown=user:user ../../ /home/user/lakitu/
43
+
44
+ # Copy scripts
45
+ COPY --chown=user:user ./start.sh /home/user/start.sh
46
+ COPY --chown=user:user ./prebuild.sh /home/user/prebuild.sh
47
+ RUN chmod +x /home/user/start.sh /home/user/prebuild.sh
48
+
49
+ # Install dependencies
50
+ WORKDIR /home/user/lakitu
51
+ RUN /root/.bun/bin/bun install || true
52
+
53
+ # Install Playwright browsers
54
+ RUN /root/.bun/bin/bunx playwright install chromium
55
+
56
+ # Pre-deploy Convex functions during build
57
+ RUN /home/user/prebuild.sh
58
+
59
+ # Fix ownership
60
+ RUN chown -R user:user /home/user/.convex
61
+
62
+ # Environment
63
+ ENV HOME=/home/user
64
+ ENV PATH="/home/user/.bun/bin:/usr/local/bin:/usr/bin:/bin"
65
+ ENV CONVEX_URL="http://localhost:3210"
66
+ ENV CONVEX_LOCAL_STORAGE="/home/user/.convex/convex-backend-state/lakitu"
67
+
68
+ USER user
69
+ WORKDIR /home/user/workspace
@@ -0,0 +1,13 @@
1
+ # E2B Sandbox Template Configuration
2
+ # This defines the Lakitu template for E2B
3
+
4
+ template_id = "425fw6bbagygha8j41lt"
5
+ template_name = "lakitu"
6
+ dockerfile = "Dockerfile"
7
+
8
+ # Start command runs the sandbox agent
9
+ start_cmd = "/home/user/start.sh"
10
+
11
+ # CPU and memory
12
+ vcpus = 2
13
+ memory_mb = 2048
@@ -0,0 +1,68 @@
1
+ #!/bin/bash
2
+ # Pre-deploy Convex functions during Docker build
3
+ # This script is called from the Dockerfile to bake functions into the image
4
+ set -e
5
+
6
+ echo "=== Pre-deploying Convex functions ==="
7
+
8
+ cd /home/user/lakitu
9
+
10
+ export CONVEX_LOCAL_STORAGE=/home/user/.convex/convex-backend-state/lakitu
11
+
12
+ mkdir -p "$CONVEX_LOCAL_STORAGE"
13
+
14
+ echo "Starting convex-backend..."
15
+ echo " - Port: 3210"
16
+ echo " - Site proxy: 3211"
17
+ echo " - Storage: $CONVEX_LOCAL_STORAGE"
18
+
19
+ # Start convex-backend in background
20
+ convex-backend --port 3210 --site-proxy-port 3211 \
21
+ --local-storage "$CONVEX_LOCAL_STORAGE" &
22
+ BACKEND_PID=$!
23
+
24
+ # Wait for backend to be ready with timeout
25
+ echo "Waiting for backend to be ready..."
26
+ for i in {1..30}; do
27
+ if curl -s http://localhost:3210/version > /dev/null 2>&1; then
28
+ echo "Backend ready after $i seconds"
29
+ break
30
+ fi
31
+ if [ $i -eq 30 ]; then
32
+ echo "ERROR: Backend failed to start within 30 seconds"
33
+ exit 1
34
+ fi
35
+ sleep 1
36
+ done
37
+
38
+ # Create .env.local to configure local deployment (skips login prompt)
39
+ echo "=== Creating .env.local ==="
40
+ cat > .env.local << 'ENVLOCAL'
41
+ # Deployment used by npx convex dev
42
+ CONVEX_DEPLOYMENT=local:lakitu-sandbox
43
+
44
+ CONVEX_URL=http://127.0.0.1:3210
45
+ ENVLOCAL
46
+ cat .env.local
47
+
48
+ # Deploy functions using convex dev --once
49
+ echo "=== Deploying functions ==="
50
+ ./node_modules/.bin/convex dev --once --typecheck disable
51
+
52
+ # Verify deployment by listing functions
53
+ echo "=== Verifying deployment ==="
54
+ curl -s http://localhost:3210/api/0.1.0/list_functions | head -100
55
+
56
+ # Give backend time to flush state to disk
57
+ sleep 2
58
+
59
+ # Stop the backend gracefully
60
+ echo "=== Stopping backend ==="
61
+ kill $BACKEND_PID 2>/dev/null || true
62
+ wait $BACKEND_PID 2>/dev/null || true
63
+
64
+ # Verify state was persisted
65
+ echo "=== Verifying persisted state ==="
66
+ ls -la "$CONVEX_LOCAL_STORAGE/"
67
+
68
+ echo "=== Pre-deploy complete! ==="
@@ -0,0 +1,14 @@
1
+ #!/bin/bash
2
+ # OPTIMIZED: Minimal startup for fastest port 3210 availability
3
+ # Skip logging and checks - template build already verified everything
4
+
5
+ STORAGE_DIR=/home/user/.convex/convex-backend-state/lakitu
6
+ SQLITE_DB=$STORAGE_DIR/convex_local_backend.sqlite3
7
+
8
+ # Start convex-backend immediately with --disable-beacon to skip telemetry
9
+ exec convex-backend \
10
+ "$SQLITE_DB" \
11
+ --port 3210 \
12
+ --site-proxy-port 3211 \
13
+ --local-storage "$STORAGE_DIR" \
14
+ --disable-beacon