@agentforge-ai/cli 0.4.2 → 0.5.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 (67) hide show
  1. package/dist/default/README.md +81 -81
  2. package/dist/default/convex/agents.ts +204 -0
  3. package/dist/default/convex/apiKeys.ts +133 -0
  4. package/dist/default/convex/cronJobs.ts +224 -0
  5. package/dist/default/convex/files.ts +103 -0
  6. package/dist/default/convex/folders.ts +110 -0
  7. package/dist/default/convex/heartbeat.ts +371 -0
  8. package/dist/default/convex/logs.ts +66 -0
  9. package/dist/default/convex/mastraIntegration.ts +184 -0
  10. package/dist/default/convex/mcpConnections.ts +127 -0
  11. package/dist/default/convex/messages.ts +90 -0
  12. package/dist/default/convex/projects.ts +114 -0
  13. package/dist/default/convex/sessions.ts +174 -0
  14. package/dist/default/convex/settings.ts +79 -0
  15. package/dist/default/convex/skills.ts +178 -0
  16. package/dist/default/convex/threads.ts +100 -0
  17. package/dist/default/convex/usage.ts +195 -0
  18. package/dist/default/convex/vault.ts +383 -0
  19. package/dist/default/dashboard/app/main.tsx +7 -3
  20. package/dist/default/dashboard/app/routes/agents.tsx +103 -161
  21. package/dist/default/dashboard/app/routes/chat.tsx +163 -317
  22. package/dist/default/dashboard/app/routes/connections.tsx +247 -386
  23. package/dist/default/dashboard/app/routes/cron.tsx +127 -286
  24. package/dist/default/dashboard/app/routes/files.tsx +184 -167
  25. package/dist/default/dashboard/app/routes/index.tsx +63 -96
  26. package/dist/default/dashboard/app/routes/projects.tsx +106 -225
  27. package/dist/default/dashboard/app/routes/sessions.tsx +87 -253
  28. package/dist/default/dashboard/app/routes/settings.tsx +316 -532
  29. package/dist/default/dashboard/app/routes/skills.tsx +329 -216
  30. package/dist/default/dashboard/app/routes/usage.tsx +107 -150
  31. package/dist/default/dashboard/tsconfig.json +3 -2
  32. package/dist/default/dashboard/vite.config.ts +6 -0
  33. package/dist/index.js +279 -50
  34. package/dist/index.js.map +1 -1
  35. package/package.json +1 -1
  36. package/templates/default/README.md +81 -81
  37. package/templates/default/convex/agents.ts +204 -0
  38. package/templates/default/convex/apiKeys.ts +133 -0
  39. package/templates/default/convex/cronJobs.ts +224 -0
  40. package/templates/default/convex/files.ts +103 -0
  41. package/templates/default/convex/folders.ts +110 -0
  42. package/templates/default/convex/heartbeat.ts +371 -0
  43. package/templates/default/convex/logs.ts +66 -0
  44. package/templates/default/convex/mastraIntegration.ts +184 -0
  45. package/templates/default/convex/mcpConnections.ts +127 -0
  46. package/templates/default/convex/messages.ts +90 -0
  47. package/templates/default/convex/projects.ts +114 -0
  48. package/templates/default/convex/sessions.ts +174 -0
  49. package/templates/default/convex/settings.ts +79 -0
  50. package/templates/default/convex/skills.ts +178 -0
  51. package/templates/default/convex/threads.ts +100 -0
  52. package/templates/default/convex/usage.ts +195 -0
  53. package/templates/default/convex/vault.ts +383 -0
  54. package/templates/default/dashboard/app/main.tsx +7 -3
  55. package/templates/default/dashboard/app/routes/agents.tsx +103 -161
  56. package/templates/default/dashboard/app/routes/chat.tsx +163 -317
  57. package/templates/default/dashboard/app/routes/connections.tsx +247 -386
  58. package/templates/default/dashboard/app/routes/cron.tsx +127 -286
  59. package/templates/default/dashboard/app/routes/files.tsx +184 -167
  60. package/templates/default/dashboard/app/routes/index.tsx +63 -96
  61. package/templates/default/dashboard/app/routes/projects.tsx +106 -225
  62. package/templates/default/dashboard/app/routes/sessions.tsx +87 -253
  63. package/templates/default/dashboard/app/routes/settings.tsx +316 -532
  64. package/templates/default/dashboard/app/routes/skills.tsx +329 -216
  65. package/templates/default/dashboard/app/routes/usage.tsx +107 -150
  66. package/templates/default/dashboard/tsconfig.json +3 -2
  67. package/templates/default/dashboard/vite.config.ts +6 -0
@@ -0,0 +1,224 @@
1
+ import { v } from "convex/values";
2
+ import { mutation, query, action } from "./_generated/server";
3
+
4
+ // Query: List cron jobs
5
+ export const list = query({
6
+ args: {
7
+ userId: v.optional(v.string()),
8
+ agentId: v.optional(v.string()),
9
+ isEnabled: v.optional(v.boolean()),
10
+ },
11
+ handler: async (ctx, args) => {
12
+ if (args.isEnabled !== undefined) {
13
+ const jobs = await ctx.db
14
+ .query("cronJobs")
15
+ .withIndex("byIsEnabled", (q) => q.eq("isEnabled", args.isEnabled))
16
+ .take(100).collect();
17
+
18
+ if (args.userId) {
19
+ return jobs.filter((j) => j.userId === args.userId);
20
+ }
21
+ if (args.agentId) {
22
+ return jobs.filter((j) => j.agentId === args.agentId);
23
+ }
24
+ return jobs;
25
+ }
26
+
27
+ if (args.agentId) {
28
+ return await ctx.db
29
+ .query("cronJobs")
30
+ .withIndex("byAgentId", (q) => q.eq("agentId", args.agentId))
31
+ .take(100).collect();
32
+ }
33
+
34
+ if (args.userId) {
35
+ return await ctx.db
36
+ .query("cronJobs")
37
+ .withIndex("byUserId", (q) => q.eq("userId", args.userId))
38
+ .take(100).collect();
39
+ }
40
+
41
+ return await ctx.db.query("cronJobs").take(100).collect();
42
+ },
43
+ });
44
+
45
+ // Query: Get cron job by ID
46
+ export const get = query({
47
+ args: { id: v.id("cronJobs") },
48
+ handler: async (ctx, args) => {
49
+ return await ctx.db.get(args.id);
50
+ },
51
+ });
52
+
53
+ // Query: Get jobs due to run
54
+ export const getDueJobs = query({
55
+ args: {},
56
+ handler: async (ctx) => {
57
+ const now = Date.now();
58
+ const jobs = await ctx.db
59
+ .query("cronJobs")
60
+ .withIndex("byNextRun")
61
+ .take(100).collect();
62
+
63
+ return jobs.filter((j) => j.isEnabled && j.nextRun && j.nextRun <= now);
64
+ },
65
+ });
66
+
67
+ // Mutation: Create cron job
68
+ export const create = mutation({
69
+ args: {
70
+ name: v.string(),
71
+ description: v.optional(v.string()),
72
+ schedule: v.string(),
73
+ agentId: v.string(),
74
+ prompt: v.string(),
75
+ userId: v.optional(v.string()),
76
+ metadata: v.optional(v.any()),
77
+ },
78
+ handler: async (ctx, args) => {
79
+ const now = Date.now();
80
+
81
+ // TODO: Parse cron expression to calculate nextRun
82
+ // For now, set it to 1 hour from now
83
+ const nextRun = now + 60 * 60 * 1000;
84
+
85
+ const jobId = await ctx.db.insert("cronJobs", {
86
+ ...args,
87
+ isEnabled: true,
88
+ nextRun,
89
+ createdAt: now,
90
+ updatedAt: now,
91
+ });
92
+ return jobId;
93
+ },
94
+ });
95
+
96
+ // Mutation: Update cron job
97
+ export const update = mutation({
98
+ args: {
99
+ id: v.id("cronJobs"),
100
+ name: v.optional(v.string()),
101
+ description: v.optional(v.string()),
102
+ schedule: v.optional(v.string()),
103
+ prompt: v.optional(v.string()),
104
+ isEnabled: v.optional(v.boolean()),
105
+ metadata: v.optional(v.any()),
106
+ },
107
+ handler: async (ctx, args) => {
108
+ const { id, ...updates } = args;
109
+
110
+ // If schedule changed, recalculate nextRun
111
+ if (updates.schedule) {
112
+ const now = Date.now();
113
+ (updates as any).nextRun = now + 60 * 60 * 1000; // TODO: Parse cron
114
+ }
115
+
116
+ await ctx.db.patch(id, {
117
+ ...updates,
118
+ updatedAt: Date.now(),
119
+ });
120
+ return id;
121
+ },
122
+ });
123
+
124
+ // Mutation: Toggle cron job enabled status
125
+ export const toggleEnabled = mutation({
126
+ args: { id: v.id("cronJobs") },
127
+ handler: async (ctx, args) => {
128
+ const job = await ctx.db.get(args.id);
129
+
130
+ if (!job) {
131
+ throw new Error(`Cron job not found`);
132
+ }
133
+
134
+ await ctx.db.patch(args.id, {
135
+ isEnabled: !job.isEnabled,
136
+ updatedAt: Date.now(),
137
+ });
138
+
139
+ return { success: true, isEnabled: !job.isEnabled };
140
+ },
141
+ });
142
+
143
+ // Mutation: Update last run time
144
+ export const updateLastRun = mutation({
145
+ args: {
146
+ id: v.id("cronJobs"),
147
+ nextRun: v.number(),
148
+ },
149
+ handler: async (ctx, args) => {
150
+ await ctx.db.patch(args.id, {
151
+ lastRun: Date.now(),
152
+ nextRun: args.nextRun,
153
+ });
154
+ return args.id;
155
+ },
156
+ });
157
+
158
+ // Mutation: Delete cron job
159
+ export const remove = mutation({
160
+ args: { id: v.id("cronJobs") },
161
+ handler: async (ctx, args) => {
162
+ // Delete all run history
163
+ const runs = await ctx.db
164
+ .query("cronJobRuns")
165
+ .withIndex("byCronJobId", (q) => q.eq("cronJobId", args.id))
166
+ .take(100).collect();
167
+
168
+ for (const run of runs) {
169
+ await ctx.db.delete(run._id);
170
+ }
171
+
172
+ await ctx.db.delete(args.id);
173
+ return { success: true };
174
+ },
175
+ });
176
+
177
+ // Mutation: Record cron job run
178
+ export const recordRun = mutation({
179
+ args: {
180
+ cronJobId: v.id("cronJobs"),
181
+ status: v.union(
182
+ v.literal("success"),
183
+ v.literal("failed"),
184
+ v.literal("running")
185
+ ),
186
+ output: v.optional(v.string()),
187
+ error: v.optional(v.string()),
188
+ },
189
+ handler: async (ctx, args) => {
190
+ const now = Date.now();
191
+ const runId = await ctx.db.insert("cronJobRuns", {
192
+ cronJobId: args.cronJobId,
193
+ status: args.status,
194
+ startedAt: now,
195
+ ...(args.status !== "running" && { completedAt: now }),
196
+ ...(args.output && { output: args.output }),
197
+ ...(args.error && { error: args.error }),
198
+ });
199
+ return runId;
200
+ },
201
+ });
202
+
203
+ // Query: Get run history for a cron job
204
+ export const getRunHistory = query({
205
+ args: {
206
+ cronJobId: v.id("cronJobs"),
207
+ limit: v.optional(v.number()),
208
+ },
209
+ handler: async (ctx, args) => {
210
+ const runs = await ctx.db
211
+ .query("cronJobRuns")
212
+ .withIndex("byCronJobId", (q) => q.eq("cronJobId", args.cronJobId))
213
+ .take(100).collect();
214
+
215
+ // Sort by startedAt descending
216
+ runs.sort((a, b) => b.startedAt - a.startedAt);
217
+
218
+ if (args.limit) {
219
+ return runs.slice(0, args.limit);
220
+ }
221
+
222
+ return runs;
223
+ },
224
+ });
@@ -0,0 +1,103 @@
1
+ import { v } from "convex/values";
2
+ import { mutation, query } from "./_generated/server";
3
+
4
+ // Query: List files
5
+ export const list = query({
6
+ args: {
7
+ folderId: v.optional(v.id("folders")),
8
+ projectId: v.optional(v.id("projects")),
9
+ userId: v.optional(v.string()),
10
+ },
11
+ handler: async (ctx, args) => {
12
+ if (args.folderId) {
13
+ return await ctx.db
14
+ .query("files")
15
+ .withIndex("byFolderId", (q) => q.eq("folderId", args.folderId))
16
+ .take(100).collect();
17
+ }
18
+
19
+ if (args.projectId) {
20
+ return await ctx.db
21
+ .query("files")
22
+ .withIndex("byProjectId", (q) => q.eq("projectId", args.projectId))
23
+ .take(100).collect();
24
+ }
25
+
26
+ if (args.userId) {
27
+ return await ctx.db
28
+ .query("files")
29
+ .withIndex("byUserId", (q) => q.eq("userId", args.userId))
30
+ .take(100).collect();
31
+ }
32
+
33
+ return await ctx.db.query("files").take(100).collect();
34
+ },
35
+ });
36
+
37
+ // Query: Get file by ID
38
+ export const get = query({
39
+ args: { id: v.id("files") },
40
+ handler: async (ctx, args) => {
41
+ return await ctx.db.get(args.id);
42
+ },
43
+ });
44
+
45
+ // Mutation: Create file metadata (file stored in Cloudflare R2)
46
+ export const create = mutation({
47
+ args: {
48
+ name: v.string(),
49
+ originalName: v.string(),
50
+ mimeType: v.string(),
51
+ size: v.number(),
52
+ url: v.string(),
53
+ folderId: v.optional(v.id("folders")),
54
+ projectId: v.optional(v.id("projects")),
55
+ userId: v.optional(v.string()),
56
+ metadata: v.optional(v.any()),
57
+ },
58
+ handler: async (ctx, args) => {
59
+ const fileId = await ctx.db.insert("files", {
60
+ ...args,
61
+ uploadedAt: Date.now(),
62
+ });
63
+ return fileId;
64
+ },
65
+ });
66
+
67
+ // Mutation: Update file metadata
68
+ export const update = mutation({
69
+ args: {
70
+ id: v.id("files"),
71
+ name: v.optional(v.string()),
72
+ folderId: v.optional(v.id("folders")),
73
+ metadata: v.optional(v.any()),
74
+ },
75
+ handler: async (ctx, args) => {
76
+ const { id, ...updates } = args;
77
+ await ctx.db.patch(id, updates);
78
+ return id;
79
+ },
80
+ });
81
+
82
+ // Mutation: Delete file
83
+ export const remove = mutation({
84
+ args: { id: v.id("files") },
85
+ handler: async (ctx, args) => {
86
+ await ctx.db.delete(args.id);
87
+ return { success: true };
88
+ },
89
+ });
90
+
91
+ // Mutation: Move file to folder
92
+ export const moveToFolder = mutation({
93
+ args: {
94
+ id: v.id("files"),
95
+ folderId: v.optional(v.id("folders")),
96
+ },
97
+ handler: async (ctx, args) => {
98
+ await ctx.db.patch(args.id, {
99
+ folderId: args.folderId,
100
+ });
101
+ return args.id;
102
+ },
103
+ });
@@ -0,0 +1,110 @@
1
+ import { v } from "convex/values";
2
+ import { mutation, query } from "./_generated/server";
3
+
4
+ // Query: List folders
5
+ export const list = query({
6
+ args: {
7
+ parentId: v.optional(v.id("folders")),
8
+ projectId: v.optional(v.id("projects")),
9
+ userId: v.optional(v.string()),
10
+ },
11
+ handler: async (ctx, args) => {
12
+ if (args.projectId) {
13
+ return await ctx.db
14
+ .query("folders")
15
+ .withIndex("byProjectId", (q) => q.eq("projectId", args.projectId))
16
+ .take(100).collect();
17
+ }
18
+
19
+ if (args.parentId) {
20
+ return await ctx.db
21
+ .query("folders")
22
+ .withIndex("byParentId", (q) => q.eq("parentId", args.parentId))
23
+ .take(100).collect();
24
+ }
25
+
26
+ if (args.userId) {
27
+ return await ctx.db
28
+ .query("folders")
29
+ .withIndex("byUserId", (q) => q.eq("userId", args.userId))
30
+ .take(100).collect();
31
+ }
32
+
33
+ return await ctx.db.query("folders").take(100).collect();
34
+ },
35
+ });
36
+
37
+ // Query: Get folder by ID
38
+ export const get = query({
39
+ args: { id: v.id("folders") },
40
+ handler: async (ctx, args) => {
41
+ return await ctx.db.get(args.id);
42
+ },
43
+ });
44
+
45
+ // Mutation: Create folder
46
+ export const create = mutation({
47
+ args: {
48
+ name: v.string(),
49
+ parentId: v.optional(v.id("folders")),
50
+ projectId: v.optional(v.id("projects")),
51
+ userId: v.optional(v.string()),
52
+ },
53
+ handler: async (ctx, args) => {
54
+ const now = Date.now();
55
+ const folderId = await ctx.db.insert("folders", {
56
+ ...args,
57
+ createdAt: now,
58
+ updatedAt: now,
59
+ });
60
+ return folderId;
61
+ },
62
+ });
63
+
64
+ // Mutation: Update folder
65
+ export const update = mutation({
66
+ args: {
67
+ id: v.id("folders"),
68
+ name: v.optional(v.string()),
69
+ parentId: v.optional(v.id("folders")),
70
+ },
71
+ handler: async (ctx, args) => {
72
+ const { id, ...updates } = args;
73
+ await ctx.db.patch(id, {
74
+ ...updates,
75
+ updatedAt: Date.now(),
76
+ });
77
+ return id;
78
+ },
79
+ });
80
+
81
+ // Mutation: Delete folder
82
+ export const remove = mutation({
83
+ args: { id: v.id("folders") },
84
+ handler: async (ctx, args) => {
85
+ // Delete all files in the folder
86
+ const files = await ctx.db
87
+ .query("files")
88
+ .withIndex("byFolderId", (q) => q.eq("folderId", args.id))
89
+ .take(100).collect();
90
+
91
+ for (const file of files) {
92
+ await ctx.db.delete(file._id);
93
+ }
94
+
95
+ // Delete all subfolders recursively
96
+ const subfolders = await ctx.db
97
+ .query("folders")
98
+ .withIndex("byParentId", (q) => q.eq("parentId", args.id))
99
+ .take(100).collect();
100
+
101
+ for (const subfolder of subfolders) {
102
+ // Recursive delete (will be called via mutation)
103
+ await ctx.db.delete(subfolder._id);
104
+ }
105
+
106
+ // Delete the folder itself
107
+ await ctx.db.delete(args.id);
108
+ return { success: true };
109
+ },
110
+ });