@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,325 @@
1
+ "use node";
2
+
3
+ /**
4
+ * LSP Actions
5
+ *
6
+ * Internal actions for Language Server Protocol operations.
7
+ * Manages LSP server lifecycle and communication.
8
+ */
9
+
10
+ import { internalAction } from "../_generated/server";
11
+ import { v } from "convex/values";
12
+
13
+ // LSP server state (managed by runtime/lsp/manager.ts)
14
+ // These actions communicate with the LSP manager
15
+
16
+ /**
17
+ * Get diagnostics for a file
18
+ */
19
+ export const getDiagnostics = internalAction({
20
+ args: {
21
+ path: v.string(),
22
+ language: v.optional(v.union(v.literal("typescript"), v.literal("python"), v.literal("rust"))),
23
+ },
24
+ handler: async (ctx, args) => {
25
+ const language = args.language || detectLanguage(args.path);
26
+ if (!language) {
27
+ return { success: false, error: "Could not determine language", diagnostics: [] };
28
+ }
29
+
30
+ try {
31
+ // Read file content
32
+ const fs = await import("fs/promises");
33
+ const content = await fs.readFile(args.path, "utf8");
34
+
35
+ // For TypeScript, we can use the TypeScript compiler API directly
36
+ // This is more reliable than waiting for LSP diagnostics
37
+ if (language === "typescript") {
38
+ const diagnostics = await getTypeScriptDiagnostics(args.path, content);
39
+ return { success: true, diagnostics };
40
+ }
41
+
42
+ // For other languages, return empty for now
43
+ // Full LSP integration would use the runtime/lsp/manager.ts
44
+ return { success: true, diagnostics: [], message: `LSP for ${language} not yet integrated` };
45
+ } catch (error: any) {
46
+ return { success: false, error: error.message, diagnostics: [] };
47
+ }
48
+ },
49
+ });
50
+
51
+ /**
52
+ * Get completions at a position
53
+ */
54
+ export const getCompletions = internalAction({
55
+ args: {
56
+ path: v.string(),
57
+ line: v.number(),
58
+ character: v.number(),
59
+ },
60
+ handler: async (ctx, args) => {
61
+ const language = detectLanguage(args.path);
62
+ if (!language) {
63
+ return { success: false, error: "Could not determine language", completions: [] };
64
+ }
65
+
66
+ try {
67
+ // For TypeScript, use TS language service
68
+ if (language === "typescript") {
69
+ const completions = await getTypeScriptCompletions(args.path, args.line, args.character);
70
+ return { success: true, completions };
71
+ }
72
+
73
+ return { success: true, completions: [], message: `LSP for ${language} not yet integrated` };
74
+ } catch (error: any) {
75
+ return { success: false, error: error.message, completions: [] };
76
+ }
77
+ },
78
+ });
79
+
80
+ /**
81
+ * Get hover information at a position
82
+ */
83
+ export const getHover = internalAction({
84
+ args: {
85
+ path: v.string(),
86
+ line: v.number(),
87
+ character: v.number(),
88
+ },
89
+ handler: async (ctx, args) => {
90
+ const language = detectLanguage(args.path);
91
+ if (!language) {
92
+ return { success: false, error: "Could not determine language" };
93
+ }
94
+
95
+ try {
96
+ if (language === "typescript") {
97
+ const hover = await getTypeScriptHover(args.path, args.line, args.character);
98
+ return { success: true, hover };
99
+ }
100
+
101
+ return { success: true, hover: null, message: `LSP for ${language} not yet integrated` };
102
+ } catch (error: any) {
103
+ return { success: false, error: error.message };
104
+ }
105
+ },
106
+ });
107
+
108
+ /**
109
+ * Get definition locations
110
+ */
111
+ export const getDefinition = internalAction({
112
+ args: {
113
+ path: v.string(),
114
+ line: v.number(),
115
+ character: v.number(),
116
+ },
117
+ handler: async (ctx, args) => {
118
+ const language = detectLanguage(args.path);
119
+ if (!language) {
120
+ return { success: false, error: "Could not determine language", definitions: [] };
121
+ }
122
+
123
+ try {
124
+ if (language === "typescript") {
125
+ const definitions = await getTypeScriptDefinition(args.path, args.line, args.character);
126
+ return { success: true, definitions };
127
+ }
128
+
129
+ return { success: true, definitions: [], message: `LSP for ${language} not yet integrated` };
130
+ } catch (error: any) {
131
+ return { success: false, error: error.message, definitions: [] };
132
+ }
133
+ },
134
+ });
135
+
136
+ /**
137
+ * Get references to a symbol
138
+ */
139
+ export const getReferences = internalAction({
140
+ args: {
141
+ path: v.string(),
142
+ line: v.number(),
143
+ character: v.number(),
144
+ },
145
+ handler: async (ctx, args) => {
146
+ const language = detectLanguage(args.path);
147
+ if (!language) {
148
+ return { success: false, error: "Could not determine language", references: [] };
149
+ }
150
+
151
+ try {
152
+ if (language === "typescript") {
153
+ const references = await getTypeScriptReferences(args.path, args.line, args.character);
154
+ return { success: true, references };
155
+ }
156
+
157
+ return { success: true, references: [], message: `LSP for ${language} not yet integrated` };
158
+ } catch (error: any) {
159
+ return { success: false, error: error.message, references: [] };
160
+ }
161
+ },
162
+ });
163
+
164
+ /**
165
+ * Get rename edits for a symbol
166
+ */
167
+ export const getRenameEdits = internalAction({
168
+ args: {
169
+ path: v.string(),
170
+ line: v.number(),
171
+ character: v.number(),
172
+ newName: v.string(),
173
+ },
174
+ handler: async (ctx, args) => {
175
+ const language = detectLanguage(args.path);
176
+ if (!language) {
177
+ return { success: false, error: "Could not determine language", edits: [] };
178
+ }
179
+
180
+ try {
181
+ if (language === "typescript") {
182
+ const edits = await getTypeScriptRenameEdits(
183
+ args.path,
184
+ args.line,
185
+ args.character,
186
+ args.newName
187
+ );
188
+ return { success: true, edits };
189
+ }
190
+
191
+ return { success: true, edits: [], message: `LSP for ${language} not yet integrated` };
192
+ } catch (error: any) {
193
+ return { success: false, error: error.message, edits: [] };
194
+ }
195
+ },
196
+ });
197
+
198
+ // ============================================
199
+ // Helper Functions
200
+ // ============================================
201
+
202
+ function detectLanguage(path: string): "typescript" | "python" | "rust" | null {
203
+ const ext = path.slice(path.lastIndexOf(".")).toLowerCase();
204
+
205
+ if ([".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"].includes(ext)) {
206
+ return "typescript";
207
+ }
208
+ if ([".py", ".pyi"].includes(ext)) {
209
+ return "python";
210
+ }
211
+ if (ext === ".rs") {
212
+ return "rust";
213
+ }
214
+
215
+ return null;
216
+ }
217
+
218
+ // TypeScript-specific implementations using the TypeScript compiler API
219
+
220
+ async function getTypeScriptDiagnostics(
221
+ path: string,
222
+ content: string
223
+ ): Promise<Array<{
224
+ line: number;
225
+ character: number;
226
+ severity: string;
227
+ message: string;
228
+ code?: number;
229
+ }>> {
230
+ try {
231
+ const ts = await import("typescript");
232
+
233
+ const compilerOptions: any = {
234
+ target: ts.ScriptTarget.ESNext,
235
+ module: ts.ModuleKind.ESNext,
236
+ strict: true,
237
+ esModuleInterop: true,
238
+ skipLibCheck: true,
239
+ noEmit: true,
240
+ };
241
+
242
+ const host = ts.createCompilerHost(compilerOptions);
243
+ const originalReadFile = host.readFile;
244
+ host.readFile = (fileName) => {
245
+ if (fileName === path) return content;
246
+ return originalReadFile(fileName);
247
+ };
248
+
249
+ const program = ts.createProgram([path], compilerOptions, host);
250
+ const sourceFile = program.getSourceFile(path);
251
+ if (!sourceFile) return [];
252
+
253
+ const diagnostics = [
254
+ ...program.getSyntacticDiagnostics(sourceFile),
255
+ ...program.getSemanticDiagnostics(sourceFile),
256
+ ];
257
+
258
+ return diagnostics.map((d) => {
259
+ const start = d.start ?? 0;
260
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(start);
261
+
262
+ return {
263
+ line,
264
+ character,
265
+ severity:
266
+ d.category === ts.DiagnosticCategory.Error
267
+ ? "error"
268
+ : d.category === ts.DiagnosticCategory.Warning
269
+ ? "warning"
270
+ : "info",
271
+ message: ts.flattenDiagnosticMessageText(d.messageText, "\n"),
272
+ code: d.code,
273
+ };
274
+ });
275
+ } catch (error) {
276
+ console.error("[lsp] TypeScript diagnostics failed:", error);
277
+ return [];
278
+ }
279
+ }
280
+
281
+ async function getTypeScriptCompletions(
282
+ path: string,
283
+ line: number,
284
+ character: number
285
+ ): Promise<Array<{ label: string; kind: string; detail?: string }>> {
286
+ // Simplified completion - full implementation would use TS language service
287
+ return [];
288
+ }
289
+
290
+ async function getTypeScriptHover(
291
+ path: string,
292
+ line: number,
293
+ character: number
294
+ ): Promise<{ contents: string } | null> {
295
+ // Simplified hover - full implementation would use TS language service
296
+ return null;
297
+ }
298
+
299
+ async function getTypeScriptDefinition(
300
+ path: string,
301
+ line: number,
302
+ character: number
303
+ ): Promise<Array<{ path: string; line: number; character: number }>> {
304
+ // Simplified definition - full implementation would use TS language service
305
+ return [];
306
+ }
307
+
308
+ async function getTypeScriptReferences(
309
+ path: string,
310
+ line: number,
311
+ character: number
312
+ ): Promise<Array<{ path: string; line: number; character: number }>> {
313
+ // Simplified references - full implementation would use TS language service
314
+ return [];
315
+ }
316
+
317
+ async function getTypeScriptRenameEdits(
318
+ path: string,
319
+ line: number,
320
+ character: number,
321
+ newName: string
322
+ ): Promise<Array<{ path: string; oldText: string; newText: string; line: number; character: number }>> {
323
+ // Simplified rename - full implementation would use TS language service
324
+ return [];
325
+ }
@@ -0,0 +1,119 @@
1
+ "use node";
2
+
3
+ /**
4
+ * PDF Generation Action
5
+ *
6
+ * Calls the runtime PDF generator script which uses PDFKit.
7
+ * Running via external script ensures fonts are properly resolved.
8
+ */
9
+
10
+ import { internalAction } from "../_generated/server";
11
+ import { v } from "convex/values";
12
+ import { execSync } from "child_process";
13
+ import * as fs from "fs";
14
+
15
+ /**
16
+ * Generate a PDF from markdown content using runtime script
17
+ */
18
+ export const generatePdf = internalAction({
19
+ args: {
20
+ filename: v.string(),
21
+ content: v.string(),
22
+ title: v.optional(v.string()),
23
+ format: v.optional(v.union(v.literal("a4"), v.literal("letter"))),
24
+ outputDir: v.optional(v.string()),
25
+ },
26
+ handler: async (_ctx, args) => {
27
+ const outputDir = args.outputDir || "/home/user/artifacts";
28
+ const outputPath = `${outputDir}/${args.filename}.pdf`;
29
+
30
+ try {
31
+ // Ensure output directory exists
32
+ if (!fs.existsSync(outputDir)) {
33
+ fs.mkdirSync(outputDir, { recursive: true });
34
+ }
35
+
36
+ // Write content to temp file
37
+ const tempFile = `/tmp/pdf-content-${Date.now()}.md`;
38
+ fs.writeFileSync(tempFile, args.content);
39
+
40
+ // Build command - call the runtime PDF generator
41
+ const titleArg = args.title ? `"${args.title.replace(/"/g, '\\"')}"` : '""';
42
+ const cmd = `cat "${tempFile}" | bun run /home/user/lakitu/runtime/pdf-generator.ts "${outputPath}" ${titleArg}`;
43
+
44
+ console.log(`[pdf action] Running: ${cmd}`);
45
+
46
+ // Execute PDF generator
47
+ const result = execSync(cmd, {
48
+ encoding: "utf-8",
49
+ timeout: 60000,
50
+ cwd: "/home/user/lakitu",
51
+ env: {
52
+ ...process.env,
53
+ HOME: "/home/user",
54
+ PATH: "/home/user/.bun/bin:/usr/local/bin:/usr/bin:/bin",
55
+ },
56
+ });
57
+
58
+ // Clean up temp file
59
+ try {
60
+ fs.unlinkSync(tempFile);
61
+ } catch (e) {
62
+ console.warn("[pdf action] Failed to clean temp file:", e);
63
+ }
64
+
65
+ // Parse result
66
+ const parsed = JSON.parse(result.trim());
67
+
68
+ if (!parsed.success) {
69
+ console.error("[pdf action] Generator failed:", parsed.error);
70
+ return {
71
+ success: false,
72
+ error: parsed.error || "PDF generation failed",
73
+ path: "",
74
+ filename: "",
75
+ size: 0,
76
+ pdfBase64: "",
77
+ };
78
+ }
79
+
80
+ // Read PDF and convert to base64
81
+ const pdfBuffer = fs.readFileSync(outputPath);
82
+ const pdfBase64 = pdfBuffer.toString("base64");
83
+
84
+ console.log(`[pdf action] Generated PDF: ${outputPath} (${pdfBuffer.length} bytes)`);
85
+
86
+ return {
87
+ success: true,
88
+ path: outputPath,
89
+ filename: `${args.filename}.pdf`,
90
+ size: parsed.size || pdfBuffer.length,
91
+ pdfBase64,
92
+ };
93
+ } catch (error) {
94
+ const errorMsg = error instanceof Error ? error.message : String(error);
95
+ console.error("[pdf action] Error:", errorMsg);
96
+
97
+ // Check for specific error types
98
+ if (errorMsg.includes("ENOENT") && errorMsg.includes("pdf-generator")) {
99
+ return {
100
+ success: false,
101
+ error: "PDF generator script not found. Ensure /home/user/lakitu/runtime/pdf-generator.ts exists.",
102
+ path: "",
103
+ filename: "",
104
+ size: 0,
105
+ pdfBase64: "",
106
+ };
107
+ }
108
+
109
+ return {
110
+ success: false,
111
+ error: errorMsg,
112
+ path: "",
113
+ filename: "",
114
+ size: 0,
115
+ pdfBase64: "",
116
+ };
117
+ }
118
+ },
119
+ });