@lovelybunch/api 1.0.67 → 1.0.69-alpha.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 (155) hide show
  1. package/dist/lib/jobs/job-scheduler.js +86 -0
  2. package/dist/lib/terminal/terminal-manager.js +45 -1
  3. package/dist/routes/api/v1/context/architecture/route.js +37 -0
  4. package/dist/routes/api/v1/context/knowledge/[filename]/route.js +69 -0
  5. package/dist/routes/api/v1/context/knowledge/route.js +39 -0
  6. package/dist/routes/api/v1/context/project/route.js +37 -0
  7. package/dist/routes/api/v1/git/index.js +143 -2
  8. package/dist/routes/api/v1/identity/agent-card-service.d.ts +11 -0
  9. package/dist/routes/api/v1/identity/agent-card-service.js +64 -0
  10. package/dist/routes/api/v1/identity/index.d.ts +2 -0
  11. package/dist/routes/api/v1/identity/index.js +2 -0
  12. package/dist/routes/api/v1/identity/route.d.ts +3 -0
  13. package/dist/routes/api/v1/identity/route.js +57 -0
  14. package/dist/routes/api/v1/resources/[id]/route.js +23 -0
  15. package/dist/routes/api/v1/resources/route.js +24 -0
  16. package/dist/server-with-static.js +5 -0
  17. package/dist/server.js +18 -0
  18. package/dist/test-setup.d.ts +1 -0
  19. package/dist/test-setup.js +38 -0
  20. package/package.json +12 -6
  21. package/static/assets/index-DIVD0EVP.css +33 -0
  22. package/static/assets/index-VVQqAzvr.js +894 -0
  23. package/static/index.html +2 -2
  24. package/dist/lib/gait-path.d.ts.map +0 -1
  25. package/dist/lib/gait-path.js.map +0 -1
  26. package/dist/lib/git.d.ts.map +0 -1
  27. package/dist/lib/git.js.map +0 -1
  28. package/dist/lib/project-paths.d.ts.map +0 -1
  29. package/dist/lib/project-paths.js.map +0 -1
  30. package/dist/lib/storage/file-storage.d.ts.map +0 -1
  31. package/dist/lib/storage/file-storage.js.map +0 -1
  32. package/dist/lib/symlinks/symlink-manager.d.ts.map +0 -1
  33. package/dist/lib/symlinks/symlink-manager.js.map +0 -1
  34. package/dist/lib/symlinks/types.d.ts.map +0 -1
  35. package/dist/lib/symlinks/types.js.map +0 -1
  36. package/dist/lib/terminal/context-helper.d.ts.map +0 -1
  37. package/dist/lib/terminal/context-helper.js.map +0 -1
  38. package/dist/lib/terminal/global-manager.d.ts.map +0 -1
  39. package/dist/lib/terminal/global-manager.js.map +0 -1
  40. package/dist/lib/terminal/shell-utils.d.ts.map +0 -1
  41. package/dist/lib/terminal/shell-utils.js.map +0 -1
  42. package/dist/lib/terminal/terminal-manager.d.ts.map +0 -1
  43. package/dist/lib/terminal/terminal-manager.js.map +0 -1
  44. package/dist/lib/user-preferences.d.ts.map +0 -1
  45. package/dist/lib/user-preferences.js.map +0 -1
  46. package/dist/routes/api/v1/agents/[id]/index.d.ts.map +0 -1
  47. package/dist/routes/api/v1/agents/[id]/index.js.map +0 -1
  48. package/dist/routes/api/v1/agents/[id]/route.d.ts.map +0 -1
  49. package/dist/routes/api/v1/agents/[id]/route.js.map +0 -1
  50. package/dist/routes/api/v1/agents/index.d.ts.map +0 -1
  51. package/dist/routes/api/v1/agents/index.js.map +0 -1
  52. package/dist/routes/api/v1/agents/route.d.ts.map +0 -1
  53. package/dist/routes/api/v1/agents/route.js.map +0 -1
  54. package/dist/routes/api/v1/ai/index.d.ts.map +0 -1
  55. package/dist/routes/api/v1/ai/index.js.map +0 -1
  56. package/dist/routes/api/v1/ai/route.d.ts.map +0 -1
  57. package/dist/routes/api/v1/ai/route.js.map +0 -1
  58. package/dist/routes/api/v1/chats/[id]/index.d.ts.map +0 -1
  59. package/dist/routes/api/v1/chats/[id]/index.js.map +0 -1
  60. package/dist/routes/api/v1/chats/[id]/route.d.ts.map +0 -1
  61. package/dist/routes/api/v1/chats/[id]/route.js.map +0 -1
  62. package/dist/routes/api/v1/chats/index.d.ts.map +0 -1
  63. package/dist/routes/api/v1/chats/index.js.map +0 -1
  64. package/dist/routes/api/v1/chats/route.d.ts.map +0 -1
  65. package/dist/routes/api/v1/chats/route.js.map +0 -1
  66. package/dist/routes/api/v1/config/index.d.ts.map +0 -1
  67. package/dist/routes/api/v1/config/index.js.map +0 -1
  68. package/dist/routes/api/v1/config/route.d.ts.map +0 -1
  69. package/dist/routes/api/v1/config/route.js.map +0 -1
  70. package/dist/routes/api/v1/context/architecture/route.d.ts.map +0 -1
  71. package/dist/routes/api/v1/context/architecture/route.js.map +0 -1
  72. package/dist/routes/api/v1/context/index.d.ts.map +0 -1
  73. package/dist/routes/api/v1/context/index.js.map +0 -1
  74. package/dist/routes/api/v1/context/knowledge/[filename]/index.d.ts.map +0 -1
  75. package/dist/routes/api/v1/context/knowledge/[filename]/index.js.map +0 -1
  76. package/dist/routes/api/v1/context/knowledge/[filename]/route.d.ts.map +0 -1
  77. package/dist/routes/api/v1/context/knowledge/[filename]/route.js.map +0 -1
  78. package/dist/routes/api/v1/context/knowledge/index.d.ts.map +0 -1
  79. package/dist/routes/api/v1/context/knowledge/index.js.map +0 -1
  80. package/dist/routes/api/v1/context/knowledge/route.d.ts.map +0 -1
  81. package/dist/routes/api/v1/context/knowledge/route.js.map +0 -1
  82. package/dist/routes/api/v1/context/project/route.d.ts.map +0 -1
  83. package/dist/routes/api/v1/context/project/route.js.map +0 -1
  84. package/dist/routes/api/v1/events/events.test.d.ts +0 -4
  85. package/dist/routes/api/v1/events/events.test.js +0 -289
  86. package/dist/routes/api/v1/git/index.d.ts.map +0 -1
  87. package/dist/routes/api/v1/git/index.js.map +0 -1
  88. package/dist/routes/api/v1/init/index.d.ts +0 -1
  89. package/dist/routes/api/v1/init/index.js +0 -1
  90. package/dist/routes/api/v1/init/route.d.ts +0 -3
  91. package/dist/routes/api/v1/init/route.js +0 -129
  92. package/dist/routes/api/v1/mcp/index.d.ts.map +0 -1
  93. package/dist/routes/api/v1/mcp/index.js.map +0 -1
  94. package/dist/routes/api/v1/mcp/route.d.ts.map +0 -1
  95. package/dist/routes/api/v1/mcp/route.js.map +0 -1
  96. package/dist/routes/api/v1/onboard/index.d.ts +0 -3
  97. package/dist/routes/api/v1/onboard/index.js +0 -8
  98. package/dist/routes/api/v1/onboard/route.d.ts +0 -13
  99. package/dist/routes/api/v1/onboard/route.js +0 -311
  100. package/dist/routes/api/v1/onboarding/check/index.d.ts +0 -3
  101. package/dist/routes/api/v1/onboarding/check/index.js +0 -5
  102. package/dist/routes/api/v1/onboarding/check/route.d.ts +0 -12
  103. package/dist/routes/api/v1/onboarding/check/route.js +0 -24
  104. package/dist/routes/api/v1/onboarding/index.d.ts +0 -1
  105. package/dist/routes/api/v1/onboarding/index.js +0 -1
  106. package/dist/routes/api/v1/onboarding/route.d.ts +0 -3
  107. package/dist/routes/api/v1/onboarding/route.js +0 -158
  108. package/dist/routes/api/v1/proposals/[id]/route.d.ts.map +0 -1
  109. package/dist/routes/api/v1/proposals/[id]/route.js.map +0 -1
  110. package/dist/routes/api/v1/proposals/index.d.ts.map +0 -1
  111. package/dist/routes/api/v1/proposals/index.js.map +0 -1
  112. package/dist/routes/api/v1/proposals/route.d.ts.map +0 -1
  113. package/dist/routes/api/v1/proposals/route.js.map +0 -1
  114. package/dist/routes/api/v1/resources/[id]/index.d.ts.map +0 -1
  115. package/dist/routes/api/v1/resources/[id]/index.js.map +0 -1
  116. package/dist/routes/api/v1/resources/[id]/route.js.map +0 -1
  117. package/dist/routes/api/v1/resources/[id]/thumbnail/index.d.ts.map +0 -1
  118. package/dist/routes/api/v1/resources/[id]/thumbnail/index.js.map +0 -1
  119. package/dist/routes/api/v1/resources/[id]/thumbnail/route.js.map +0 -1
  120. package/dist/routes/api/v1/resources/index.d.ts.map +0 -1
  121. package/dist/routes/api/v1/resources/index.js.map +0 -1
  122. package/dist/routes/api/v1/resources/route.d.ts.map +0 -1
  123. package/dist/routes/api/v1/resources/route.js.map +0 -1
  124. package/dist/routes/api/v1/symlinks/index.d.ts.map +0 -1
  125. package/dist/routes/api/v1/symlinks/index.js.map +0 -1
  126. package/dist/routes/api/v1/symlinks/route.d.ts.map +0 -1
  127. package/dist/routes/api/v1/symlinks/route.js.map +0 -1
  128. package/dist/routes/api/v1/terminal/[proposalId]/create/index.d.ts.map +0 -1
  129. package/dist/routes/api/v1/terminal/[proposalId]/create/index.js.map +0 -1
  130. package/dist/routes/api/v1/terminal/[proposalId]/create/route.d.ts.map +0 -1
  131. package/dist/routes/api/v1/terminal/[proposalId]/create/route.js.map +0 -1
  132. package/dist/routes/api/v1/terminal/[proposalId]/destroy/index.d.ts.map +0 -1
  133. package/dist/routes/api/v1/terminal/[proposalId]/destroy/index.js.map +0 -1
  134. package/dist/routes/api/v1/terminal/[proposalId]/destroy/route.d.ts.map +0 -1
  135. package/dist/routes/api/v1/terminal/[proposalId]/destroy/route.js.map +0 -1
  136. package/dist/routes/api/v1/terminal/[proposalId]/resize/index.d.ts.map +0 -1
  137. package/dist/routes/api/v1/terminal/[proposalId]/resize/index.js.map +0 -1
  138. package/dist/routes/api/v1/terminal/[proposalId]/resize/route.d.ts.map +0 -1
  139. package/dist/routes/api/v1/terminal/[proposalId]/resize/route.js.map +0 -1
  140. package/dist/routes/api/v1/terminal/sessions/index.d.ts.map +0 -1
  141. package/dist/routes/api/v1/terminal/sessions/index.js.map +0 -1
  142. package/dist/routes/api/v1/terminal/sessions/route.d.ts.map +0 -1
  143. package/dist/routes/api/v1/terminal/sessions/route.js.map +0 -1
  144. package/dist/routes/api/v1/user/index.d.ts.map +0 -1
  145. package/dist/routes/api/v1/user/index.js.map +0 -1
  146. package/dist/routes/api/v1/user/settings/index.d.ts.map +0 -1
  147. package/dist/routes/api/v1/user/settings/index.js.map +0 -1
  148. package/dist/routes/api/v1/user/settings/route.d.ts.map +0 -1
  149. package/dist/routes/api/v1/user/settings/route.js.map +0 -1
  150. package/dist/server-with-static.d.ts.map +0 -1
  151. package/dist/server-with-static.js.map +0 -1
  152. package/dist/server.d.ts.map +0 -1
  153. package/dist/server.js.map +0 -1
  154. package/static/assets/index-ChgXTZpc.css +0 -33
  155. package/static/assets/index-aLGL6jN0.js +0 -869
@@ -0,0 +1,64 @@
1
+ import { promises as fs } from 'fs';
2
+ import path from 'path';
3
+ import { findGaitDirectory } from '../../../../lib/gait-path.js';
4
+ export const AGENT_CARD_FILENAME = 'agent-card.json';
5
+ export const PUBLIC_AGENT_CARD_PATH = `/.well-known/${AGENT_CARD_FILENAME}`;
6
+ async function resolveAgentCardPath(options = {}) {
7
+ const nutDir = await findGaitDirectory();
8
+ if (!nutDir) {
9
+ throw new Error('GAIT directory not found');
10
+ }
11
+ if (options.ensureDirectory) {
12
+ await fs.mkdir(nutDir, { recursive: true });
13
+ }
14
+ return {
15
+ storageDir: nutDir,
16
+ cardPath: path.join(nutDir, AGENT_CARD_FILENAME),
17
+ };
18
+ }
19
+ export async function readAgentCard() {
20
+ const { cardPath } = await resolveAgentCardPath();
21
+ try {
22
+ const fileContent = await fs.readFile(cardPath, 'utf-8');
23
+ const card = JSON.parse(fileContent);
24
+ const stats = await fs.stat(cardPath);
25
+ return {
26
+ exists: true,
27
+ card,
28
+ publicPath: PUBLIC_AGENT_CARD_PATH,
29
+ storagePath: cardPath,
30
+ updatedAt: stats.mtime.toISOString(),
31
+ };
32
+ }
33
+ catch (error) {
34
+ if (error.code === 'ENOENT') {
35
+ return {
36
+ exists: false,
37
+ card: null,
38
+ publicPath: PUBLIC_AGENT_CARD_PATH,
39
+ storagePath: cardPath,
40
+ };
41
+ }
42
+ if (error instanceof SyntaxError) {
43
+ throw new Error('Agent card JSON is invalid');
44
+ }
45
+ throw error;
46
+ }
47
+ }
48
+ export async function writeAgentCard(card) {
49
+ if (typeof card !== 'object' || card === null) {
50
+ throw new Error('Agent card payload must be an object');
51
+ }
52
+ const { storageDir, cardPath } = await resolveAgentCardPath({ ensureDirectory: true });
53
+ await fs.mkdir(storageDir, { recursive: true });
54
+ const payload = JSON.stringify(card, null, 2);
55
+ await fs.writeFile(cardPath, `${payload}\n`);
56
+ const stats = await fs.stat(cardPath);
57
+ return {
58
+ exists: true,
59
+ card,
60
+ publicPath: PUBLIC_AGENT_CARD_PATH,
61
+ storagePath: cardPath,
62
+ updatedAt: stats.mtime.toISOString(),
63
+ };
64
+ }
@@ -0,0 +1,2 @@
1
+ export { default } from './route.js';
2
+ export { readAgentCard, writeAgentCard, PUBLIC_AGENT_CARD_PATH } from './agent-card-service.js';
@@ -0,0 +1,2 @@
1
+ export { default } from './route.js';
2
+ export { readAgentCard, writeAgentCard, PUBLIC_AGENT_CARD_PATH } from './agent-card-service.js';
@@ -0,0 +1,3 @@
1
+ import { Hono } from 'hono';
2
+ declare const identity: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
3
+ export default identity;
@@ -0,0 +1,57 @@
1
+ import { Hono } from 'hono';
2
+ import { requireAuth } from '../../../../middleware/auth.js';
3
+ import { readAgentCard, writeAgentCard } from './agent-card-service.js';
4
+ const identity = new Hono();
5
+ identity.get('/agent-card', async (c) => {
6
+ try {
7
+ requireAuth(c);
8
+ const document = await readAgentCard();
9
+ return c.json({
10
+ success: true,
11
+ data: document,
12
+ });
13
+ }
14
+ catch (error) {
15
+ console.error('Failed to load agent card:', error);
16
+ if (error.message === 'Authentication required') {
17
+ return c.json({ success: false, error: error.message }, 401);
18
+ }
19
+ if (error.message === 'GAIT directory not found') {
20
+ return c.json({ success: false, error: error.message }, 404);
21
+ }
22
+ if (error.message === 'Agent card JSON is invalid') {
23
+ return c.json({ success: false, error: error.message }, 500);
24
+ }
25
+ return c.json({ success: false, error: 'Failed to load agent card' }, 500);
26
+ }
27
+ });
28
+ identity.put('/agent-card', async (c) => {
29
+ try {
30
+ requireAuth(c);
31
+ const body = await c.req.json();
32
+ const { card } = body || {};
33
+ if (!card || typeof card !== 'object') {
34
+ return c.json({ success: false, error: 'Missing or invalid agent card payload' }, 400);
35
+ }
36
+ const document = await writeAgentCard(card);
37
+ return c.json({
38
+ success: true,
39
+ data: document,
40
+ message: 'Agent card saved successfully',
41
+ });
42
+ }
43
+ catch (error) {
44
+ console.error('Failed to save agent card:', error);
45
+ if (error.message === 'Authentication required') {
46
+ return c.json({ success: false, error: error.message }, 401);
47
+ }
48
+ if (error.message === 'Agent card payload must be an object') {
49
+ return c.json({ success: false, error: error.message }, 400);
50
+ }
51
+ if (error.message === 'GAIT directory not found') {
52
+ return c.json({ success: false, error: error.message }, 404);
53
+ }
54
+ return c.json({ success: false, error: 'Failed to save agent card' }, 500);
55
+ }
56
+ });
57
+ export default identity;
@@ -1,5 +1,7 @@
1
1
  import { promises as fs } from 'fs';
2
2
  import path from 'path';
3
+ import { getLogger, ResourceKinds } from '@lovelybunch/core/logging';
4
+ import { requireAuth } from '../../../../../middleware/auth.js';
3
5
  function getResourcesPath() {
4
6
  let basePath;
5
7
  if (process.env.NODE_ENV === 'development' && process.env.GAIT_DEV_ROOT) {
@@ -141,6 +143,27 @@ export async function DELETE(c) {
141
143
  // Delete metadata
142
144
  const metadataPath = path.join(METADATA_DIR, `${resource.id}.json`);
143
145
  await fs.unlink(metadataPath);
146
+ // Log resource deletion event
147
+ try {
148
+ const session = await requireAuth(c);
149
+ const actor = session ? `human:${session.email}` : "human:unknown";
150
+ const logger = getLogger();
151
+ logger.log({
152
+ kind: ResourceKinds.DELETE,
153
+ actor,
154
+ subject: `resource:${id}`,
155
+ tags: ["resource"],
156
+ payload: {
157
+ id,
158
+ name: resource.name,
159
+ type: resource.type,
160
+ size: resource.size,
161
+ }
162
+ });
163
+ }
164
+ catch (logError) {
165
+ console.error('Error logging resource deletion:', logError);
166
+ }
144
167
  return c.json({
145
168
  success: true,
146
169
  message: 'Resource deleted successfully'
@@ -1,5 +1,7 @@
1
1
  import { promises as fs } from 'fs';
2
2
  import path from 'path';
3
+ import { getLogger, ResourceKinds } from '@lovelybunch/core/logging';
4
+ import { requireAuth } from '../../../../middleware/auth.js';
3
5
  // Generate a random ID
4
6
  function generateId() {
5
7
  return `res-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
@@ -145,6 +147,28 @@ export async function POST(c) {
145
147
  }
146
148
  }
147
149
  await saveResourceMetadata(resource);
150
+ // Log resource upload event
151
+ try {
152
+ const session = await requireAuth(c);
153
+ const actor = session ? `human:${session.email}` : "human:unknown";
154
+ const logger = getLogger();
155
+ logger.log({
156
+ kind: ResourceKinds.UPLOAD,
157
+ actor,
158
+ subject: `resource:${id}`,
159
+ tags: ["resource", ...(resource.metadata.tags || [])],
160
+ payload: {
161
+ id,
162
+ name: resource.name,
163
+ type: resource.type,
164
+ size: resource.size,
165
+ summary: resource.metadata.description || `Uploaded ${resource.type} file: ${resource.name}`,
166
+ }
167
+ });
168
+ }
169
+ catch (logError) {
170
+ console.error('Error logging resource upload:', logError);
171
+ }
148
172
  return c.json({
149
173
  success: true,
150
174
  data: resource
@@ -196,7 +196,9 @@ app.get('/api/health', (c) => {
196
196
  });
197
197
  // Serve static files from the frontend build
198
198
  // This will look for the frontend build in multiple possible locations
199
+ const envStaticPath = process.env.COCONUT_STATIC_DIR || process.env.COCONUT_STATIC_PATH;
199
200
  const possibleStaticPaths = [
201
+ ...(envStaticPath ? [path.resolve(envStaticPath)] : []),
200
202
  // When installed via npm globally
201
203
  path.join(__dirname, '../../frontend/dist'),
202
204
  // When running from development
@@ -247,6 +249,9 @@ if (staticPath) {
247
249
  });
248
250
  }
249
251
  else {
252
+ if (envStaticPath) {
253
+ console.warn(`⚠️ Env static path not found: ${path.resolve(envStaticPath)}`);
254
+ }
250
255
  console.warn('⚠️ No static files found. Frontend may not work properly.');
251
256
  console.warn(' Run "pnpm run build:bundle" in the api package to bundle frontend files.');
252
257
  }
package/dist/server.js CHANGED
@@ -157,6 +157,7 @@ import config from './routes/api/v1/config/index.js';
157
157
  import user from './routes/api/v1/user/index.js';
158
158
  import agents from './routes/api/v1/agents/index.js';
159
159
  import agentsById from './routes/api/v1/agents/[id]/index.js';
160
+ import identity, { readAgentCard, PUBLIC_AGENT_CARD_PATH } from './routes/api/v1/identity/index.js';
160
161
  import git from './routes/api/v1/git/index.js';
161
162
  import mcp from './routes/api/v1/mcp/index.js';
162
163
  import symlinks from './routes/api/v1/symlinks/index.js';
@@ -182,11 +183,28 @@ app.route('/api/v1/config', config);
182
183
  app.route('/api/v1/user', user);
183
184
  app.route('/api/v1/agents', agents);
184
185
  app.route('/api/v1/agents/:id', agentsById);
186
+ app.route('/api/v1/identity', identity);
185
187
  app.route('/api/v1/git', git);
186
188
  app.route('/api/v1/mcp', mcp);
187
189
  app.route('/api/v1/symlinks', symlinks);
188
190
  app.route('/api/v1/jobs', jobs);
189
191
  app.route('/api/v1/events', events);
192
+ app.get(PUBLIC_AGENT_CARD_PATH, authMiddleware, async (c) => {
193
+ try {
194
+ const document = await readAgentCard();
195
+ if (!document.exists || !document.card) {
196
+ return c.json({ error: 'Agent card not found' }, 404);
197
+ }
198
+ return c.json(document.card);
199
+ }
200
+ catch (error) {
201
+ if (error.message === 'GAIT directory not found') {
202
+ return c.json({ error: error.message }, 404);
203
+ }
204
+ console.error('Failed to serve agent card:', error);
205
+ return c.json({ error: 'Failed to load agent card' }, 500);
206
+ }
207
+ });
190
208
  // Health check endpoint
191
209
  app.get('/health', (c) => {
192
210
  return c.json({ status: 'ok', timestamp: new Date().toISOString() });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,38 @@
1
+ import { beforeAll, afterAll, beforeEach, afterEach, vi } from 'vitest';
2
+ import { mkdtempSync, rmSync } from 'fs';
3
+ import { tmpdir } from 'os';
4
+ import { join } from 'path';
5
+ // Temporary test data directory
6
+ let testDataDir;
7
+ beforeAll(() => {
8
+ // Create a temporary directory for test data
9
+ testDataDir = mkdtempSync(join(tmpdir(), 'coconut-test-'));
10
+ // Set test environment variables
11
+ process.env.NODE_ENV = 'test';
12
+ process.env.GAIT_DATA_PATH = testDataDir;
13
+ // Mock console methods to reduce noise in test output
14
+ vi.spyOn(console, 'log').mockImplementation(() => { });
15
+ vi.spyOn(console, 'info').mockImplementation(() => { });
16
+ vi.spyOn(console, 'warn').mockImplementation(() => { });
17
+ // Keep console.error for debugging test failures
18
+ });
19
+ afterAll(() => {
20
+ // Clean up temporary test directory
21
+ if (testDataDir) {
22
+ try {
23
+ rmSync(testDataDir, { recursive: true, force: true });
24
+ }
25
+ catch (error) {
26
+ console.error('Failed to clean up test directory:', error);
27
+ }
28
+ }
29
+ // Restore console methods
30
+ vi.restoreAllMocks();
31
+ });
32
+ beforeEach(() => {
33
+ // Clear all mocks before each test
34
+ vi.clearAllMocks();
35
+ });
36
+ afterEach(() => {
37
+ // Additional cleanup after each test if needed
38
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovelybunch/api",
3
- "version": "1.0.67",
3
+ "version": "1.0.69-alpha.0",
4
4
  "type": "module",
5
5
  "main": "dist/server-with-static.js",
6
6
  "exports": {
@@ -17,7 +17,11 @@
17
17
  "build:bundle": "tsc && node scripts/bundle-frontend.js",
18
18
  "start": "node dist/server-with-static.js",
19
19
  "start:dev": "node dist/server.js",
20
- "test": "echo \"Error: no test specified\" && exit 1"
20
+ "clean": "rm -rf dist static tsconfig.tsbuildinfo coverage",
21
+ "test": "vitest run",
22
+ "test:coverage": "vitest run --coverage",
23
+ "test:watch": "vitest watch",
24
+ "test:ui": "vitest --ui"
21
25
  },
22
26
  "keywords": [
23
27
  "api",
@@ -32,9 +36,9 @@
32
36
  "dependencies": {
33
37
  "@hono/node-server": "^1.13.7",
34
38
  "@hono/node-ws": "^1.0.6",
35
- "@lovelybunch/core": "^1.0.67",
36
- "@lovelybunch/mcp": "^1.0.67",
37
- "@lovelybunch/types": "^1.0.67",
39
+ "@lovelybunch/core": "^1.0.69-alpha.0",
40
+ "@lovelybunch/mcp": "^1.0.69-alpha.0",
41
+ "@lovelybunch/types": "^1.0.69-alpha.0",
38
42
  "arctic": "^1.9.2",
39
43
  "bcrypt": "^5.1.1",
40
44
  "cookie": "^0.6.0",
@@ -52,7 +56,9 @@
52
56
  "@types/jsonwebtoken": "^9.0.5",
53
57
  "@types/node": "^22.10.2",
54
58
  "@types/ws": "^8.5.13",
59
+ "@vitest/coverage-v8": "^1.6.1",
55
60
  "tsx": "^4.19.2",
56
- "typescript": "^5.7.2"
61
+ "typescript": "^5.7.2",
62
+ "vitest": "^4.0.5"
57
63
  }
58
64
  }