@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,127 @@
1
+ import { v } from "convex/values";
2
+ import { mutation, query } from "./_generated/server";
3
+
4
+ // Query: List MCP connections
5
+ export const list = query({
6
+ args: {
7
+ userId: v.optional(v.string()),
8
+ isEnabled: v.optional(v.boolean()),
9
+ },
10
+ handler: async (ctx, args) => {
11
+ if (args.isEnabled !== undefined) {
12
+ const connections = await ctx.db
13
+ .query("mcpConnections")
14
+ .withIndex("byIsEnabled", (q) => q.eq("isEnabled", args.isEnabled))
15
+ .take(100).collect();
16
+
17
+ if (args.userId) {
18
+ return connections.filter((c) => c.userId === args.userId);
19
+ }
20
+ return connections;
21
+ }
22
+
23
+ if (args.userId) {
24
+ return await ctx.db
25
+ .query("mcpConnections")
26
+ .withIndex("byUserId", (q) => q.eq("userId", args.userId))
27
+ .take(100).collect();
28
+ }
29
+
30
+ return await ctx.db.query("mcpConnections").take(100).collect();
31
+ },
32
+ });
33
+
34
+ // Query: Get MCP connection by ID
35
+ export const get = query({
36
+ args: { id: v.id("mcpConnections") },
37
+ handler: async (ctx, args) => {
38
+ return await ctx.db.get(args.id);
39
+ },
40
+ });
41
+
42
+ // Mutation: Create MCP connection
43
+ export const create = mutation({
44
+ args: {
45
+ name: v.string(),
46
+ serverUrl: v.string(),
47
+ protocol: v.string(),
48
+ credentials: v.optional(v.any()),
49
+ capabilities: v.optional(v.any()),
50
+ userId: v.optional(v.string()),
51
+ },
52
+ handler: async (ctx, args) => {
53
+ const now = Date.now();
54
+ const connectionId = await ctx.db.insert("mcpConnections", {
55
+ ...args,
56
+ isConnected: false,
57
+ isEnabled: true,
58
+ createdAt: now,
59
+ updatedAt: now,
60
+ });
61
+ return connectionId;
62
+ },
63
+ });
64
+
65
+ // Mutation: Update MCP connection
66
+ export const update = mutation({
67
+ args: {
68
+ id: v.id("mcpConnections"),
69
+ name: v.optional(v.string()),
70
+ serverUrl: v.optional(v.string()),
71
+ credentials: v.optional(v.any()),
72
+ capabilities: v.optional(v.any()),
73
+ isEnabled: v.optional(v.boolean()),
74
+ },
75
+ handler: async (ctx, args) => {
76
+ const { id, ...updates } = args;
77
+ await ctx.db.patch(id, {
78
+ ...updates,
79
+ updatedAt: Date.now(),
80
+ });
81
+ return id;
82
+ },
83
+ });
84
+
85
+ // Mutation: Update connection status
86
+ export const updateStatus = mutation({
87
+ args: {
88
+ id: v.id("mcpConnections"),
89
+ isConnected: v.boolean(),
90
+ },
91
+ handler: async (ctx, args) => {
92
+ await ctx.db.patch(args.id, {
93
+ isConnected: args.isConnected,
94
+ lastConnectedAt: args.isConnected ? Date.now() : undefined,
95
+ updatedAt: Date.now(),
96
+ });
97
+ return args.id;
98
+ },
99
+ });
100
+
101
+ // Mutation: Toggle MCP connection enabled status
102
+ export const toggleEnabled = mutation({
103
+ args: { id: v.id("mcpConnections") },
104
+ handler: async (ctx, args) => {
105
+ const connection = await ctx.db.get(args.id);
106
+
107
+ if (!connection) {
108
+ throw new Error(`MCP connection not found`);
109
+ }
110
+
111
+ await ctx.db.patch(args.id, {
112
+ isEnabled: !connection.isEnabled,
113
+ updatedAt: Date.now(),
114
+ });
115
+
116
+ return { success: true, isEnabled: !connection.isEnabled };
117
+ },
118
+ });
119
+
120
+ // Mutation: Delete MCP connection
121
+ export const remove = mutation({
122
+ args: { id: v.id("mcpConnections") },
123
+ handler: async (ctx, args) => {
124
+ await ctx.db.delete(args.id);
125
+ return { success: true };
126
+ },
127
+ });
@@ -0,0 +1,90 @@
1
+ import { mutation, query } from "./_generated/server";
2
+ import { v } from "convex/values";
3
+
4
+ // Mutation: Add a message to a thread
5
+ export const add = mutation({
6
+ args: {
7
+ threadId: v.id("threads"),
8
+ role: v.union(
9
+ v.literal("user"),
10
+ v.literal("assistant"),
11
+ v.literal("system"),
12
+ v.literal("tool")
13
+ ),
14
+ content: v.string(),
15
+ tool_calls: v.optional(v.any()),
16
+ },
17
+ handler: async (ctx, args) => {
18
+ const messageId = await ctx.db.insert("messages", {
19
+ ...args,
20
+ createdAt: Date.now(),
21
+ });
22
+
23
+ // Update thread's updatedAt timestamp
24
+ await ctx.db.patch(args.threadId, {
25
+ updatedAt: Date.now(),
26
+ });
27
+
28
+ return messageId;
29
+ },
30
+ });
31
+
32
+ // Mutation: Create a message (alias for add)
33
+ export const create = mutation({
34
+ args: {
35
+ threadId: v.id("threads"),
36
+ role: v.union(
37
+ v.literal("user"),
38
+ v.literal("assistant"),
39
+ v.literal("system"),
40
+ v.literal("tool")
41
+ ),
42
+ content: v.string(),
43
+ tool_calls: v.optional(v.any()),
44
+ },
45
+ handler: async (ctx, args) => {
46
+ const messageId = await ctx.db.insert("messages", {
47
+ ...args,
48
+ createdAt: Date.now(),
49
+ });
50
+ return messageId;
51
+ },
52
+ });
53
+
54
+ // Query: Get messages by thread
55
+ export const list = query({
56
+ args: { threadId: v.id("threads") },
57
+ handler: async (ctx, args) => {
58
+ const messages = await ctx.db
59
+ .query("messages")
60
+ .withIndex("by_thread", (q) => q.eq("threadId", args.threadId))
61
+ .take(100).collect();
62
+ return messages;
63
+ },
64
+ });
65
+
66
+ // Mutation: Delete a message
67
+ export const remove = mutation({
68
+ args: { id: v.id("messages") },
69
+ handler: async (ctx, args) => {
70
+ await ctx.db.delete(args.id);
71
+ return { success: true };
72
+ },
73
+ });
74
+
75
+ // Mutation: Clear all messages in a thread
76
+ export const clearThread = mutation({
77
+ args: { threadId: v.id("threads") },
78
+ handler: async (ctx, args) => {
79
+ const messages = await ctx.db
80
+ .query("messages")
81
+ .withIndex("by_thread", (q) => q.eq("threadId", args.threadId))
82
+ .take(100).collect();
83
+
84
+ for (const message of messages) {
85
+ await ctx.db.delete(message._id);
86
+ }
87
+
88
+ return { success: true, deleted: messages.length };
89
+ },
90
+ });
@@ -0,0 +1,114 @@
1
+ import { v } from "convex/values";
2
+ import { mutation, query } from "./_generated/server";
3
+
4
+ // Query: List projects
5
+ export const list = query({
6
+ args: {
7
+ userId: v.optional(v.string()),
8
+ },
9
+ handler: async (ctx, args) => {
10
+ if (args.userId) {
11
+ return await ctx.db
12
+ .query("projects")
13
+ .withIndex("byUserId", (q) => q.eq("userId", args.userId))
14
+ .take(100).collect();
15
+ }
16
+
17
+ return await ctx.db.query("projects").take(100).collect();
18
+ },
19
+ });
20
+
21
+ // Query: Get project by ID
22
+ export const get = query({
23
+ args: { id: v.id("projects") },
24
+ handler: async (ctx, args) => {
25
+ return await ctx.db.get(args.id);
26
+ },
27
+ });
28
+
29
+ // Mutation: Create project
30
+ export const create = mutation({
31
+ args: {
32
+ name: v.string(),
33
+ description: v.optional(v.string()),
34
+ userId: v.optional(v.string()),
35
+ settings: v.optional(v.any()),
36
+ },
37
+ handler: async (ctx, args) => {
38
+ const now = Date.now();
39
+ const projectId = await ctx.db.insert("projects", {
40
+ ...args,
41
+ createdAt: now,
42
+ updatedAt: now,
43
+ });
44
+ return projectId;
45
+ },
46
+ });
47
+
48
+ // Mutation: Update project
49
+ export const update = mutation({
50
+ args: {
51
+ id: v.id("projects"),
52
+ name: v.optional(v.string()),
53
+ description: v.optional(v.string()),
54
+ settings: v.optional(v.any()),
55
+ },
56
+ handler: async (ctx, args) => {
57
+ const { id, ...updates } = args;
58
+ await ctx.db.patch(id, {
59
+ ...updates,
60
+ updatedAt: Date.now(),
61
+ });
62
+ return id;
63
+ },
64
+ });
65
+
66
+ // Mutation: Delete project
67
+ export const remove = mutation({
68
+ args: { id: v.id("projects") },
69
+ handler: async (ctx, args) => {
70
+ // Delete all threads in the project
71
+ const threads = await ctx.db
72
+ .query("threads")
73
+ .withIndex("byProjectId", (q) => q.eq("projectId", args.id))
74
+ .take(100).collect();
75
+
76
+ for (const thread of threads) {
77
+ // Delete messages in thread
78
+ const messages = await ctx.db
79
+ .query("messages")
80
+ .withIndex("byThread", (q) => q.eq("threadId", thread._id))
81
+ .take(100).collect();
82
+
83
+ for (const message of messages) {
84
+ await ctx.db.delete(message._id);
85
+ }
86
+
87
+ await ctx.db.delete(thread._id);
88
+ }
89
+
90
+ // Delete all files in the project
91
+ const files = await ctx.db
92
+ .query("files")
93
+ .withIndex("byProjectId", (q) => q.eq("projectId", args.id))
94
+ .take(100).collect();
95
+
96
+ for (const file of files) {
97
+ await ctx.db.delete(file._id);
98
+ }
99
+
100
+ // Delete all folders in the project
101
+ const folders = await ctx.db
102
+ .query("folders")
103
+ .withIndex("byProjectId", (q) => q.eq("projectId", args.id))
104
+ .take(100).collect();
105
+
106
+ for (const folder of folders) {
107
+ await ctx.db.delete(folder._id);
108
+ }
109
+
110
+ // Delete the project itself
111
+ await ctx.db.delete(args.id);
112
+ return { success: true };
113
+ },
114
+ });
@@ -0,0 +1,174 @@
1
+ import { v } from "convex/values";
2
+ import { mutation, query } from "./_generated/server";
3
+
4
+ // Query: Get all sessions
5
+ export const list = query({
6
+ args: {
7
+ userId: v.optional(v.string()),
8
+ agentId: v.optional(v.string()),
9
+ status: v.optional(v.string()),
10
+ },
11
+ handler: async (ctx, args) => {
12
+ if (args.status) {
13
+ const sessions = await ctx.db
14
+ .query("sessions")
15
+ .withIndex("byStatus", (q) => q.eq("status", args.status as any))
16
+ .take(100).collect();
17
+
18
+ if (args.userId) {
19
+ return sessions.filter((s) => s.userId === args.userId);
20
+ }
21
+ if (args.agentId) {
22
+ return sessions.filter((s) => s.agentId === args.agentId);
23
+ }
24
+ return sessions;
25
+ }
26
+
27
+ if (args.agentId) {
28
+ return await ctx.db
29
+ .query("sessions")
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("sessions")
37
+ .withIndex("byUserId", (q) => q.eq("userId", args.userId))
38
+ .take(100).collect();
39
+ }
40
+
41
+ return await ctx.db.query("sessions").take(100).collect();
42
+ },
43
+ });
44
+
45
+ // Query: Get session by ID
46
+ export const get = query({
47
+ args: { sessionId: v.string() },
48
+ handler: async (ctx, args) => {
49
+ return await ctx.db
50
+ .query("sessions")
51
+ .withIndex("bySessionId", (q) => q.eq("sessionId", args.sessionId))
52
+ .first();
53
+ },
54
+ });
55
+
56
+ // Query: Get active sessions
57
+ export const listActive = query({
58
+ args: {
59
+ userId: v.optional(v.string()),
60
+ },
61
+ handler: async (ctx, args) => {
62
+ const sessions = await ctx.db
63
+ .query("sessions")
64
+ .withIndex("byStatus", (q) => q.eq("status", "active"))
65
+ .take(100).collect();
66
+
67
+ if (args.userId) {
68
+ return sessions.filter((s) => s.userId === args.userId);
69
+ }
70
+
71
+ return sessions;
72
+ },
73
+ });
74
+
75
+ // Mutation: Create a new session
76
+ export const create = mutation({
77
+ args: {
78
+ sessionId: v.string(),
79
+ threadId: v.id("threads"),
80
+ agentId: v.string(),
81
+ userId: v.optional(v.string()),
82
+ channel: v.optional(v.string()),
83
+ metadata: v.optional(v.any()),
84
+ },
85
+ handler: async (ctx, args) => {
86
+ const now = Date.now();
87
+ const sessionId = await ctx.db.insert("sessions", {
88
+ ...args,
89
+ status: "active",
90
+ startedAt: now,
91
+ lastActivityAt: now,
92
+ });
93
+ return sessionId;
94
+ },
95
+ });
96
+
97
+ // Mutation: Update session activity
98
+ export const updateActivity = mutation({
99
+ args: {
100
+ sessionId: v.string(),
101
+ metadata: v.optional(v.any()),
102
+ },
103
+ handler: async (ctx, args) => {
104
+ const session = await ctx.db
105
+ .query("sessions")
106
+ .withIndex("bySessionId", (q) => q.eq("sessionId", args.sessionId))
107
+ .first();
108
+
109
+ if (!session) {
110
+ throw new Error(`Session ${args.sessionId} not found`);
111
+ }
112
+
113
+ await ctx.db.patch(session._id, {
114
+ lastActivityAt: Date.now(),
115
+ ...(args.metadata && { metadata: args.metadata }),
116
+ });
117
+
118
+ return session._id;
119
+ },
120
+ });
121
+
122
+ // Mutation: Update session status
123
+ export const updateStatus = mutation({
124
+ args: {
125
+ sessionId: v.string(),
126
+ status: v.union(
127
+ v.literal("active"),
128
+ v.literal("paused"),
129
+ v.literal("completed"),
130
+ v.literal("error")
131
+ ),
132
+ },
133
+ handler: async (ctx, args) => {
134
+ const session = await ctx.db
135
+ .query("sessions")
136
+ .withIndex("bySessionId", (q) => q.eq("sessionId", args.sessionId))
137
+ .first();
138
+
139
+ if (!session) {
140
+ throw new Error(`Session ${args.sessionId} not found`);
141
+ }
142
+
143
+ const updates: any = {
144
+ status: args.status,
145
+ lastActivityAt: Date.now(),
146
+ };
147
+
148
+ if (args.status === "completed" || args.status === "error") {
149
+ updates.completedAt = Date.now();
150
+ }
151
+
152
+ await ctx.db.patch(session._id, updates);
153
+
154
+ return session._id;
155
+ },
156
+ });
157
+
158
+ // Mutation: Delete session
159
+ export const remove = mutation({
160
+ args: { sessionId: v.string() },
161
+ handler: async (ctx, args) => {
162
+ const session = await ctx.db
163
+ .query("sessions")
164
+ .withIndex("bySessionId", (q) => q.eq("sessionId", args.sessionId))
165
+ .first();
166
+
167
+ if (!session) {
168
+ throw new Error(`Session ${args.sessionId} not found`);
169
+ }
170
+
171
+ await ctx.db.delete(session._id);
172
+ return { success: true };
173
+ },
174
+ });
@@ -0,0 +1,79 @@
1
+ import { v } from "convex/values";
2
+ import { mutation, query } from "./_generated/server";
3
+
4
+ // Query: Get a setting by key
5
+ export const get = query({
6
+ args: { userId: v.string(), key: v.string() },
7
+ handler: async (ctx, args) => {
8
+ const setting = await ctx.db
9
+ .query("settings")
10
+ .withIndex("byUserIdAndKey", (q) =>
11
+ q.eq("userId", args.userId).eq("key", args.key)
12
+ )
13
+ .first();
14
+ return setting;
15
+ },
16
+ });
17
+
18
+ // Query: List all settings for a user
19
+ export const list = query({
20
+ args: { userId: v.optional(v.string()) },
21
+ handler: async (ctx, args) => {
22
+ if (args.userId) {
23
+ return await ctx.db
24
+ .query("settings")
25
+ .withIndex("byUserId", (q) => q.eq("userId", args.userId!))
26
+ .collect();
27
+ }
28
+ return await ctx.db.query("settings").collect();
29
+ },
30
+ });
31
+
32
+ // Mutation: Set a setting (upsert)
33
+ export const set = mutation({
34
+ args: {
35
+ userId: v.string(),
36
+ key: v.string(),
37
+ value: v.any(),
38
+ },
39
+ handler: async (ctx, args) => {
40
+ const existing = await ctx.db
41
+ .query("settings")
42
+ .withIndex("byUserIdAndKey", (q) =>
43
+ q.eq("userId", args.userId).eq("key", args.key)
44
+ )
45
+ .first();
46
+
47
+ if (existing) {
48
+ await ctx.db.patch(existing._id, {
49
+ value: args.value,
50
+ updatedAt: Date.now(),
51
+ });
52
+ return existing._id;
53
+ }
54
+
55
+ return await ctx.db.insert("settings", {
56
+ userId: args.userId,
57
+ key: args.key,
58
+ value: args.value,
59
+ updatedAt: Date.now(),
60
+ });
61
+ },
62
+ });
63
+
64
+ // Mutation: Delete a setting
65
+ export const remove = mutation({
66
+ args: { userId: v.string(), key: v.string() },
67
+ handler: async (ctx, args) => {
68
+ const existing = await ctx.db
69
+ .query("settings")
70
+ .withIndex("byUserIdAndKey", (q) =>
71
+ q.eq("userId", args.userId).eq("key", args.key)
72
+ )
73
+ .first();
74
+
75
+ if (existing) {
76
+ await ctx.db.delete(existing._id);
77
+ }
78
+ },
79
+ });