@agentforge-ai/cli 0.4.3 → 0.5.1

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/convex/agents.ts +204 -0
  2. package/dist/default/convex/apiKeys.ts +133 -0
  3. package/dist/default/convex/cronJobs.ts +224 -0
  4. package/dist/default/convex/files.ts +103 -0
  5. package/dist/default/convex/folders.ts +110 -0
  6. package/dist/default/convex/heartbeat.ts +371 -0
  7. package/dist/default/convex/logs.ts +66 -0
  8. package/dist/default/convex/mastraIntegration.ts +185 -0
  9. package/dist/default/convex/mcpConnections.ts +127 -0
  10. package/dist/default/convex/messages.ts +90 -0
  11. package/dist/default/convex/projects.ts +114 -0
  12. package/dist/default/convex/schema.ts +150 -83
  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 +397 -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 +256 -49
  34. package/dist/index.js.map +1 -1
  35. package/package.json +1 -1
  36. package/templates/default/convex/agents.ts +204 -0
  37. package/templates/default/convex/apiKeys.ts +133 -0
  38. package/templates/default/convex/cronJobs.ts +224 -0
  39. package/templates/default/convex/files.ts +103 -0
  40. package/templates/default/convex/folders.ts +110 -0
  41. package/templates/default/convex/heartbeat.ts +371 -0
  42. package/templates/default/convex/logs.ts +66 -0
  43. package/templates/default/convex/mastraIntegration.ts +185 -0
  44. package/templates/default/convex/mcpConnections.ts +127 -0
  45. package/templates/default/convex/messages.ts +90 -0
  46. package/templates/default/convex/projects.ts +114 -0
  47. package/templates/default/convex/schema.ts +150 -83
  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 +397 -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,178 @@
1
+ import { v } from "convex/values";
2
+ import { mutation, query } from "./_generated/server";
3
+
4
+ // Query: List skills
5
+ export const list = query({
6
+ args: {
7
+ userId: v.optional(v.string()),
8
+ category: v.optional(v.string()),
9
+ isInstalled: v.optional(v.boolean()),
10
+ },
11
+ handler: async (ctx, args) => {
12
+ if (args.category) {
13
+ const skills = await ctx.db
14
+ .query("skills")
15
+ .withIndex("byCategory", (q) => q.eq("category", args.category!))
16
+ .collect();
17
+
18
+ if (args.userId) {
19
+ return skills.filter((s) => s.userId === args.userId);
20
+ }
21
+ if (args.isInstalled !== undefined) {
22
+ return skills.filter((s) => s.isInstalled === args.isInstalled);
23
+ }
24
+ return skills;
25
+ }
26
+
27
+ if (args.isInstalled !== undefined) {
28
+ const skills = await ctx.db
29
+ .query("skills")
30
+ .withIndex("byIsInstalled", (q) => q.eq("isInstalled", args.isInstalled!))
31
+ .collect();
32
+
33
+ if (args.userId) {
34
+ return skills.filter((s) => s.userId === args.userId);
35
+ }
36
+ return skills;
37
+ }
38
+
39
+ if (args.userId) {
40
+ return await ctx.db
41
+ .query("skills")
42
+ .withIndex("byUserId", (q) => q.eq("userId", args.userId!))
43
+ .collect();
44
+ }
45
+
46
+ return await ctx.db.query("skills").collect();
47
+ },
48
+ });
49
+
50
+ // Query: Get skill by ID
51
+ export const get = query({
52
+ args: { id: v.id("skills") },
53
+ handler: async (ctx, args) => {
54
+ return await ctx.db.get(args.id);
55
+ },
56
+ });
57
+
58
+ // Query: Get installed skills
59
+ export const listInstalled = query({
60
+ args: {
61
+ userId: v.optional(v.string()),
62
+ },
63
+ handler: async (ctx, args) => {
64
+ const skills = await ctx.db
65
+ .query("skills")
66
+ .withIndex("byIsInstalled", (q) => q.eq("isInstalled", true))
67
+ .collect();
68
+
69
+ if (args.userId) {
70
+ return skills.filter((s) => s.userId === args.userId);
71
+ }
72
+
73
+ return skills;
74
+ },
75
+ });
76
+
77
+ // Mutation: Create skill
78
+ export const create = mutation({
79
+ args: {
80
+ name: v.string(),
81
+ displayName: v.string(),
82
+ description: v.string(),
83
+ category: v.string(),
84
+ version: v.string(),
85
+ author: v.optional(v.string()),
86
+ repository: v.optional(v.string()),
87
+ documentation: v.optional(v.string()),
88
+ code: v.string(),
89
+ schema: v.optional(v.any()),
90
+ userId: v.optional(v.string()),
91
+ },
92
+ handler: async (ctx, args) => {
93
+ const now = Date.now();
94
+ const skillId = await ctx.db.insert("skills", {
95
+ ...args,
96
+ isInstalled: false,
97
+ isEnabled: false,
98
+ createdAt: now,
99
+ updatedAt: now,
100
+ });
101
+ return skillId;
102
+ },
103
+ });
104
+
105
+ // Mutation: Install skill
106
+ export const install = mutation({
107
+ args: { id: v.id("skills") },
108
+ handler: async (ctx, args) => {
109
+ await ctx.db.patch(args.id, {
110
+ isInstalled: true,
111
+ isEnabled: true,
112
+ installedAt: Date.now(),
113
+ updatedAt: Date.now(),
114
+ });
115
+ return args.id;
116
+ },
117
+ });
118
+
119
+ // Mutation: Uninstall skill
120
+ export const uninstall = mutation({
121
+ args: { id: v.id("skills") },
122
+ handler: async (ctx, args) => {
123
+ await ctx.db.patch(args.id, {
124
+ isInstalled: false,
125
+ isEnabled: false,
126
+ updatedAt: Date.now(),
127
+ });
128
+ return args.id;
129
+ },
130
+ });
131
+
132
+ // Mutation: Toggle skill enabled status
133
+ export const toggleEnabled = mutation({
134
+ args: { id: v.id("skills") },
135
+ handler: async (ctx, args) => {
136
+ const skill = await ctx.db.get(args.id);
137
+
138
+ if (!skill) {
139
+ throw new Error(`Skill not found`);
140
+ }
141
+
142
+ await ctx.db.patch(args.id, {
143
+ isEnabled: !skill.isEnabled,
144
+ updatedAt: Date.now(),
145
+ });
146
+
147
+ return { success: true, isEnabled: !skill.isEnabled };
148
+ },
149
+ });
150
+
151
+ // Mutation: Update skill
152
+ export const update = mutation({
153
+ args: {
154
+ id: v.id("skills"),
155
+ displayName: v.optional(v.string()),
156
+ description: v.optional(v.string()),
157
+ version: v.optional(v.string()),
158
+ code: v.optional(v.string()),
159
+ schema: v.optional(v.any()),
160
+ },
161
+ handler: async (ctx, args) => {
162
+ const { id, ...updates } = args;
163
+ await ctx.db.patch(id, {
164
+ ...updates,
165
+ updatedAt: Date.now(),
166
+ });
167
+ return id;
168
+ },
169
+ });
170
+
171
+ // Mutation: Delete skill
172
+ export const remove = mutation({
173
+ args: { id: v.id("skills") },
174
+ handler: async (ctx, args) => {
175
+ await ctx.db.delete(args.id);
176
+ return { success: true };
177
+ },
178
+ });
@@ -0,0 +1,100 @@
1
+ import { v } from "convex/values";
2
+ import { mutation, query } from "./_generated/server";
3
+
4
+ // Query: Get all threads
5
+ export const list = query({
6
+ args: {
7
+ userId: v.optional(v.string()),
8
+ agentId: v.optional(v.string()),
9
+ projectId: v.optional(v.id("projects")),
10
+ },
11
+ handler: async (ctx, args) => {
12
+ if (args.projectId) {
13
+ return await ctx.db
14
+ .query("threads")
15
+ .withIndex("byProjectId", (q) => q.eq("projectId", args.projectId!))
16
+ .collect();
17
+ }
18
+
19
+ if (args.agentId) {
20
+ return await ctx.db
21
+ .query("threads")
22
+ .withIndex("byAgentId", (q) => q.eq("agentId", args.agentId!))
23
+ .collect();
24
+ }
25
+
26
+ if (args.userId) {
27
+ return await ctx.db
28
+ .query("threads")
29
+ .withIndex("byUserId", (q) => q.eq("userId", args.userId!))
30
+ .collect();
31
+ }
32
+
33
+ return await ctx.db.query("threads").collect();
34
+ },
35
+ });
36
+
37
+ // Query: Get thread by ID
38
+ export const get = query({
39
+ args: { id: v.id("threads") },
40
+ handler: async (ctx, args) => {
41
+ return await ctx.db.get(args.id);
42
+ },
43
+ });
44
+
45
+ // Mutation: Create a new thread
46
+ export const create = mutation({
47
+ args: {
48
+ name: v.optional(v.string()),
49
+ agentId: v.string(),
50
+ userId: v.optional(v.string()),
51
+ projectId: v.optional(v.id("projects")),
52
+ metadata: v.optional(v.any()),
53
+ },
54
+ handler: async (ctx, args) => {
55
+ const now = Date.now();
56
+ const threadId = await ctx.db.insert("threads", {
57
+ ...args,
58
+ createdAt: now,
59
+ updatedAt: now,
60
+ });
61
+ return threadId;
62
+ },
63
+ });
64
+
65
+ // Mutation: Update thread
66
+ export const update = mutation({
67
+ args: {
68
+ id: v.id("threads"),
69
+ name: v.optional(v.string()),
70
+ metadata: v.optional(v.any()),
71
+ },
72
+ handler: async (ctx, args) => {
73
+ const { id, ...updates } = args;
74
+ await ctx.db.patch(id, {
75
+ ...updates,
76
+ updatedAt: Date.now(),
77
+ });
78
+ return id;
79
+ },
80
+ });
81
+
82
+ // Mutation: Delete thread
83
+ export const remove = mutation({
84
+ args: { id: v.id("threads") },
85
+ handler: async (ctx, args) => {
86
+ // Delete all messages in the thread
87
+ const messages = await ctx.db
88
+ .query("messages")
89
+ .withIndex("byThread", (q) => q.eq("threadId", args.id!))
90
+ .collect();
91
+
92
+ for (const message of messages) {
93
+ await ctx.db.delete(message._id);
94
+ }
95
+
96
+ // Delete the thread
97
+ await ctx.db.delete(args.id);
98
+ return { success: true };
99
+ },
100
+ });
@@ -0,0 +1,195 @@
1
+ import { v } from "convex/values";
2
+ import { mutation, query } from "./_generated/server";
3
+
4
+ // Query: Get usage records
5
+ export const list = query({
6
+ args: {
7
+ userId: v.optional(v.string()),
8
+ agentId: v.optional(v.string()),
9
+ provider: v.optional(v.string()),
10
+ startTime: v.optional(v.number()),
11
+ endTime: v.optional(v.number()),
12
+ },
13
+ handler: async (ctx, args) => {
14
+ let records;
15
+
16
+ if (args.provider) {
17
+ records = await ctx.db
18
+ .query("usage")
19
+ .withIndex("byProvider", (q) => q.eq("provider", args.provider!))
20
+ .collect();
21
+ } else if (args.agentId) {
22
+ records = await ctx.db
23
+ .query("usage")
24
+ .withIndex("byAgentId", (q) => q.eq("agentId", args.agentId!))
25
+ .collect();
26
+ } else if (args.userId) {
27
+ records = await ctx.db
28
+ .query("usage")
29
+ .withIndex("byUserId", (q) => q.eq("userId", args.userId!))
30
+ .collect();
31
+ } else {
32
+ records = await ctx.db.query("usage").collect();
33
+ }
34
+
35
+ // Filter by time range if provided
36
+ if (args.startTime) {
37
+ records = records.filter((r) => r.timestamp >= args.startTime!);
38
+ }
39
+ if (args.endTime) {
40
+ records = records.filter((r) => r.timestamp <= args.endTime!);
41
+ }
42
+
43
+ return records;
44
+ },
45
+ });
46
+
47
+ // Query: Get usage statistics
48
+ export const getStats = query({
49
+ args: {
50
+ userId: v.optional(v.string()),
51
+ agentId: v.optional(v.string()),
52
+ startTime: v.optional(v.number()),
53
+ endTime: v.optional(v.number()),
54
+ },
55
+ handler: async (ctx, args) => {
56
+ let records;
57
+
58
+ if (args.agentId) {
59
+ records = await ctx.db
60
+ .query("usage")
61
+ .withIndex("byAgentId", (q) => q.eq("agentId", args.agentId!))
62
+ .collect();
63
+ } else if (args.userId) {
64
+ records = await ctx.db
65
+ .query("usage")
66
+ .withIndex("byUserId", (q) => q.eq("userId", args.userId!))
67
+ .collect();
68
+ } else {
69
+ records = await ctx.db.query("usage").collect();
70
+ }
71
+
72
+ // Filter by time range
73
+ if (args.startTime) {
74
+ records = records.filter((r) => r.timestamp >= args.startTime!);
75
+ }
76
+ if (args.endTime) {
77
+ records = records.filter((r) => r.timestamp <= args.endTime!);
78
+ }
79
+
80
+ // Calculate statistics
81
+ const totalTokens = records.reduce((sum, r) => sum + r.totalTokens, 0);
82
+ const totalCost = records.reduce((sum, r) => sum + (r.cost || 0), 0);
83
+ const totalRequests = records.length;
84
+
85
+ const byProvider: Record<string, { tokens: number; cost: number; requests: number }> = {};
86
+ const byModel: Record<string, { tokens: number; cost: number; requests: number }> = {};
87
+
88
+ for (const record of records) {
89
+ // By provider
90
+ if (!byProvider[record.provider]) {
91
+ byProvider[record.provider] = { tokens: 0, cost: 0, requests: 0 };
92
+ }
93
+ byProvider[record.provider].tokens += record.totalTokens;
94
+ byProvider[record.provider].cost += record.cost || 0;
95
+ byProvider[record.provider].requests += 1;
96
+
97
+ // By model
98
+ if (!byModel[record.model]) {
99
+ byModel[record.model] = { tokens: 0, cost: 0, requests: 0 };
100
+ }
101
+ byModel[record.model].tokens += record.totalTokens;
102
+ byModel[record.model].cost += record.cost || 0;
103
+ byModel[record.model].requests += 1;
104
+ }
105
+
106
+ return {
107
+ totalTokens,
108
+ totalCost,
109
+ totalRequests,
110
+ byProvider,
111
+ byModel,
112
+ };
113
+ },
114
+ });
115
+
116
+ // Query: Get usage by time period
117
+ export const getByTimePeriod = query({
118
+ args: {
119
+ userId: v.optional(v.string()),
120
+ period: v.union(v.literal("day"), v.literal("week"), v.literal("month")),
121
+ },
122
+ handler: async (ctx, args) => {
123
+ const now = Date.now();
124
+ let startTime: number;
125
+
126
+ switch (args.period) {
127
+ case "day":
128
+ startTime = now - 24 * 60 * 60 * 1000;
129
+ break;
130
+ case "week":
131
+ startTime = now - 7 * 24 * 60 * 60 * 1000;
132
+ break;
133
+ case "month":
134
+ startTime = now - 30 * 24 * 60 * 60 * 1000;
135
+ break;
136
+ }
137
+
138
+ let records;
139
+ if (args.userId) {
140
+ records = await ctx.db
141
+ .query("usage")
142
+ .withIndex("byUserId", (q) => q.eq("userId", args.userId!))
143
+ .collect();
144
+ } else {
145
+ records = await ctx.db.query("usage").collect();
146
+ }
147
+
148
+ records = records.filter((r) => r.timestamp >= startTime);
149
+
150
+ return records;
151
+ },
152
+ });
153
+
154
+ // Mutation: Record usage
155
+ export const record = mutation({
156
+ args: {
157
+ agentId: v.string(),
158
+ sessionId: v.optional(v.string()),
159
+ provider: v.string(),
160
+ model: v.string(),
161
+ promptTokens: v.number(),
162
+ completionTokens: v.number(),
163
+ totalTokens: v.number(),
164
+ cost: v.optional(v.number()),
165
+ userId: v.optional(v.string()),
166
+ },
167
+ handler: async (ctx, args) => {
168
+ const usageId = await ctx.db.insert("usage", {
169
+ ...args,
170
+ timestamp: Date.now(),
171
+ });
172
+ return usageId;
173
+ },
174
+ });
175
+
176
+ // Mutation: Delete old usage records
177
+ export const cleanup = mutation({
178
+ args: {
179
+ olderThan: v.number(), // Timestamp
180
+ },
181
+ handler: async (ctx, args) => {
182
+ const records = await ctx.db
183
+ .query("usage")
184
+ .withIndex("byTimestamp")
185
+ .collect();
186
+
187
+ const toDelete = records.filter((r) => r.timestamp < args.olderThan);
188
+
189
+ for (const record of toDelete) {
190
+ await ctx.db.delete(record._id);
191
+ }
192
+
193
+ return { deleted: toDelete.length };
194
+ },
195
+ });