@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,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Beads - Task Tracking
|
|
3
|
+
*
|
|
4
|
+
* CRUD operations for task tracking with CRDT support
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { mutation, query } from "../_generated/server";
|
|
8
|
+
import { v } from "convex/values";
|
|
9
|
+
|
|
10
|
+
// ============================================
|
|
11
|
+
// Mutations
|
|
12
|
+
// ============================================
|
|
13
|
+
|
|
14
|
+
export const create = mutation({
|
|
15
|
+
args: {
|
|
16
|
+
title: v.string(),
|
|
17
|
+
type: v.union(
|
|
18
|
+
v.literal("task"),
|
|
19
|
+
v.literal("bug"),
|
|
20
|
+
v.literal("feature"),
|
|
21
|
+
v.literal("chore"),
|
|
22
|
+
v.literal("epic")
|
|
23
|
+
),
|
|
24
|
+
priority: v.optional(v.number()),
|
|
25
|
+
description: v.optional(v.string()),
|
|
26
|
+
labels: v.optional(v.array(v.string())),
|
|
27
|
+
parentId: v.optional(v.id("beads")),
|
|
28
|
+
threadId: v.optional(v.string()),
|
|
29
|
+
},
|
|
30
|
+
handler: async (ctx, args) => {
|
|
31
|
+
return await ctx.db.insert("beads", {
|
|
32
|
+
title: args.title,
|
|
33
|
+
type: args.type,
|
|
34
|
+
status: "open",
|
|
35
|
+
priority: args.priority ?? 2,
|
|
36
|
+
description: args.description,
|
|
37
|
+
labels: args.labels,
|
|
38
|
+
parentId: args.parentId,
|
|
39
|
+
threadId: args.threadId,
|
|
40
|
+
createdAt: Date.now(),
|
|
41
|
+
updatedAt: Date.now(),
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export const update = mutation({
|
|
47
|
+
args: {
|
|
48
|
+
id: v.id("beads"),
|
|
49
|
+
status: v.optional(
|
|
50
|
+
v.union(
|
|
51
|
+
v.literal("open"),
|
|
52
|
+
v.literal("in_progress"),
|
|
53
|
+
v.literal("blocked"),
|
|
54
|
+
v.literal("closed")
|
|
55
|
+
)
|
|
56
|
+
),
|
|
57
|
+
priority: v.optional(v.number()),
|
|
58
|
+
title: v.optional(v.string()),
|
|
59
|
+
description: v.optional(v.string()),
|
|
60
|
+
labels: v.optional(v.array(v.string())),
|
|
61
|
+
blockedBy: v.optional(v.array(v.id("beads"))),
|
|
62
|
+
},
|
|
63
|
+
handler: async (ctx, args) => {
|
|
64
|
+
const { id, ...updates } = args;
|
|
65
|
+
const filtered = Object.fromEntries(
|
|
66
|
+
Object.entries(updates).filter(([_, v]) => v !== undefined)
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
await ctx.db.patch(id, {
|
|
70
|
+
...filtered,
|
|
71
|
+
updatedAt: Date.now(),
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
export const close = mutation({
|
|
77
|
+
args: {
|
|
78
|
+
id: v.id("beads"),
|
|
79
|
+
reason: v.optional(v.string()),
|
|
80
|
+
},
|
|
81
|
+
handler: async (ctx, args) => {
|
|
82
|
+
await ctx.db.patch(args.id, {
|
|
83
|
+
status: "closed",
|
|
84
|
+
closedAt: Date.now(),
|
|
85
|
+
closeReason: args.reason,
|
|
86
|
+
updatedAt: Date.now(),
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// ============================================
|
|
92
|
+
// Queries
|
|
93
|
+
// ============================================
|
|
94
|
+
|
|
95
|
+
export const get = query({
|
|
96
|
+
args: { id: v.id("beads") },
|
|
97
|
+
handler: async (ctx, args) => {
|
|
98
|
+
return await ctx.db.get(args.id);
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
export const list = query({
|
|
103
|
+
args: {
|
|
104
|
+
status: v.optional(
|
|
105
|
+
v.union(
|
|
106
|
+
v.literal("open"),
|
|
107
|
+
v.literal("in_progress"),
|
|
108
|
+
v.literal("blocked"),
|
|
109
|
+
v.literal("closed")
|
|
110
|
+
)
|
|
111
|
+
),
|
|
112
|
+
type: v.optional(
|
|
113
|
+
v.union(
|
|
114
|
+
v.literal("task"),
|
|
115
|
+
v.literal("bug"),
|
|
116
|
+
v.literal("feature"),
|
|
117
|
+
v.literal("chore"),
|
|
118
|
+
v.literal("epic")
|
|
119
|
+
)
|
|
120
|
+
),
|
|
121
|
+
limit: v.optional(v.number()),
|
|
122
|
+
},
|
|
123
|
+
handler: async (ctx, args) => {
|
|
124
|
+
const { status, type } = args;
|
|
125
|
+
const limit = args.limit ?? 50;
|
|
126
|
+
|
|
127
|
+
// Use index if status is specified, otherwise full table scan
|
|
128
|
+
const items = status
|
|
129
|
+
? await ctx.db
|
|
130
|
+
.query("beads")
|
|
131
|
+
.withIndex("by_status", (q) => q.eq("status", status))
|
|
132
|
+
.order("desc")
|
|
133
|
+
.take(limit)
|
|
134
|
+
: await ctx.db.query("beads").order("desc").take(limit);
|
|
135
|
+
|
|
136
|
+
// Filter by type if specified (after index query)
|
|
137
|
+
if (type) {
|
|
138
|
+
return items.filter((i) => i.type === type);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return items;
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
export const getReady = query({
|
|
146
|
+
args: { limit: v.optional(v.number()) },
|
|
147
|
+
handler: async (ctx, args) => {
|
|
148
|
+
// Get all open tasks
|
|
149
|
+
const open = await ctx.db
|
|
150
|
+
.query("beads")
|
|
151
|
+
.withIndex("by_status", (q) => q.eq("status", "open"))
|
|
152
|
+
.collect();
|
|
153
|
+
|
|
154
|
+
// Filter out blocked tasks (those with unresolved blockedBy)
|
|
155
|
+
const ready = [];
|
|
156
|
+
for (const task of open) {
|
|
157
|
+
if (task.blockedBy && task.blockedBy.length > 0) {
|
|
158
|
+
// Check if all blockers are resolved
|
|
159
|
+
const blockers = await Promise.all(
|
|
160
|
+
task.blockedBy.map((id) => ctx.db.get(id))
|
|
161
|
+
);
|
|
162
|
+
const unresolvedBlockers = blockers.filter(
|
|
163
|
+
(b) => b && b.status !== "closed"
|
|
164
|
+
);
|
|
165
|
+
if (unresolvedBlockers.length > 0) {
|
|
166
|
+
continue; // Still blocked
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
ready.push(task);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Sort by priority (ascending = higher priority first)
|
|
173
|
+
ready.sort((a, b) => a.priority - b.priority);
|
|
174
|
+
|
|
175
|
+
return ready.slice(0, args.limit ?? 10);
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
export const getByThread = query({
|
|
180
|
+
args: { threadId: v.string() },
|
|
181
|
+
handler: async (ctx, args) => {
|
|
182
|
+
return await ctx.db
|
|
183
|
+
.query("beads")
|
|
184
|
+
.withIndex("by_thread", (q) => q.eq("threadId", args.threadId))
|
|
185
|
+
.collect();
|
|
186
|
+
},
|
|
187
|
+
});
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync - Cloud ↔ Sandbox Synchronization
|
|
3
|
+
*
|
|
4
|
+
* Queue items for sync to cloud Convex.
|
|
5
|
+
* Handle artifact uploads, state snapshots, and result reporting.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { mutation, query, internalMutation } from "../_generated/server";
|
|
9
|
+
import { v } from "convex/values";
|
|
10
|
+
|
|
11
|
+
// ============================================
|
|
12
|
+
// Mutations
|
|
13
|
+
// ============================================
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Queue an item for sync to cloud
|
|
17
|
+
*/
|
|
18
|
+
export const queueSync = mutation({
|
|
19
|
+
args: {
|
|
20
|
+
type: v.union(
|
|
21
|
+
v.literal("artifact"),
|
|
22
|
+
v.literal("bead"),
|
|
23
|
+
v.literal("decision"),
|
|
24
|
+
v.literal("checkpoint"),
|
|
25
|
+
v.literal("result")
|
|
26
|
+
),
|
|
27
|
+
itemId: v.string(),
|
|
28
|
+
priority: v.optional(v.number()), // 0 = highest
|
|
29
|
+
metadata: v.optional(v.any()),
|
|
30
|
+
},
|
|
31
|
+
handler: async (ctx, args) => {
|
|
32
|
+
return await ctx.db.insert("syncQueue", {
|
|
33
|
+
type: args.type,
|
|
34
|
+
itemId: args.itemId,
|
|
35
|
+
status: "pending",
|
|
36
|
+
priority: args.priority ?? 5,
|
|
37
|
+
metadata: args.metadata,
|
|
38
|
+
createdAt: Date.now(),
|
|
39
|
+
attempts: 0,
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Mark sync item as in progress
|
|
46
|
+
*/
|
|
47
|
+
export const markInProgress = internalMutation({
|
|
48
|
+
args: { id: v.id("syncQueue") },
|
|
49
|
+
handler: async (ctx, args) => {
|
|
50
|
+
await ctx.db.patch(args.id, {
|
|
51
|
+
status: "in_progress",
|
|
52
|
+
startedAt: Date.now(),
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Mark sync item as completed
|
|
59
|
+
*/
|
|
60
|
+
export const markCompleted = internalMutation({
|
|
61
|
+
args: {
|
|
62
|
+
id: v.id("syncQueue"),
|
|
63
|
+
cloudId: v.optional(v.string()),
|
|
64
|
+
},
|
|
65
|
+
handler: async (ctx, args) => {
|
|
66
|
+
await ctx.db.patch(args.id, {
|
|
67
|
+
status: "completed",
|
|
68
|
+
completedAt: Date.now(),
|
|
69
|
+
cloudId: args.cloudId,
|
|
70
|
+
});
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Mark sync item as failed
|
|
76
|
+
*/
|
|
77
|
+
export const markFailed = internalMutation({
|
|
78
|
+
args: {
|
|
79
|
+
id: v.id("syncQueue"),
|
|
80
|
+
error: v.string(),
|
|
81
|
+
},
|
|
82
|
+
handler: async (ctx, args) => {
|
|
83
|
+
const item = await ctx.db.get(args.id);
|
|
84
|
+
if (!item) return;
|
|
85
|
+
|
|
86
|
+
await ctx.db.patch(args.id, {
|
|
87
|
+
status: item.attempts >= 3 ? "failed" : "pending",
|
|
88
|
+
lastError: args.error,
|
|
89
|
+
lastAttemptAt: Date.now(),
|
|
90
|
+
attempts: item.attempts + 1,
|
|
91
|
+
});
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Clear completed sync items
|
|
97
|
+
*/
|
|
98
|
+
export const clearCompleted = mutation({
|
|
99
|
+
args: { olderThanMs: v.optional(v.number()) },
|
|
100
|
+
handler: async (ctx, args) => {
|
|
101
|
+
const cutoff = Date.now() - (args.olderThanMs ?? 3600000); // 1 hour default
|
|
102
|
+
|
|
103
|
+
const completed = await ctx.db
|
|
104
|
+
.query("syncQueue")
|
|
105
|
+
.withIndex("by_status", (q) => q.eq("status", "completed"))
|
|
106
|
+
.collect();
|
|
107
|
+
|
|
108
|
+
let deleted = 0;
|
|
109
|
+
for (const item of completed) {
|
|
110
|
+
if (item.completedAt && item.completedAt < cutoff) {
|
|
111
|
+
await ctx.db.delete(item._id);
|
|
112
|
+
deleted++;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return { deleted };
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// ============================================
|
|
121
|
+
// Queries
|
|
122
|
+
// ============================================
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Get pending sync items
|
|
126
|
+
*/
|
|
127
|
+
export const getPending = query({
|
|
128
|
+
args: { limit: v.optional(v.number()) },
|
|
129
|
+
handler: async (ctx, args) => {
|
|
130
|
+
const items = await ctx.db
|
|
131
|
+
.query("syncQueue")
|
|
132
|
+
.withIndex("by_status", (q) => q.eq("status", "pending"))
|
|
133
|
+
.take(args.limit ?? 50);
|
|
134
|
+
|
|
135
|
+
// Sort by priority (ascending)
|
|
136
|
+
return items.sort((a, b) => a.priority - b.priority);
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get sync queue status
|
|
142
|
+
*/
|
|
143
|
+
export const getStatus = query({
|
|
144
|
+
args: {},
|
|
145
|
+
handler: async (ctx) => {
|
|
146
|
+
const pending = await ctx.db
|
|
147
|
+
.query("syncQueue")
|
|
148
|
+
.withIndex("by_status", (q) => q.eq("status", "pending"))
|
|
149
|
+
.collect();
|
|
150
|
+
|
|
151
|
+
const inProgress = await ctx.db
|
|
152
|
+
.query("syncQueue")
|
|
153
|
+
.withIndex("by_status", (q) => q.eq("status", "in_progress"))
|
|
154
|
+
.collect();
|
|
155
|
+
|
|
156
|
+
const failed = await ctx.db
|
|
157
|
+
.query("syncQueue")
|
|
158
|
+
.withIndex("by_status", (q) => q.eq("status", "failed"))
|
|
159
|
+
.collect();
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
pending: pending.length,
|
|
163
|
+
inProgress: inProgress.length,
|
|
164
|
+
failed: failed.length,
|
|
165
|
+
oldestPending: pending[0]?.createdAt,
|
|
166
|
+
};
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Get failed sync items for retry
|
|
172
|
+
*/
|
|
173
|
+
export const getFailed = query({
|
|
174
|
+
args: {},
|
|
175
|
+
handler: async (ctx) => {
|
|
176
|
+
return await ctx.db
|
|
177
|
+
.query("syncQueue")
|
|
178
|
+
.withIndex("by_status", (q) => q.eq("status", "failed"))
|
|
179
|
+
.collect();
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Get sync history for an item
|
|
185
|
+
*/
|
|
186
|
+
export const getByItemId = query({
|
|
187
|
+
args: { itemId: v.string() },
|
|
188
|
+
handler: async (ctx, args) => {
|
|
189
|
+
return await ctx.db
|
|
190
|
+
.query("syncQueue")
|
|
191
|
+
.filter((q) => q.eq(q.field("itemId"), args.itemId))
|
|
192
|
+
.collect();
|
|
193
|
+
},
|
|
194
|
+
});
|