@cortexmemory/cli 0.27.4 → 0.28.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 (66) hide show
  1. package/dist/commands/db.d.ts.map +1 -1
  2. package/dist/commands/db.js +18 -6
  3. package/dist/commands/db.js.map +1 -1
  4. package/dist/commands/deploy.d.ts.map +1 -1
  5. package/dist/commands/deploy.js +74 -34
  6. package/dist/commands/deploy.js.map +1 -1
  7. package/dist/commands/dev.js +3 -2
  8. package/dist/commands/dev.js.map +1 -1
  9. package/dist/commands/init.d.ts.map +1 -1
  10. package/dist/commands/init.js +12 -0
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/types.d.ts +1 -1
  13. package/dist/types.d.ts.map +1 -1
  14. package/dist/utils/app-template-sync.d.ts.map +1 -1
  15. package/dist/utils/app-template-sync.js +3 -1
  16. package/dist/utils/app-template-sync.js.map +1 -1
  17. package/dist/utils/init/quickstart-setup.d.ts.map +1 -1
  18. package/dist/utils/init/quickstart-setup.js.map +1 -1
  19. package/package.json +4 -4
  20. package/templates/basic/.env.local.example +23 -0
  21. package/templates/basic/README.md +181 -56
  22. package/templates/basic/package-lock.json +2180 -406
  23. package/templates/basic/package.json +23 -5
  24. package/templates/basic/src/__tests__/chat.test.ts +340 -0
  25. package/templates/basic/src/__tests__/cortex.test.ts +260 -0
  26. package/templates/basic/src/__tests__/display.test.ts +455 -0
  27. package/templates/basic/src/__tests__/e2e/fact-extraction.test.ts +498 -0
  28. package/templates/basic/src/__tests__/e2e/memory-flow.test.ts +355 -0
  29. package/templates/basic/src/__tests__/e2e/server-e2e.test.ts +414 -0
  30. package/templates/basic/src/__tests__/helpers/test-utils.ts +345 -0
  31. package/templates/basic/src/__tests__/integration/chat-flow.test.ts +422 -0
  32. package/templates/basic/src/__tests__/integration/server.test.ts +441 -0
  33. package/templates/basic/src/__tests__/llm.test.ts +344 -0
  34. package/templates/basic/src/chat.ts +300 -0
  35. package/templates/basic/src/cortex.ts +203 -0
  36. package/templates/basic/src/display.ts +425 -0
  37. package/templates/basic/src/index.ts +194 -64
  38. package/templates/basic/src/llm.ts +214 -0
  39. package/templates/basic/src/server.ts +280 -0
  40. package/templates/basic/vitest.config.ts +33 -0
  41. package/templates/basic/vitest.e2e.config.ts +28 -0
  42. package/templates/basic/vitest.integration.config.ts +25 -0
  43. package/templates/vercel-ai-quickstart/app/api/auth/check/route.ts +1 -1
  44. package/templates/vercel-ai-quickstart/app/api/auth/login/route.ts +6 -9
  45. package/templates/vercel-ai-quickstart/app/api/auth/register/route.ts +14 -18
  46. package/templates/vercel-ai-quickstart/app/api/auth/setup/route.ts +4 -7
  47. package/templates/vercel-ai-quickstart/app/api/chat/route.ts +28 -11
  48. package/templates/vercel-ai-quickstart/app/api/chat-v6/route.ts +19 -13
  49. package/templates/vercel-ai-quickstart/app/api/conversations/route.ts +16 -16
  50. package/templates/vercel-ai-quickstart/app/globals.css +24 -9
  51. package/templates/vercel-ai-quickstart/app/page.tsx +25 -13
  52. package/templates/vercel-ai-quickstart/components/AdminSetup.tsx +3 -1
  53. package/templates/vercel-ai-quickstart/components/AuthProvider.tsx +6 -6
  54. package/templates/vercel-ai-quickstart/components/ChatHistorySidebar.tsx +19 -8
  55. package/templates/vercel-ai-quickstart/components/ChatInterface.tsx +41 -14
  56. package/templates/vercel-ai-quickstart/components/LoginScreen.tsx +10 -5
  57. package/templates/vercel-ai-quickstart/lib/agents/memory-agent.ts +3 -3
  58. package/templates/vercel-ai-quickstart/lib/password.ts +5 -5
  59. package/templates/vercel-ai-quickstart/next.config.js +10 -2
  60. package/templates/vercel-ai-quickstart/package.json +18 -11
  61. package/templates/vercel-ai-quickstart/test-api.mjs +131 -100
  62. package/templates/vercel-ai-quickstart/tests/e2e/chat-memory-flow.test.ts +73 -44
  63. package/templates/vercel-ai-quickstart/tests/helpers/mock-cortex.ts +40 -40
  64. package/templates/vercel-ai-quickstart/tests/integration/auth.test.ts +8 -8
  65. package/templates/vercel-ai-quickstart/tests/integration/conversations.test.ts +12 -8
  66. package/templates/vercel-ai-quickstart/tests/unit/password.test.ts +4 -1
@@ -48,42 +48,40 @@ export function createMockCortex() {
48
48
  const ns = mutableStore.get(namespace);
49
49
  if (!ns) return null;
50
50
  return ns.get(key) ?? null;
51
- }
51
+ },
52
52
  ),
53
53
  set: jest.fn(
54
54
  async (
55
55
  namespace: string,
56
56
  key: string,
57
- value: unknown
57
+ value: unknown,
58
58
  ): Promise<void> => {
59
59
  if (!mutableStore.has(namespace)) {
60
60
  mutableStore.set(namespace, new Map());
61
61
  }
62
62
  mutableStore.get(namespace)!.set(key, value);
63
- }
64
- ),
65
- delete: jest.fn(
66
- async (namespace: string, key: string): Promise<void> => {
67
- const ns = mutableStore.get(namespace);
68
- if (ns) ns.delete(key);
69
- }
63
+ },
70
64
  ),
65
+ delete: jest.fn(async (namespace: string, key: string): Promise<void> => {
66
+ const ns = mutableStore.get(namespace);
67
+ if (ns) ns.delete(key);
68
+ }),
71
69
  },
72
70
  users: {
73
71
  get: jest.fn(
74
72
  async (
75
- userId: string
73
+ userId: string,
76
74
  ): Promise<{
77
75
  userId: string;
78
76
  data: Record<string, unknown>;
79
77
  } | null> => {
80
78
  return usersStore.get(userId) ?? null;
81
- }
79
+ },
82
80
  ),
83
81
  update: jest.fn(
84
82
  async (
85
83
  userId: string,
86
- data: Record<string, unknown>
84
+ data: Record<string, unknown>,
87
85
  ): Promise<{ userId: string; data: Record<string, unknown> }> => {
88
86
  const existing = usersStore.get(userId);
89
87
  const user = {
@@ -92,7 +90,7 @@ export function createMockCortex() {
92
90
  };
93
91
  usersStore.set(userId, user);
94
92
  return user;
95
- }
93
+ },
96
94
  ),
97
95
  delete: jest.fn(async (userId: string): Promise<void> => {
98
96
  usersStore.delete(userId);
@@ -115,17 +113,14 @@ export function createMockCortex() {
115
113
  ) {
116
114
  return false;
117
115
  }
118
- if (
119
- params.userId &&
120
- conv.participants.userId !== params.userId
121
- ) {
116
+ if (params.userId && conv.participants.userId !== params.userId) {
122
117
  return false;
123
118
  }
124
119
  return true;
125
- }
120
+ },
126
121
  );
127
122
  return { conversations, hasMore: false };
128
- }
123
+ },
129
124
  ),
130
125
  create: jest.fn(
131
126
  async (params: {
@@ -148,31 +143,36 @@ export function createMockCortex() {
148
143
  };
149
144
  conversationsStore.set(params.conversationId, conversation);
150
145
  return conversation;
151
- }
146
+ },
147
+ ),
148
+ get: jest.fn(
149
+ async (
150
+ conversationId: string,
151
+ options?: { includeMessages?: boolean; messageLimit?: number },
152
+ ) => {
153
+ const conv = conversationsStore.get(conversationId);
154
+ if (!conv) return null;
155
+
156
+ // If includeMessages is requested, return with messages
157
+ if (options?.includeMessages) {
158
+ return {
159
+ ...conv,
160
+ messages: conv.messages || [],
161
+ };
162
+ }
163
+
164
+ // Otherwise return without messages
165
+ const { messages: _messages, ...convWithoutMessages } = conv;
166
+ return convWithoutMessages;
167
+ },
152
168
  ),
153
- get: jest.fn(async (conversationId: string, options?: { includeMessages?: boolean; messageLimit?: number }) => {
154
- const conv = conversationsStore.get(conversationId);
155
- if (!conv) return null;
156
-
157
- // If includeMessages is requested, return with messages
158
- if (options?.includeMessages) {
159
- return {
160
- ...conv,
161
- messages: conv.messages || [],
162
- };
163
- }
164
-
165
- // Otherwise return without messages
166
- const { messages: _messages, ...convWithoutMessages } = conv;
167
- return convWithoutMessages;
168
- }),
169
169
  delete: jest.fn(async (conversationId: string): Promise<void> => {
170
170
  conversationsStore.delete(conversationId);
171
171
  }),
172
172
  update: jest.fn(
173
173
  async (
174
174
  conversationId: string,
175
- updates: { metadata?: Record<string, unknown> }
175
+ updates: { metadata?: Record<string, unknown> },
176
176
  ) => {
177
177
  const conv = conversationsStore.get(conversationId);
178
178
  if (!conv) throw new Error("Conversation not found");
@@ -183,7 +183,7 @@ export function createMockCortex() {
183
183
  };
184
184
  conversationsStore.set(conversationId, updated);
185
185
  return updated;
186
- }
186
+ },
187
187
  ),
188
188
  },
189
189
  memory: {
@@ -215,7 +215,7 @@ export type MockCortex = ReturnType<typeof createMockCortex>;
215
215
  export const seedTestData = {
216
216
  user: (
217
217
  userId: string,
218
- data: Record<string, unknown> = {}
218
+ data: Record<string, unknown> = {},
219
219
  ): { userId: string; data: Record<string, unknown> } => {
220
220
  const user = { userId, data };
221
221
  usersStore.set(userId, user);
@@ -234,7 +234,7 @@ export const seedTestData = {
234
234
  userId?: string;
235
235
  title?: string;
236
236
  messages?: Array<{ role: string; content: string }>;
237
- } = {}
237
+ } = {},
238
238
  ) => {
239
239
  const now = Date.now();
240
240
  const messages = params.messages?.map((msg, i) => ({
@@ -31,7 +31,7 @@ import { POST as loginPost } from "../../app/api/auth/login/route";
31
31
  function createRequest(
32
32
  method: string,
33
33
  body?: Record<string, unknown>,
34
- url: string = "http://localhost:3000"
34
+ url: string = "http://localhost:3000",
35
35
  ): Request {
36
36
  const init: RequestInit = { method };
37
37
  if (body) {
@@ -76,7 +76,7 @@ describe("Auth API Routes", () => {
76
76
  seedTestData.mutable(
77
77
  "quickstart-config",
78
78
  "admin_password_hash",
79
- "somehash:value"
79
+ "somehash:value",
80
80
  );
81
81
 
82
82
  const response = await checkGet();
@@ -91,7 +91,7 @@ describe("Auth API Routes", () => {
91
91
 
92
92
  expect(mockCortex.mutable.get).toHaveBeenCalledWith(
93
93
  "quickstart-config",
94
- "admin_password_hash"
94
+ "admin_password_hash",
95
95
  );
96
96
  });
97
97
  });
@@ -133,7 +133,7 @@ describe("Auth API Routes", () => {
133
133
  seedTestData.mutable(
134
134
  "quickstart-config",
135
135
  "admin_password_hash",
136
- "existing:hash"
136
+ "existing:hash",
137
137
  );
138
138
 
139
139
  const request = createRequest("POST", { password: "newpassword" });
@@ -157,7 +157,7 @@ describe("Auth API Routes", () => {
157
157
  expect(mockCortex.mutable.set).toHaveBeenCalledWith(
158
158
  "quickstart-config",
159
159
  "admin_password_hash",
160
- expect.stringContaining(":") // salt:hash format
160
+ expect.stringContaining(":"), // salt:hash format
161
161
  );
162
162
  });
163
163
  });
@@ -262,7 +262,7 @@ describe("Auth API Routes", () => {
262
262
  passwordHash: expect.stringContaining(":"),
263
263
  createdAt: expect.any(Number),
264
264
  lastLoginAt: expect.any(Number),
265
- })
265
+ }),
266
266
  );
267
267
  });
268
268
 
@@ -288,7 +288,7 @@ describe("Auth API Routes", () => {
288
288
 
289
289
  expect(status).toBe(200);
290
290
  expect((data.user as { displayName: string }).displayName).toBe(
291
- "testuser"
291
+ "testuser",
292
292
  );
293
293
  });
294
294
 
@@ -448,7 +448,7 @@ describe("Auth API Routes", () => {
448
448
 
449
449
  expect(status).toBe(200);
450
450
  expect((data.user as { displayName: string }).displayName).toBe(
451
- "testuser"
451
+ "testuser",
452
452
  );
453
453
  });
454
454
  });
@@ -33,7 +33,7 @@ function createRequest(
33
33
  options: {
34
34
  body?: Record<string, unknown>;
35
35
  searchParams?: Record<string, string>;
36
- } = {}
36
+ } = {},
37
37
  ): Request {
38
38
  const url = new URL("http://localhost:3000/api/conversations");
39
39
 
@@ -102,8 +102,12 @@ describe("Conversations API Routes", () => {
102
102
 
103
103
  expect(status).toBe(200);
104
104
  expect(data.conversation).toBeDefined();
105
- expect((data.conversation as { id: string }).id).toBe("conv-with-messages");
106
- expect((data.conversation as { title: string }).title).toBe("Test Conversation");
105
+ expect((data.conversation as { id: string }).id).toBe(
106
+ "conv-with-messages",
107
+ );
108
+ expect((data.conversation as { title: string }).title).toBe(
109
+ "Test Conversation",
110
+ );
107
111
  expect(data.messages).toBeDefined();
108
112
  expect((data.messages as unknown[]).length).toBe(2);
109
113
  });
@@ -235,7 +239,7 @@ describe("Conversations API Routes", () => {
235
239
  expect.objectContaining({
236
240
  memorySpaceId: "quickstart-demo",
237
241
  userId: "testuser",
238
- })
242
+ }),
239
243
  );
240
244
  });
241
245
  });
@@ -304,7 +308,7 @@ describe("Conversations API Routes", () => {
304
308
  expect(mockCortex.conversations.create).toHaveBeenCalledWith(
305
309
  expect.objectContaining({
306
310
  memorySpaceId: "custom-space",
307
- })
311
+ }),
308
312
  );
309
313
  });
310
314
 
@@ -317,7 +321,7 @@ describe("Conversations API Routes", () => {
317
321
  expect(mockCortex.conversations.create).toHaveBeenCalledWith(
318
322
  expect.objectContaining({
319
323
  memorySpaceId: "quickstart-demo",
320
- })
324
+ }),
321
325
  );
322
326
  });
323
327
 
@@ -330,7 +334,7 @@ describe("Conversations API Routes", () => {
330
334
  expect(mockCortex.conversations.create).toHaveBeenCalledWith(
331
335
  expect.objectContaining({
332
336
  type: "user-agent",
333
- })
337
+ }),
334
338
  );
335
339
  });
336
340
 
@@ -346,7 +350,7 @@ describe("Conversations API Routes", () => {
346
350
  userId: "testuser",
347
351
  agentId: "quickstart-assistant",
348
352
  },
349
- })
353
+ }),
350
354
  );
351
355
  });
352
356
 
@@ -137,7 +137,10 @@ describe("Password Utilities", () => {
137
137
  });
138
138
 
139
139
  it("should return false for invalid base64 in salt", async () => {
140
- const result = await verifyPassword("password", "!!!invalid!!!:validhash");
140
+ const result = await verifyPassword(
141
+ "password",
142
+ "!!!invalid!!!:validhash",
143
+ );
141
144
 
142
145
  expect(result).toBe(false);
143
146
  });