@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.
- package/dist/lib/jobs/job-scheduler.js +86 -0
- package/dist/lib/terminal/terminal-manager.js +45 -1
- package/dist/routes/api/v1/context/architecture/route.js +37 -0
- package/dist/routes/api/v1/context/knowledge/[filename]/route.js +69 -0
- package/dist/routes/api/v1/context/knowledge/route.js +39 -0
- package/dist/routes/api/v1/context/project/route.js +37 -0
- package/dist/routes/api/v1/git/index.js +143 -2
- package/dist/routes/api/v1/identity/agent-card-service.d.ts +11 -0
- package/dist/routes/api/v1/identity/agent-card-service.js +64 -0
- package/dist/routes/api/v1/identity/index.d.ts +2 -0
- package/dist/routes/api/v1/identity/index.js +2 -0
- package/dist/routes/api/v1/identity/route.d.ts +3 -0
- package/dist/routes/api/v1/identity/route.js +57 -0
- package/dist/routes/api/v1/resources/[id]/route.js +23 -0
- package/dist/routes/api/v1/resources/route.js +24 -0
- package/dist/server-with-static.js +5 -0
- package/dist/server.js +18 -0
- package/dist/test-setup.d.ts +1 -0
- package/dist/test-setup.js +38 -0
- package/package.json +12 -6
- package/static/assets/index-DIVD0EVP.css +33 -0
- package/static/assets/index-VVQqAzvr.js +894 -0
- package/static/index.html +2 -2
- package/dist/lib/gait-path.d.ts.map +0 -1
- package/dist/lib/gait-path.js.map +0 -1
- package/dist/lib/git.d.ts.map +0 -1
- package/dist/lib/git.js.map +0 -1
- package/dist/lib/project-paths.d.ts.map +0 -1
- package/dist/lib/project-paths.js.map +0 -1
- package/dist/lib/storage/file-storage.d.ts.map +0 -1
- package/dist/lib/storage/file-storage.js.map +0 -1
- package/dist/lib/symlinks/symlink-manager.d.ts.map +0 -1
- package/dist/lib/symlinks/symlink-manager.js.map +0 -1
- package/dist/lib/symlinks/types.d.ts.map +0 -1
- package/dist/lib/symlinks/types.js.map +0 -1
- package/dist/lib/terminal/context-helper.d.ts.map +0 -1
- package/dist/lib/terminal/context-helper.js.map +0 -1
- package/dist/lib/terminal/global-manager.d.ts.map +0 -1
- package/dist/lib/terminal/global-manager.js.map +0 -1
- package/dist/lib/terminal/shell-utils.d.ts.map +0 -1
- package/dist/lib/terminal/shell-utils.js.map +0 -1
- package/dist/lib/terminal/terminal-manager.d.ts.map +0 -1
- package/dist/lib/terminal/terminal-manager.js.map +0 -1
- package/dist/lib/user-preferences.d.ts.map +0 -1
- package/dist/lib/user-preferences.js.map +0 -1
- package/dist/routes/api/v1/agents/[id]/index.d.ts.map +0 -1
- package/dist/routes/api/v1/agents/[id]/index.js.map +0 -1
- package/dist/routes/api/v1/agents/[id]/route.d.ts.map +0 -1
- package/dist/routes/api/v1/agents/[id]/route.js.map +0 -1
- package/dist/routes/api/v1/agents/index.d.ts.map +0 -1
- package/dist/routes/api/v1/agents/index.js.map +0 -1
- package/dist/routes/api/v1/agents/route.d.ts.map +0 -1
- package/dist/routes/api/v1/agents/route.js.map +0 -1
- package/dist/routes/api/v1/ai/index.d.ts.map +0 -1
- package/dist/routes/api/v1/ai/index.js.map +0 -1
- package/dist/routes/api/v1/ai/route.d.ts.map +0 -1
- package/dist/routes/api/v1/ai/route.js.map +0 -1
- package/dist/routes/api/v1/chats/[id]/index.d.ts.map +0 -1
- package/dist/routes/api/v1/chats/[id]/index.js.map +0 -1
- package/dist/routes/api/v1/chats/[id]/route.d.ts.map +0 -1
- package/dist/routes/api/v1/chats/[id]/route.js.map +0 -1
- package/dist/routes/api/v1/chats/index.d.ts.map +0 -1
- package/dist/routes/api/v1/chats/index.js.map +0 -1
- package/dist/routes/api/v1/chats/route.d.ts.map +0 -1
- package/dist/routes/api/v1/chats/route.js.map +0 -1
- package/dist/routes/api/v1/config/index.d.ts.map +0 -1
- package/dist/routes/api/v1/config/index.js.map +0 -1
- package/dist/routes/api/v1/config/route.d.ts.map +0 -1
- package/dist/routes/api/v1/config/route.js.map +0 -1
- package/dist/routes/api/v1/context/architecture/route.d.ts.map +0 -1
- package/dist/routes/api/v1/context/architecture/route.js.map +0 -1
- package/dist/routes/api/v1/context/index.d.ts.map +0 -1
- package/dist/routes/api/v1/context/index.js.map +0 -1
- package/dist/routes/api/v1/context/knowledge/[filename]/index.d.ts.map +0 -1
- package/dist/routes/api/v1/context/knowledge/[filename]/index.js.map +0 -1
- package/dist/routes/api/v1/context/knowledge/[filename]/route.d.ts.map +0 -1
- package/dist/routes/api/v1/context/knowledge/[filename]/route.js.map +0 -1
- package/dist/routes/api/v1/context/knowledge/index.d.ts.map +0 -1
- package/dist/routes/api/v1/context/knowledge/index.js.map +0 -1
- package/dist/routes/api/v1/context/knowledge/route.d.ts.map +0 -1
- package/dist/routes/api/v1/context/knowledge/route.js.map +0 -1
- package/dist/routes/api/v1/context/project/route.d.ts.map +0 -1
- package/dist/routes/api/v1/context/project/route.js.map +0 -1
- package/dist/routes/api/v1/events/events.test.d.ts +0 -4
- package/dist/routes/api/v1/events/events.test.js +0 -289
- package/dist/routes/api/v1/git/index.d.ts.map +0 -1
- package/dist/routes/api/v1/git/index.js.map +0 -1
- package/dist/routes/api/v1/init/index.d.ts +0 -1
- package/dist/routes/api/v1/init/index.js +0 -1
- package/dist/routes/api/v1/init/route.d.ts +0 -3
- package/dist/routes/api/v1/init/route.js +0 -129
- package/dist/routes/api/v1/mcp/index.d.ts.map +0 -1
- package/dist/routes/api/v1/mcp/index.js.map +0 -1
- package/dist/routes/api/v1/mcp/route.d.ts.map +0 -1
- package/dist/routes/api/v1/mcp/route.js.map +0 -1
- package/dist/routes/api/v1/onboard/index.d.ts +0 -3
- package/dist/routes/api/v1/onboard/index.js +0 -8
- package/dist/routes/api/v1/onboard/route.d.ts +0 -13
- package/dist/routes/api/v1/onboard/route.js +0 -311
- package/dist/routes/api/v1/onboarding/check/index.d.ts +0 -3
- package/dist/routes/api/v1/onboarding/check/index.js +0 -5
- package/dist/routes/api/v1/onboarding/check/route.d.ts +0 -12
- package/dist/routes/api/v1/onboarding/check/route.js +0 -24
- package/dist/routes/api/v1/onboarding/index.d.ts +0 -1
- package/dist/routes/api/v1/onboarding/index.js +0 -1
- package/dist/routes/api/v1/onboarding/route.d.ts +0 -3
- package/dist/routes/api/v1/onboarding/route.js +0 -158
- package/dist/routes/api/v1/proposals/[id]/route.d.ts.map +0 -1
- package/dist/routes/api/v1/proposals/[id]/route.js.map +0 -1
- package/dist/routes/api/v1/proposals/index.d.ts.map +0 -1
- package/dist/routes/api/v1/proposals/index.js.map +0 -1
- package/dist/routes/api/v1/proposals/route.d.ts.map +0 -1
- package/dist/routes/api/v1/proposals/route.js.map +0 -1
- package/dist/routes/api/v1/resources/[id]/index.d.ts.map +0 -1
- package/dist/routes/api/v1/resources/[id]/index.js.map +0 -1
- package/dist/routes/api/v1/resources/[id]/route.js.map +0 -1
- package/dist/routes/api/v1/resources/[id]/thumbnail/index.d.ts.map +0 -1
- package/dist/routes/api/v1/resources/[id]/thumbnail/index.js.map +0 -1
- package/dist/routes/api/v1/resources/[id]/thumbnail/route.js.map +0 -1
- package/dist/routes/api/v1/resources/index.d.ts.map +0 -1
- package/dist/routes/api/v1/resources/index.js.map +0 -1
- package/dist/routes/api/v1/resources/route.d.ts.map +0 -1
- package/dist/routes/api/v1/resources/route.js.map +0 -1
- package/dist/routes/api/v1/symlinks/index.d.ts.map +0 -1
- package/dist/routes/api/v1/symlinks/index.js.map +0 -1
- package/dist/routes/api/v1/symlinks/route.d.ts.map +0 -1
- package/dist/routes/api/v1/symlinks/route.js.map +0 -1
- package/dist/routes/api/v1/terminal/[proposalId]/create/index.d.ts.map +0 -1
- package/dist/routes/api/v1/terminal/[proposalId]/create/index.js.map +0 -1
- package/dist/routes/api/v1/terminal/[proposalId]/create/route.d.ts.map +0 -1
- package/dist/routes/api/v1/terminal/[proposalId]/create/route.js.map +0 -1
- package/dist/routes/api/v1/terminal/[proposalId]/destroy/index.d.ts.map +0 -1
- package/dist/routes/api/v1/terminal/[proposalId]/destroy/index.js.map +0 -1
- package/dist/routes/api/v1/terminal/[proposalId]/destroy/route.d.ts.map +0 -1
- package/dist/routes/api/v1/terminal/[proposalId]/destroy/route.js.map +0 -1
- package/dist/routes/api/v1/terminal/[proposalId]/resize/index.d.ts.map +0 -1
- package/dist/routes/api/v1/terminal/[proposalId]/resize/index.js.map +0 -1
- package/dist/routes/api/v1/terminal/[proposalId]/resize/route.d.ts.map +0 -1
- package/dist/routes/api/v1/terminal/[proposalId]/resize/route.js.map +0 -1
- package/dist/routes/api/v1/terminal/sessions/index.d.ts.map +0 -1
- package/dist/routes/api/v1/terminal/sessions/index.js.map +0 -1
- package/dist/routes/api/v1/terminal/sessions/route.d.ts.map +0 -1
- package/dist/routes/api/v1/terminal/sessions/route.js.map +0 -1
- package/dist/routes/api/v1/user/index.d.ts.map +0 -1
- package/dist/routes/api/v1/user/index.js.map +0 -1
- package/dist/routes/api/v1/user/settings/index.d.ts.map +0 -1
- package/dist/routes/api/v1/user/settings/index.js.map +0 -1
- package/dist/routes/api/v1/user/settings/route.d.ts.map +0 -1
- package/dist/routes/api/v1/user/settings/route.js.map +0 -1
- package/dist/server-with-static.d.ts.map +0 -1
- package/dist/server-with-static.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js.map +0 -1
- package/static/assets/index-ChgXTZpc.css +0 -33
- 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,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.
|
|
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
|
-
"
|
|
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.
|
|
36
|
-
"@lovelybunch/mcp": "^1.0.
|
|
37
|
-
"@lovelybunch/types": "^1.0.
|
|
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
|
}
|