@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.
- package/README.md +166 -0
- package/convex/_generated/api.d.ts +45 -0
- package/convex/_generated/api.js +23 -0
- package/convex/_generated/dataModel.d.ts +58 -0
- package/convex/_generated/server.d.ts +143 -0
- package/convex/_generated/server.js +93 -0
- package/convex/cloud/CLAUDE.md +238 -0
- package/convex/cloud/_generated/api.ts +84 -0
- package/convex/cloud/_generated/component.ts +861 -0
- package/convex/cloud/_generated/dataModel.ts +60 -0
- package/convex/cloud/_generated/server.ts +156 -0
- package/convex/cloud/convex.config.ts +16 -0
- package/convex/cloud/index.ts +29 -0
- package/convex/cloud/intentSchema/generate.ts +447 -0
- package/convex/cloud/intentSchema/index.ts +16 -0
- package/convex/cloud/intentSchema/types.ts +418 -0
- package/convex/cloud/ksaPolicy.ts +554 -0
- package/convex/cloud/mail.ts +92 -0
- package/convex/cloud/schema.ts +322 -0
- package/convex/cloud/utils/kanbanContext.ts +229 -0
- package/convex/cloud/workflows/agentBoard.ts +451 -0
- package/convex/cloud/workflows/agentPrompt.ts +272 -0
- package/convex/cloud/workflows/agentThread.ts +374 -0
- package/convex/cloud/workflows/compileSandbox.ts +146 -0
- package/convex/cloud/workflows/crudBoard.ts +217 -0
- package/convex/cloud/workflows/crudKSAs.ts +262 -0
- package/convex/cloud/workflows/crudLorobeads.ts +371 -0
- package/convex/cloud/workflows/crudSkills.ts +205 -0
- package/convex/cloud/workflows/crudThreads.ts +708 -0
- package/convex/cloud/workflows/lifecycleSandbox.ts +1396 -0
- package/convex/cloud/workflows/sandboxConvex.ts +1046 -0
- package/convex/sandbox/README.md +90 -0
- package/convex/sandbox/_generated/api.d.ts +2934 -0
- package/convex/sandbox/_generated/api.js +23 -0
- package/convex/sandbox/_generated/dataModel.d.ts +60 -0
- package/convex/sandbox/_generated/server.d.ts +143 -0
- package/convex/sandbox/_generated/server.js +93 -0
- package/convex/sandbox/actions/bash.ts +130 -0
- package/convex/sandbox/actions/browser.ts +282 -0
- package/convex/sandbox/actions/file.ts +336 -0
- package/convex/sandbox/actions/lsp.ts +325 -0
- package/convex/sandbox/actions/pdf.ts +119 -0
- package/convex/sandbox/agent/codeExecLoop.ts +535 -0
- package/convex/sandbox/agent/decisions.ts +284 -0
- package/convex/sandbox/agent/index.ts +515 -0
- package/convex/sandbox/agent/subagents.ts +651 -0
- package/convex/sandbox/brandResearch/index.ts +417 -0
- package/convex/sandbox/context/index.ts +7 -0
- package/convex/sandbox/context/session.ts +402 -0
- package/convex/sandbox/convex.config.ts +17 -0
- package/convex/sandbox/index.ts +51 -0
- package/convex/sandbox/nodeActions/codeExec.ts +130 -0
- package/convex/sandbox/planning/beads.ts +187 -0
- package/convex/sandbox/planning/index.ts +8 -0
- package/convex/sandbox/planning/sync.ts +194 -0
- package/convex/sandbox/prompts/codeExec.ts +852 -0
- package/convex/sandbox/prompts/modes.ts +231 -0
- package/convex/sandbox/prompts/system.ts +142 -0
- package/convex/sandbox/schema.ts +510 -0
- package/convex/sandbox/state/artifacts.ts +99 -0
- package/convex/sandbox/state/checkpoints.ts +341 -0
- package/convex/sandbox/state/files.ts +383 -0
- package/convex/sandbox/state/index.ts +10 -0
- package/convex/sandbox/state/verification.actions.ts +268 -0
- package/convex/sandbox/state/verification.ts +101 -0
- package/convex/sandbox/tsconfig.json +25 -0
- package/convex/sandbox/utils/codeExecHelpers.ts +52 -0
- package/dist/cli/commands/build.d.ts +19 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/build.js +223 -0
- package/dist/cli/commands/init.d.ts +16 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +148 -0
- package/dist/cli/commands/publish.d.ts +12 -0
- package/dist/cli/commands/publish.d.ts.map +1 -0
- package/dist/cli/commands/publish.js +33 -0
- package/dist/cli/index.d.ts +14 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +40 -0
- package/dist/sdk/builders.d.ts +104 -0
- package/dist/sdk/builders.d.ts.map +1 -0
- package/dist/sdk/builders.js +214 -0
- package/dist/sdk/index.d.ts +29 -0
- package/dist/sdk/index.d.ts.map +1 -0
- package/dist/sdk/index.js +38 -0
- package/dist/sdk/types.d.ts +107 -0
- package/dist/sdk/types.d.ts.map +1 -0
- package/dist/sdk/types.js +6 -0
- package/ksa/README.md +263 -0
- package/ksa/_generated/REFERENCE.md +2954 -0
- package/ksa/_generated/registry.ts +257 -0
- package/ksa/_shared/configReader.ts +302 -0
- package/ksa/_shared/configSchemas.ts +649 -0
- package/ksa/_shared/gateway.ts +175 -0
- package/ksa/_shared/ksaBehaviors.ts +411 -0
- package/ksa/_shared/ksaProxy.ts +248 -0
- package/ksa/_shared/localDb.ts +302 -0
- package/ksa/index.ts +134 -0
- package/package.json +93 -0
- package/runtime/browser/agent-browser.ts +330 -0
- package/runtime/entrypoint.ts +194 -0
- package/runtime/lsp/manager.ts +366 -0
- package/runtime/pdf/pdf-generator.ts +50 -0
- package/runtime/pdf/renderer.ts +357 -0
- package/runtime/pdf/schema.ts +97 -0
- package/runtime/services/file-watcher.ts +191 -0
- package/template/build.ts +307 -0
- package/template/e2b/Dockerfile +69 -0
- package/template/e2b/e2b.toml +13 -0
- package/template/e2b/prebuild.sh +68 -0
- 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
|