@lovelybunch/api 1.0.71-alpha.3 → 1.0.71-alpha.5

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 (95) hide show
  1. package/dist/routes/api/v1/context/images/index.d.ts +2 -0
  2. package/dist/routes/api/v1/context/images/index.js +2 -0
  3. package/dist/routes/api/v1/context/images/route.d.ts +3 -0
  4. package/dist/routes/api/v1/context/images/route.js +253 -0
  5. package/dist/routes/api/v1/context/index.js +2 -0
  6. package/dist/routes/api/v1/resources/generate-audio/index.d.ts +3 -0
  7. package/dist/routes/api/v1/resources/generate-audio/index.js +5 -0
  8. package/dist/routes/api/v1/resources/generate-audio/route.d.ts +19 -0
  9. package/dist/routes/api/v1/resources/generate-audio/route.js +129 -0
  10. package/dist/routes/api/v1/resources/index.js +2 -0
  11. package/package.json +4 -4
  12. package/static/assets/{AgentDetailPage-DVDnvYcy.js → AgentDetailPage-B3CFO9Vg.js} +1 -1
  13. package/static/assets/{AgentEditPage-DRLTkdIZ.js → AgentEditPage-Cc8k9uYb.js} +1 -1
  14. package/static/assets/{AgentsPage-CVoYisFq.js → AgentsPage-CcRVHD2p.js} +2 -2
  15. package/static/assets/{AgentsSettingsPage-D9FDJHpC.js → AgentsSettingsPage-BMphtJ6C.js} +1 -1
  16. package/static/assets/{ApiKeysSettingsPage-DGcz0E10.js → ApiKeysSettingsPage-BLlmALn1.js} +3 -3
  17. package/static/assets/{ArchitectureEditPage-PXH0HtcY.js → ArchitectureEditPage-B8YrHerA.js} +1 -1
  18. package/static/assets/{ArchitecturePage-BiybPTif.js → ArchitecturePage-fIoEV_ow.js} +1 -1
  19. package/static/assets/{AuthSettingsPage-6TaOiZV7.js → AuthSettingsPage-CICO_5eb.js} +2 -2
  20. package/static/assets/{CallbackPage-BdZglBBj.js → CallbackPage-6lJyGru9.js} +1 -1
  21. package/static/assets/{CodePage-B239DtM2.js → CodePage-gGhNXTQn.js} +1 -1
  22. package/static/assets/{CollapsibleSection-DaqBpCe-.js → CollapsibleSection-CkCVMSBD.js} +1 -1
  23. package/static/assets/{DashboardPage-B2FJcHVR.js → DashboardPage-qkyq1COW.js} +1 -1
  24. package/static/assets/{GitPage-DaWE2Q-b.js → GitPage-Dj9uMiQV.js} +1 -1
  25. package/static/assets/{GitSettingsPage-bTqUr0fn.js → GitSettingsPage--hjPt4zu.js} +2 -2
  26. package/static/assets/{IdentityPage-eXzMXYy2.js → IdentityPage-DzqrsAU2.js} +2 -2
  27. package/static/assets/{ImplementationStepsEditor-CuDeossU.js → ImplementationStepsEditor-GxhD-g8y.js} +1 -1
  28. package/static/assets/{IntegrationsSettingsPage-wAf_7nar.js → IntegrationsSettingsPage-DR_v_Fbo.js} +1 -1
  29. package/static/assets/{KnowledgeDetailPage-B5ieYIze.js → KnowledgeDetailPage-BEHrLcNg.js} +1 -1
  30. package/static/assets/{KnowledgeEditPage-OMUREl1n.js → KnowledgeEditPage-CETMgdZf.js} +1 -1
  31. package/static/assets/{KnowledgePage-CKtcok1N.js → KnowledgePage-Dz2YIqdH.js} +2 -2
  32. package/static/assets/{LoginPage-B70_aCBv.js → LoginPage-DSxl4xGK.js} +1 -1
  33. package/static/assets/McpSettingsPage-CLDzqlt3.js +1 -0
  34. package/static/assets/{NewAgentPage-DITLLDez.js → NewAgentPage-DlEnBUUY.js} +1 -1
  35. package/static/assets/{NewKnowledgePage-C7vEg4PR.js → NewKnowledgePage-CI8D1NRB.js} +1 -1
  36. package/static/assets/{NewProposalPage-z8wqyXIj.js → NewProposalPage-B1hVwad9.js} +1 -1
  37. package/static/assets/{ProjectEditPage-BDj8GlD_.js → ProjectEditPage-t_oD7x6f.js} +1 -1
  38. package/static/assets/{ProjectPage-CtoKV0l9.js → ProjectPage-CMez4KRO.js} +1 -1
  39. package/static/assets/{PromptsSettingsPage-CI-pWQVw.js → PromptsSettingsPage-DXvS4JX8.js} +1 -1
  40. package/static/assets/{ProposalDetailPage-D6rhO9vm.js → ProposalDetailPage-Cbld0UYO.js} +1 -1
  41. package/static/assets/{ProposalEditPage-DCy3_sbg.js → ProposalEditPage-Dujm4G1-.js} +1 -1
  42. package/static/assets/{ProposalsPage-DQLqm83b.js → ProposalsPage-0L4kWC5Y.js} +1 -1
  43. package/static/assets/ResourcesPage-5sZL01s_.js +66 -0
  44. package/static/assets/{RulesSettingsPage-MgsP5qaA.js → RulesSettingsPage-D6qjkKbl.js} +1 -1
  45. package/static/assets/{SchedulePage-C1vDSjyh.js → SchedulePage-CgnTsib0.js} +1 -1
  46. package/static/assets/{TagInput-Cdfvhozb.js → TagInput-DJMwLVTn.js} +1 -1
  47. package/static/assets/{TerminalPage-NQzi2rzj.js → TerminalPage-EYVbapc9.js} +1 -1
  48. package/static/assets/{TerminalSessionPage-DQgbm-LP.js → TerminalSessionPage-CQCLFjOR.js} +1 -1
  49. package/static/assets/{UserPreferencesPage-CCYsj_XY.js → UserPreferencesPage-KAsCdvFQ.js} +1 -1
  50. package/static/assets/{UserSettingsPage-DdCnaoY_.js → UserSettingsPage-DclI2Mhd.js} +1 -1
  51. package/static/assets/{UtilitiesPage-DGcmJSz6.js → UtilitiesPage-BKdyva6y.js} +1 -1
  52. package/static/assets/{alert-BAeRxZ1d.js → alert-p2sQnjrU.js} +1 -1
  53. package/static/assets/{arrow-down-5CQhXptz.js → arrow-down-DGeJDsho.js} +1 -1
  54. package/static/assets/{arrow-left-DSqUNUH-.js → arrow-left-BRSAC1N6.js} +1 -1
  55. package/static/assets/{arrow-up-CYoJSbWn.js → arrow-up-C5ecpR5U.js} +1 -1
  56. package/static/assets/{badge-NJasrAx_.js → badge-DaM4gF82.js} +1 -1
  57. package/static/assets/browser-modal-CyeEbzDK.js +6 -0
  58. package/static/assets/{calendar-wiZSxCBM.js → calendar-CV2haPQ9.js} +1 -1
  59. package/static/assets/{card-CvaBJsG6.js → card-B9ym6neB.js} +1 -1
  60. package/static/assets/{chevron-left-CaZHWPr-.js → chevron-left-D8aMFTU2.js} +1 -1
  61. package/static/assets/{circle-alert-61156jM6.js → circle-alert-C-piOZLm.js} +1 -1
  62. package/static/assets/{circle-check-z0By2KN8.js → circle-check-4zzXsmHH.js} +1 -1
  63. package/static/assets/{circle-check-big-K_QMED_K.js → circle-check-big-AlE11jqb.js} +1 -1
  64. package/static/assets/{circle-play-88lMuMRZ.js → circle-play-cWY3nlZW.js} +1 -1
  65. package/static/assets/{circle-x-DdTsJYO7.js → circle-x-D58MbKgZ.js} +1 -1
  66. package/static/assets/{clipboard-BNXOfcye.js → clipboard-BFF6-pdC.js} +1 -1
  67. package/static/assets/{clock-BTCBJF7v.js → clock-B-uSJOTR.js} +1 -1
  68. package/static/assets/{download-BaYIFjpj.js → download-DrQn0jny.js} +1 -1
  69. package/static/assets/{eye-CuSCp49Y.js → eye-BcjteMts.js} +1 -1
  70. package/static/assets/{folder-git-2-CiVM8o0Y.js → folder-git-2-B_ezHf_E.js} +1 -1
  71. package/static/assets/index-B0JO3x3V.js +458 -0
  72. package/static/assets/index-C8p-lTq9.css +2 -0
  73. package/static/assets/label-BHOOQ99D.js +1 -0
  74. package/static/assets/{markdown-editor-DvlGlqU9.js → markdown-editor-B0i_LOAR.js} +1 -1
  75. package/static/assets/{pause-COIsHZIp.js → pause-DqQ7Twc6.js} +1 -1
  76. package/static/assets/{play-a8BsF4gF.js → play-Y2N8OVBu.js} +1 -1
  77. package/static/assets/{plus-Bon5P_OK.js → plus-D737EJ5S.js} +1 -1
  78. package/static/assets/radio-group-nRRUTZ_w.js +1 -0
  79. package/static/assets/{refresh-cw-CnHMzcH3.js → refresh-cw-uBnPtZwp.js} +1 -1
  80. package/static/assets/registry-ANRa5WBi.js +1 -0
  81. package/static/assets/{search-BR37JgJ3.js → search-cntvIhnF.js} +1 -1
  82. package/static/assets/{switch-D86f4WeD.js → switch-BYf9VEgx.js} +1 -1
  83. package/static/assets/{tabs-BYrDWPwx.js → tabs-BnsC3AY5.js} +1 -1
  84. package/static/assets/{tag--U3Nuedb.js → tag-C_HL28Xd.js} +1 -1
  85. package/static/assets/{terminal-preview-Be68j_3t.js → terminal-preview-Qv4UvCJz.js} +1 -1
  86. package/static/assets/{use-terminal-2DGl8X5T.js → use-terminal-5sW1t6SD.js} +1 -1
  87. package/static/assets/{zap-C0eIGEl_.js → zap-CrLPiVyl.js} +1 -1
  88. package/static/index.html +2 -2
  89. package/static/assets/McpSettingsPage-DcJIlHEi.js +0 -1
  90. package/static/assets/ResourcesPage-Bq9t872V.js +0 -66
  91. package/static/assets/browser-modal-x3ise3M1.js +0 -6
  92. package/static/assets/index-B8vejVRZ.js +0 -458
  93. package/static/assets/index-CKwmN6yL.css +0 -2
  94. package/static/assets/label-DtNTh--4.js +0 -1
  95. package/static/assets/radio-group-DpJuX02X.js +0 -1
@@ -0,0 +1,2 @@
1
+ import images from './route.js';
2
+ export default images;
@@ -0,0 +1,2 @@
1
+ import images from './route.js';
2
+ export default images;
@@ -0,0 +1,3 @@
1
+ import { Hono } from 'hono';
2
+ declare const app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
3
+ export default app;
@@ -0,0 +1,253 @@
1
+ import { Hono } from 'hono';
2
+ import { promises as fs } from 'fs';
3
+ import path from 'path';
4
+ import { getLogger } from '@lovelybunch/core/logging';
5
+ import { requireAuth } from '../../../../../middleware/auth.js';
6
+ const app = new Hono();
7
+ // Supported image MIME types
8
+ const IMAGE_MIME_TYPES = {
9
+ '.png': 'image/png',
10
+ '.jpg': 'image/jpeg',
11
+ '.jpeg': 'image/jpeg',
12
+ '.gif': 'image/gif',
13
+ '.webp': 'image/webp',
14
+ '.svg': 'image/svg+xml',
15
+ '.ico': 'image/x-icon',
16
+ '.bmp': 'image/bmp',
17
+ };
18
+ const ALLOWED_EXTENSIONS = Object.keys(IMAGE_MIME_TYPES);
19
+ function getImagesPath() {
20
+ let basePath;
21
+ if (process.env.NODE_ENV === 'development' && process.env.GAIT_DEV_ROOT) {
22
+ // Dev mode: use project root .nut directory
23
+ basePath = process.env.GAIT_DEV_ROOT;
24
+ }
25
+ else if (process.env.GAIT_DATA_PATH) {
26
+ // Production mode: use GAIT_DATA_PATH (set by CLI)
27
+ basePath = path.resolve(process.env.GAIT_DATA_PATH, '.nut');
28
+ }
29
+ else {
30
+ // Fallback: use current directory .nut
31
+ basePath = path.resolve(process.cwd(), '.nut');
32
+ }
33
+ return path.join(basePath, 'context', 'images');
34
+ }
35
+ function getMimeType(filename) {
36
+ const ext = path.extname(filename).toLowerCase();
37
+ return IMAGE_MIME_TYPES[ext] || null;
38
+ }
39
+ function isValidImageFilename(filename) {
40
+ const ext = path.extname(filename).toLowerCase();
41
+ return ALLOWED_EXTENSIONS.includes(ext);
42
+ }
43
+ function sanitizeFilename(filename) {
44
+ // Remove path traversal attempts and invalid characters
45
+ return filename
46
+ .replace(/\.\./g, '')
47
+ .replace(/[/\\]/g, '')
48
+ .replace(/[^a-zA-Z0-9._-]/g, '-');
49
+ }
50
+ /**
51
+ * GET /api/v1/context/images
52
+ * List all images
53
+ */
54
+ app.get('/', async (c) => {
55
+ try {
56
+ const imagesPath = getImagesPath();
57
+ // Ensure directory exists
58
+ await fs.mkdir(imagesPath, { recursive: true });
59
+ const files = await fs.readdir(imagesPath);
60
+ const images = await Promise.all(files
61
+ .filter(file => isValidImageFilename(file))
62
+ .map(async (file) => {
63
+ try {
64
+ const filePath = path.join(imagesPath, file);
65
+ const stats = await fs.stat(filePath);
66
+ const mimeType = getMimeType(file);
67
+ if (!mimeType)
68
+ return null;
69
+ return {
70
+ filename: file,
71
+ size: stats.size,
72
+ mimeType,
73
+ uploadedAt: stats.mtime.toISOString(),
74
+ };
75
+ }
76
+ catch {
77
+ return null;
78
+ }
79
+ }));
80
+ const validImages = images.filter((img) => img !== null);
81
+ return c.json({
82
+ success: true,
83
+ images: validImages.sort((a, b) => a.filename.localeCompare(b.filename))
84
+ });
85
+ }
86
+ catch (error) {
87
+ console.error('Error listing images:', error);
88
+ return c.json({ success: false, error: 'Failed to list images' }, 500);
89
+ }
90
+ });
91
+ /**
92
+ * GET /api/v1/context/images/:filename
93
+ * Serve a specific image
94
+ */
95
+ app.get('/:filename', async (c) => {
96
+ try {
97
+ const filename = c.req.param('filename');
98
+ const imagesPath = getImagesPath();
99
+ // Sanitize filename to prevent path traversal
100
+ const safeFilename = sanitizeFilename(filename);
101
+ if (!isValidImageFilename(safeFilename)) {
102
+ return c.json({ success: false, error: 'Invalid image file type' }, 400);
103
+ }
104
+ const filePath = path.join(imagesPath, safeFilename);
105
+ const mimeType = getMimeType(safeFilename);
106
+ if (!mimeType) {
107
+ return c.json({ success: false, error: 'Unsupported image format' }, 400);
108
+ }
109
+ try {
110
+ const fileBuffer = await fs.readFile(filePath);
111
+ const stats = await fs.stat(filePath);
112
+ return new Response(fileBuffer, {
113
+ headers: {
114
+ 'Content-Type': mimeType,
115
+ 'Content-Length': stats.size.toString(),
116
+ 'Cache-Control': 'public, max-age=31536000',
117
+ }
118
+ });
119
+ }
120
+ catch (error) {
121
+ if (error.code === 'ENOENT') {
122
+ return c.json({ success: false, error: 'Image not found' }, 404);
123
+ }
124
+ throw error;
125
+ }
126
+ }
127
+ catch (error) {
128
+ console.error('Error serving image:', error);
129
+ return c.json({ success: false, error: 'Failed to serve image' }, 500);
130
+ }
131
+ });
132
+ /**
133
+ * POST /api/v1/context/images
134
+ * Upload a new image (multipart/form-data)
135
+ */
136
+ app.post('/', async (c) => {
137
+ try {
138
+ const imagesPath = getImagesPath();
139
+ // Ensure directory exists
140
+ await fs.mkdir(imagesPath, { recursive: true });
141
+ // Parse multipart form data
142
+ const formData = await c.req.formData();
143
+ const file = formData.get('file');
144
+ if (!file || !(file instanceof File)) {
145
+ return c.json({ success: false, error: 'No file provided. Use multipart/form-data with a "file" field.' }, 400);
146
+ }
147
+ // Get filename from form data or use original
148
+ let filename = formData.get('filename')?.toString() || file.name;
149
+ filename = sanitizeFilename(filename);
150
+ if (!isValidImageFilename(filename)) {
151
+ return c.json({ success: false, error: `Invalid file type. Supported types: ${ALLOWED_EXTENSIONS.join(', ')}` }, 400);
152
+ }
153
+ const filePath = path.join(imagesPath, filename);
154
+ // Check if file already exists
155
+ try {
156
+ await fs.access(filePath);
157
+ return c.json({ success: false, error: 'An image with this filename already exists' }, 409);
158
+ }
159
+ catch {
160
+ // File doesn't exist, which is what we want
161
+ }
162
+ // Write file
163
+ const arrayBuffer = await file.arrayBuffer();
164
+ await fs.writeFile(filePath, Buffer.from(arrayBuffer));
165
+ const stats = await fs.stat(filePath);
166
+ const mimeType = getMimeType(filename);
167
+ // Log image upload event
168
+ try {
169
+ const session = await requireAuth(c);
170
+ const actor = session ? `human:${session.email}` : 'human:unknown';
171
+ const logger = getLogger();
172
+ logger.log({
173
+ kind: 'image.upload',
174
+ actor,
175
+ subject: `image:${filename}`,
176
+ tags: ['image', 'upload'],
177
+ payload: {
178
+ filename,
179
+ size: stats.size,
180
+ mimeType,
181
+ }
182
+ });
183
+ }
184
+ catch (logError) {
185
+ console.error('Error logging image upload:', logError);
186
+ }
187
+ return c.json({
188
+ success: true,
189
+ image: {
190
+ filename,
191
+ size: stats.size,
192
+ mimeType,
193
+ uploadedAt: stats.mtime.toISOString(),
194
+ }
195
+ }, 201);
196
+ }
197
+ catch (error) {
198
+ console.error('Error uploading image:', error);
199
+ return c.json({ success: false, error: 'Failed to upload image' }, 500);
200
+ }
201
+ });
202
+ /**
203
+ * DELETE /api/v1/context/images/:filename
204
+ * Delete an image
205
+ */
206
+ app.delete('/:filename', async (c) => {
207
+ try {
208
+ const filename = c.req.param('filename');
209
+ const imagesPath = getImagesPath();
210
+ // Sanitize filename to prevent path traversal
211
+ const safeFilename = sanitizeFilename(filename);
212
+ if (!isValidImageFilename(safeFilename)) {
213
+ return c.json({ success: false, error: 'Invalid image file type' }, 400);
214
+ }
215
+ const filePath = path.join(imagesPath, safeFilename);
216
+ // Check if file exists
217
+ try {
218
+ await fs.access(filePath);
219
+ }
220
+ catch {
221
+ return c.json({ success: false, error: 'Image not found' }, 404);
222
+ }
223
+ // Delete the file
224
+ await fs.unlink(filePath);
225
+ // Log image deletion event
226
+ try {
227
+ const session = await requireAuth(c);
228
+ const actor = session ? `human:${session.email}` : 'human:unknown';
229
+ const logger = getLogger();
230
+ logger.log({
231
+ kind: 'image.delete',
232
+ actor,
233
+ subject: `image:${safeFilename}`,
234
+ tags: ['image', 'delete'],
235
+ payload: {
236
+ filename: safeFilename,
237
+ }
238
+ });
239
+ }
240
+ catch (logError) {
241
+ console.error('Error logging image deletion:', logError);
242
+ }
243
+ return c.json({
244
+ success: true,
245
+ message: 'Image deleted successfully'
246
+ });
247
+ }
248
+ catch (error) {
249
+ console.error('Error deleting image:', error);
250
+ return c.json({ success: false, error: 'Failed to delete image' }, 500);
251
+ }
252
+ });
253
+ export default app;
@@ -2,8 +2,10 @@ import { Hono } from 'hono';
2
2
  import project from './project/route.js';
3
3
  import architecture from './architecture/route.js';
4
4
  import knowledge from './knowledge/index.js';
5
+ import images from './images/index.js';
5
6
  const context = new Hono();
6
7
  context.route('/project', project);
7
8
  context.route('/architecture', architecture);
8
9
  context.route('/knowledge', knowledge);
10
+ context.route('/images', images);
9
11
  export default context;
@@ -0,0 +1,3 @@
1
+ import { Hono } from 'hono';
2
+ declare const app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
3
+ export default app;
@@ -0,0 +1,5 @@
1
+ import { Hono } from 'hono';
2
+ import { POST } from './route.js';
3
+ const app = new Hono();
4
+ app.post('/', POST);
5
+ export default app;
@@ -0,0 +1,19 @@
1
+ import { Context } from 'hono';
2
+ export declare function POST(c: Context): Promise<(Response & import("hono").TypedResponse<{
3
+ success: false;
4
+ error: {
5
+ code: string;
6
+ message: string;
7
+ };
8
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
9
+ success: true;
10
+ data: {
11
+ audioUrl: string;
12
+ };
13
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
14
+ success: false;
15
+ error: {
16
+ code: string;
17
+ message: string;
18
+ };
19
+ }, 500, "json">)>;
@@ -0,0 +1,129 @@
1
+ import Replicate from 'replicate';
2
+ import path from 'path';
3
+ import { homedir } from 'os';
4
+ import { existsSync, readFileSync } from 'fs';
5
+ /**
6
+ * Get Replicate API token from global config or environment variable
7
+ */
8
+ function getReplicateApiToken() {
9
+ // First try global config
10
+ try {
11
+ const platform = process.platform;
12
+ let configDir;
13
+ if (platform === 'win32') {
14
+ configDir = path.join(process.env.APPDATA || homedir(), 'coconuts');
15
+ }
16
+ else if (platform === 'darwin') {
17
+ configDir = path.join(homedir(), 'Library', 'Application Support', 'coconuts');
18
+ }
19
+ else {
20
+ configDir = path.join(process.env.XDG_CONFIG_HOME || path.join(homedir(), '.config'), 'coconuts');
21
+ }
22
+ const configPath = path.join(configDir, 'config.json');
23
+ if (existsSync(configPath)) {
24
+ const config = JSON.parse(readFileSync(configPath, 'utf-8'));
25
+ if (config.apiKeys?.replicate) {
26
+ return config.apiKeys.replicate;
27
+ }
28
+ }
29
+ }
30
+ catch (error) {
31
+ console.warn('Failed to load Replicate token from config:', error);
32
+ }
33
+ // Fallback to environment variable
34
+ return process.env.REPLICATE_API_TOKEN || null;
35
+ }
36
+ // Initialize Replicate client lazily to ensure token is loaded at request time
37
+ function getReplicateClient() {
38
+ const token = getReplicateApiToken();
39
+ if (!token) {
40
+ throw new Error('Replicate API token not configured');
41
+ }
42
+ return new Replicate({
43
+ auth: token,
44
+ });
45
+ }
46
+ export async function POST(c) {
47
+ try {
48
+ // Check if Replicate API token is configured
49
+ const replicateToken = getReplicateApiToken();
50
+ if (!replicateToken) {
51
+ return c.json({
52
+ success: false,
53
+ error: {
54
+ code: 'MISSING_API_TOKEN',
55
+ message: 'Replicate API token not configured. Please add it in Settings → Integrations.'
56
+ }
57
+ }, 400);
58
+ }
59
+ const body = await c.req.json();
60
+ const { text, voice_id = 'English_Trustworth_Man', speed = 1, pitch = 0, emotion = 'auto', language_boost = 'English', audio_format = 'mp3' } = body;
61
+ if (!text || !text.trim()) {
62
+ return c.json({
63
+ success: false,
64
+ error: {
65
+ code: 'MISSING_TEXT',
66
+ message: 'Text is required for audio generation'
67
+ }
68
+ }, 400);
69
+ }
70
+ // Build input for minimax/speech-02-turbo
71
+ const input = {
72
+ text: text.trim(),
73
+ pitch,
74
+ speed,
75
+ volume: 1,
76
+ bitrate: 128000,
77
+ channel: 'mono',
78
+ emotion,
79
+ voice_id,
80
+ sample_rate: 32000,
81
+ audio_format,
82
+ language_boost,
83
+ subtitle_enable: false,
84
+ english_normalization: true
85
+ };
86
+ // Run the model
87
+ const replicateClient = getReplicateClient();
88
+ const output = await replicateClient.run('minimax/speech-02-turbo', { input });
89
+ // Extract URL from output
90
+ // Replicate output can be: FileOutput object with url() method
91
+ let audioUrl;
92
+ if (typeof output === 'string') {
93
+ audioUrl = output;
94
+ }
95
+ else if (output && typeof output === 'object') {
96
+ // Check for url() method (FileOutput object)
97
+ const outputObj = output;
98
+ if (typeof outputObj.url === 'function') {
99
+ audioUrl = outputObj.url();
100
+ }
101
+ else if ('url' in outputObj && typeof outputObj.url === 'string') {
102
+ audioUrl = outputObj.url;
103
+ }
104
+ else {
105
+ throw new Error('Unexpected output format from Replicate');
106
+ }
107
+ }
108
+ else {
109
+ throw new Error('Unexpected output format from Replicate');
110
+ }
111
+ return c.json({
112
+ success: true,
113
+ data: {
114
+ audioUrl
115
+ }
116
+ });
117
+ }
118
+ catch (error) {
119
+ console.error('Error generating audio:', error);
120
+ const message = error instanceof Error ? error.message : 'Failed to generate audio';
121
+ return c.json({
122
+ success: false,
123
+ error: {
124
+ code: 'GENERATION_ERROR',
125
+ message
126
+ }
127
+ }, 500);
128
+ }
129
+ }
@@ -1,8 +1,10 @@
1
1
  import { Hono } from 'hono';
2
2
  import { GET, POST } from './route.js';
3
3
  import generate from './generate/index.js';
4
+ import generateAudio from './generate-audio/index.js';
4
5
  const app = new Hono();
5
6
  app.get('/', GET);
6
7
  app.post('/', POST);
7
8
  app.route('/generate', generate);
9
+ app.route('/generate-audio', generateAudio);
8
10
  export default app;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovelybunch/api",
3
- "version": "1.0.71-alpha.3",
3
+ "version": "1.0.71-alpha.5",
4
4
  "type": "module",
5
5
  "main": "dist/server-with-static.js",
6
6
  "exports": {
@@ -36,9 +36,9 @@
36
36
  "dependencies": {
37
37
  "@hono/node-server": "^1.13.7",
38
38
  "@hono/node-ws": "^1.0.6",
39
- "@lovelybunch/core": "^1.0.71-alpha.3",
40
- "@lovelybunch/mcp": "^1.0.71-alpha.3",
41
- "@lovelybunch/types": "^1.0.71-alpha.3",
39
+ "@lovelybunch/core": "^1.0.71-alpha.5",
40
+ "@lovelybunch/mcp": "^1.0.71-alpha.5",
41
+ "@lovelybunch/types": "^1.0.71-alpha.5",
42
42
  "arctic": "^1.9.2",
43
43
  "bcrypt": "^5.1.1",
44
44
  "cookie": "^0.6.0",
@@ -1 +1 @@
1
- import{E as C,u as E,r as h,j as e,B as i,L as d,J as k,T as B,i as T,A as N}from"./index-B8vejVRZ.js";import{C as l,b as o,a as m,c as f,d as z}from"./card-CvaBJsG6.js";import{B as v}from"./badge-NJasrAx_.js";import{A as u}from"./arrow-left-DSqUNUH-.js";const D=t=>t?Array.isArray(t)?t.filter(r=>typeof r=="string").map(r=>r.trim()).filter(Boolean):typeof t=="string"?t.split(",").map(r=>r.trim()).filter(Boolean):[]:[],c={blue:{bg:"#dbeafe",border:"#2563eb",text:"#1e40af"},green:{bg:"#dcfce7",border:"#16a34a",text:"#166534"},red:{bg:"#fee2e2",border:"#dc2626",text:"#991b1b"},emerald:{bg:"#d1fae5",border:"#10b981",text:"#047857"},purple:{bg:"#f3e8ff",border:"#9333ea",text:"#6b21a8"},orange:{bg:"#fed7aa",border:"#ea580c",text:"#9a3412"},yellow:{bg:"#fef9c3",border:"#eab308",text:"#854d0e"},teal:{bg:"#ccfbf1",border:"#14b8a6",text:"#0f766e"},indigo:{bg:"#e0e7ff",border:"#6366f1",text:"#4338ca"},pink:{bg:"#fce7f3",border:"#ec4899",text:"#9f1239"},cyan:{bg:"#cffafe",border:"#06b6d4",text:"#155e75"},slate:{bg:"#f1f5f9",border:"#475569",text:"#334155"},gray:{bg:"#f3f4f6",border:"#6b7280",text:"#374151"}};function F(){const t=C(),r=E(),[s,y]=h.useState(null),[w,j]=h.useState(!0),[p,x]=h.useState(null);h.useEffect(()=>{async function a(){try{j(!0);const g=await(await fetch(`${N}/api/v1/agents/${t.id}`)).json();g.success?y(g.document):x(g.error||"Failed to fetch agent")}catch(n){x(n instanceof Error?n.message:"Unknown error")}finally{j(!1)}}t.id&&a()},[t.id]);const A=async()=>{if(!(!s||!confirm("Are you sure you want to delete this agent?")))try{const n=await(await fetch(`${N}/api/v1/agents/${s.filename.replace(".md","")}`,{method:"DELETE"})).json();n.success?r("/agents"):x(n.error?.message||"Failed to delete agent")}catch(a){x(a instanceof Error?a.message:"Unknown error")}};if(w)return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"h-8 bg-muted rounded w-64 animate-pulse"}),e.jsx("div",{className:"h-4 bg-muted rounded w-32 animate-pulse mt-2"})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(i,{variant:"ghost",size:"sm",asChild:!0,className:"px-2 hover:bg-transparent",children:e.jsx(d,{to:"/agents",className:"flex items-center text-muted-foreground hover:text-foreground transition-colors",children:e.jsx(u,{className:"h-4 w-4"})})})})]}),e.jsx(l,{children:e.jsxs(o,{children:[e.jsx("div",{className:"h-6 bg-muted rounded w-48 animate-pulse"}),e.jsx("div",{className:"h-4 bg-muted rounded w-64 animate-pulse"})]})})]});if(p||!s)return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Agent Not Found"}),e.jsx("p",{className:"text-muted-foreground",children:"The requested agent could not be found"})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(i,{variant:"ghost",size:"sm",asChild:!0,className:"px-2 hover:bg-transparent",children:e.jsx(d,{to:"/agents",className:"flex items-center text-muted-foreground hover:text-foreground transition-colors",children:e.jsx(u,{className:"h-4 w-4"})})})})]}),e.jsx(l,{children:e.jsx(m,{className:"pt-6",children:e.jsx("div",{className:"text-center",children:e.jsx("p",{className:"text-destructive",children:p||"Agent not found"})})})})]});const b=D(s.metadata.tools);return e.jsxs("div",{className:"space-y-6",children:[e.jsx("div",{className:"space-y-1",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsx("h1",{className:"text-xl sm:text-2xl font-bold tracking-tight",children:s.metadata.name}),e.jsxs("div",{className:"flex items-center gap-2 flex-shrink-0",children:[e.jsx(i,{variant:"ghost",size:"sm",asChild:!0,children:e.jsx(d,{to:"/agents",className:"flex items-center gap-1 text-muted-foreground hover:text-foreground transition-colors",children:e.jsx(u,{className:"h-4 w-4"})})}),e.jsx(i,{variant:"outline",size:"sm",asChild:!0,children:e.jsxs(d,{to:`/agents/${s.filename.replace(".md","")}/edit`,children:[e.jsx(k,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Edit"})]})}),e.jsxs(i,{variant:"destructive",size:"sm",onClick:A,children:[e.jsx(B,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Delete"})]})]})]})}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-6",children:[e.jsxs("div",{className:"lg:col-span-2 space-y-6",children:[e.jsxs(l,{children:[e.jsx(o,{children:e.jsx(f,{children:"Description"})}),e.jsx(m,{children:e.jsx("p",{children:s.metadata.description})})]}),s.content&&e.jsxs(l,{children:[e.jsxs(o,{children:[e.jsx(f,{children:"Instructions"}),e.jsx(z,{children:"System prompt and behavior instructions for this agent"})]}),e.jsx(m,{children:e.jsx("pre",{className:"whitespace-pre-wrap text-sm bg-muted p-4 rounded-md",children:s.content})})]})]}),e.jsxs("div",{className:"space-y-6",children:[e.jsxs(l,{children:[e.jsx(o,{children:e.jsx(f,{children:"Agent Actions"})}),e.jsx(m,{className:"space-y-2",children:e.jsx(i,{variant:"default",className:"w-full justify-start",asChild:!0,children:e.jsxs(d,{to:`/terminal/ag-${s.filename.replace(".md","")}`,children:[e.jsx(T,{className:"h-4 w-4 mr-2"}),"Prepare Agent"]})})})]}),e.jsxs(l,{children:[e.jsx(o,{children:e.jsx(f,{children:"Information"})}),e.jsxs(m,{className:"space-y-2",children:[s.metadata.color&&e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium mb-2",children:"Color"}),e.jsx(v,{variant:"outline",className:"capitalize border-2",style:{backgroundColor:c[s.metadata.color]?.bg||c.blue.bg,color:c[s.metadata.color]?.text||c.blue.text,borderColor:c[s.metadata.color]?.border||c.blue.border},children:s.metadata.color})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:"Tools"}),b.length>0?e.jsx("div",{className:"flex flex-wrap gap-2 mt-1",children:b.map(a=>e.jsx(v,{variant:"secondary",children:a},a))}):e.jsx("p",{className:"text-sm text-muted-foreground",children:"No specific tools configured - inherits all tools"})]})]})]})]})]})]})}export{F as default};
1
+ import{E as C,u as E,r as h,j as e,B as i,L as d,J as k,T as B,i as T,A as N}from"./index-B0JO3x3V.js";import{C as l,b as o,a as m,c as f,d as z}from"./card-B9ym6neB.js";import{B as v}from"./badge-DaM4gF82.js";import{A as u}from"./arrow-left-BRSAC1N6.js";const D=t=>t?Array.isArray(t)?t.filter(r=>typeof r=="string").map(r=>r.trim()).filter(Boolean):typeof t=="string"?t.split(",").map(r=>r.trim()).filter(Boolean):[]:[],c={blue:{bg:"#dbeafe",border:"#2563eb",text:"#1e40af"},green:{bg:"#dcfce7",border:"#16a34a",text:"#166534"},red:{bg:"#fee2e2",border:"#dc2626",text:"#991b1b"},emerald:{bg:"#d1fae5",border:"#10b981",text:"#047857"},purple:{bg:"#f3e8ff",border:"#9333ea",text:"#6b21a8"},orange:{bg:"#fed7aa",border:"#ea580c",text:"#9a3412"},yellow:{bg:"#fef9c3",border:"#eab308",text:"#854d0e"},teal:{bg:"#ccfbf1",border:"#14b8a6",text:"#0f766e"},indigo:{bg:"#e0e7ff",border:"#6366f1",text:"#4338ca"},pink:{bg:"#fce7f3",border:"#ec4899",text:"#9f1239"},cyan:{bg:"#cffafe",border:"#06b6d4",text:"#155e75"},slate:{bg:"#f1f5f9",border:"#475569",text:"#334155"},gray:{bg:"#f3f4f6",border:"#6b7280",text:"#374151"}};function F(){const t=C(),r=E(),[s,y]=h.useState(null),[w,j]=h.useState(!0),[p,x]=h.useState(null);h.useEffect(()=>{async function a(){try{j(!0);const g=await(await fetch(`${N}/api/v1/agents/${t.id}`)).json();g.success?y(g.document):x(g.error||"Failed to fetch agent")}catch(n){x(n instanceof Error?n.message:"Unknown error")}finally{j(!1)}}t.id&&a()},[t.id]);const A=async()=>{if(!(!s||!confirm("Are you sure you want to delete this agent?")))try{const n=await(await fetch(`${N}/api/v1/agents/${s.filename.replace(".md","")}`,{method:"DELETE"})).json();n.success?r("/agents"):x(n.error?.message||"Failed to delete agent")}catch(a){x(a instanceof Error?a.message:"Unknown error")}};if(w)return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"h-8 bg-muted rounded w-64 animate-pulse"}),e.jsx("div",{className:"h-4 bg-muted rounded w-32 animate-pulse mt-2"})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(i,{variant:"ghost",size:"sm",asChild:!0,className:"px-2 hover:bg-transparent",children:e.jsx(d,{to:"/agents",className:"flex items-center text-muted-foreground hover:text-foreground transition-colors",children:e.jsx(u,{className:"h-4 w-4"})})})})]}),e.jsx(l,{children:e.jsxs(o,{children:[e.jsx("div",{className:"h-6 bg-muted rounded w-48 animate-pulse"}),e.jsx("div",{className:"h-4 bg-muted rounded w-64 animate-pulse"})]})})]});if(p||!s)return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Agent Not Found"}),e.jsx("p",{className:"text-muted-foreground",children:"The requested agent could not be found"})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(i,{variant:"ghost",size:"sm",asChild:!0,className:"px-2 hover:bg-transparent",children:e.jsx(d,{to:"/agents",className:"flex items-center text-muted-foreground hover:text-foreground transition-colors",children:e.jsx(u,{className:"h-4 w-4"})})})})]}),e.jsx(l,{children:e.jsx(m,{className:"pt-6",children:e.jsx("div",{className:"text-center",children:e.jsx("p",{className:"text-destructive",children:p||"Agent not found"})})})})]});const b=D(s.metadata.tools);return e.jsxs("div",{className:"space-y-6",children:[e.jsx("div",{className:"space-y-1",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsx("h1",{className:"text-xl sm:text-2xl font-bold tracking-tight",children:s.metadata.name}),e.jsxs("div",{className:"flex items-center gap-2 flex-shrink-0",children:[e.jsx(i,{variant:"ghost",size:"sm",asChild:!0,children:e.jsx(d,{to:"/agents",className:"flex items-center gap-1 text-muted-foreground hover:text-foreground transition-colors",children:e.jsx(u,{className:"h-4 w-4"})})}),e.jsx(i,{variant:"outline",size:"sm",asChild:!0,children:e.jsxs(d,{to:`/agents/${s.filename.replace(".md","")}/edit`,children:[e.jsx(k,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Edit"})]})}),e.jsxs(i,{variant:"destructive",size:"sm",onClick:A,children:[e.jsx(B,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Delete"})]})]})]})}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-6",children:[e.jsxs("div",{className:"lg:col-span-2 space-y-6",children:[e.jsxs(l,{children:[e.jsx(o,{children:e.jsx(f,{children:"Description"})}),e.jsx(m,{children:e.jsx("p",{children:s.metadata.description})})]}),s.content&&e.jsxs(l,{children:[e.jsxs(o,{children:[e.jsx(f,{children:"Instructions"}),e.jsx(z,{children:"System prompt and behavior instructions for this agent"})]}),e.jsx(m,{children:e.jsx("pre",{className:"whitespace-pre-wrap text-sm bg-muted p-4 rounded-md",children:s.content})})]})]}),e.jsxs("div",{className:"space-y-6",children:[e.jsxs(l,{children:[e.jsx(o,{children:e.jsx(f,{children:"Agent Actions"})}),e.jsx(m,{className:"space-y-2",children:e.jsx(i,{variant:"default",className:"w-full justify-start",asChild:!0,children:e.jsxs(d,{to:`/terminal/ag-${s.filename.replace(".md","")}`,children:[e.jsx(T,{className:"h-4 w-4 mr-2"}),"Prepare Agent"]})})})]}),e.jsxs(l,{children:[e.jsx(o,{children:e.jsx(f,{children:"Information"})}),e.jsxs(m,{className:"space-y-2",children:[s.metadata.color&&e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium mb-2",children:"Color"}),e.jsx(v,{variant:"outline",className:"capitalize border-2",style:{backgroundColor:c[s.metadata.color]?.bg||c.blue.bg,color:c[s.metadata.color]?.text||c.blue.text,borderColor:c[s.metadata.color]?.border||c.blue.border},children:s.metadata.color})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:"Tools"}),b.length>0?e.jsx("div",{className:"flex flex-wrap gap-2 mt-1",children:b.map(a=>e.jsx(v,{variant:"secondary",children:a},a))}):e.jsx("p",{className:"text-sm text-muted-foreground",children:"No specific tools configured - inherits all tools"})]})]})]})]})]})]})}export{F as default};
@@ -1 +1 @@
1
- import{E as X,u as Y,H as Z,r as n,j as e,B as m,L as v,i as O,I as D,a0 as ee,ac as te,A as y}from"./index-B8vejVRZ.js";import{C as N,a as C,b as se,c as ae}from"./card-CvaBJsG6.js";import{L as l}from"./label-DtNTh--4.js";import{B as re}from"./badge-NJasrAx_.js";import{c as ne}from"./clipboard-B9ndUJKl.js";import{A as z}from"./arrow-left-DSqUNUH-.js";import{C as oe,a as ie}from"./clipboard-BNXOfcye.js";function xe(){const{id:i}=X(),U=Y(),{toast:w}=Z(),[q,S]=n.useState(!0),[o,A]=n.useState(!1),[d,c]=n.useState(null),[H,R]=n.useState(""),[u,E]=n.useState(""),[g,F]=n.useState(""),[f,P]=n.useState("blue"),[x,k]=n.useState([]),[h,$]=n.useState(""),[L,p]=n.useState([]),[_,M]=n.useState(!0),[J,T]=n.useState(!1),G=["blue","green","red","emerald","purple","orange","yellow","teal","indigo","pink","cyan","slate","gray"],K={blue:{bg:"#3b82f6",border:"#1e40af",text:"#ffffff"},green:{bg:"#22c55e",border:"#15803d",text:"#ffffff"},red:{bg:"#ef4444",border:"#b91c1c",text:"#ffffff"},emerald:{bg:"#10b981",border:"#047857",text:"#ffffff"},purple:{bg:"#a855f7",border:"#7e22ce",text:"#ffffff"},orange:{bg:"#f97316",border:"#c2410c",text:"#ffffff"},yellow:{bg:"#eab308",border:"#a16207",text:"#ffffff"},teal:{bg:"#14b8a6",border:"#0f766e",text:"#ffffff"},indigo:{bg:"#6366f1",border:"#4338ca",text:"#ffffff"},pink:{bg:"#ec4899",border:"#be185d",text:"#ffffff"},cyan:{bg:"#06b6d4",border:"#0e7490",text:"#ffffff"},slate:{bg:"#64748b",border:"#475569",text:"#ffffff"},gray:{bg:"#6b7280",border:"#4b5563",text:"#ffffff"}},Q=t=>{if(!t)return[];if(Array.isArray(t)){const a=t.filter(s=>typeof s=="string").map(s=>s.trim()).filter(Boolean);return Array.from(new Set(a))}return typeof t=="string"?Array.from(new Set(t.split(",").map(a=>a.trim()).filter(Boolean))):[]};n.useEffect(()=>{async function t(){try{S(!0);const s=await(await fetch(`${y}/api/v1/agents/${i}`)).json();if(!s.success)throw new Error(s.error||"Failed to load agent");const r=s.document;R(r.filename),E(r.metadata.name||""),F(r.metadata.description||""),P(r.metadata.color||"blue"),$(r.content||""),k(Q(r.metadata.tools))}catch(a){const s=a instanceof Error?a.message:"Failed to load agent";c(s)}finally{S(!1)}}i&&t()},[i]),n.useEffect(()=>{let t=!0;return(async()=>{M(!0);try{const s=await fetch(`${y}/api/v1/mcp`);if(!s.ok)throw new Error("Failed to fetch MCP servers");const r=await s.json();if(!r?.success||!Array.isArray(r.servers)){t&&p([]);return}const B=r.mcpServers&&typeof r.mcpServers=="object"?r.mcpServers:{},b=r.servers.map(I=>{const j=B[I]??{};return{name:I,enabled:j?.enabled!==!1,description:typeof j?.description=="string"?j.description:void 0}});t&&p(b)}catch(s){console.error("Failed to load MCP servers",s),t&&p([])}finally{t&&M(!1)}})(),()=>{t=!1}},[]);const V=async()=>{const t=".nut/config.json";try{await ne(t),T(!0),w({title:"Copied!",description:`${t} copied to clipboard`}),setTimeout(()=>T(!1),2e3)}catch(a){console.error("Failed to copy config path:",a),w({title:"Error",description:"Failed to copy to clipboard",variant:"destructive"})}},W=async t=>{if(t.preventDefault(),!u.trim()||!g.trim()||!h.trim()){c("Name, description, and agent instructions are required");return}try{A(!0),c(null);const a={name:u.trim(),description:g.trim(),content:h.trim(),metadata:{color:f,tools:x.length?x:void 0}},r=await(await fetch(`${y}/api/v1/agents/${i}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)})).json();if(!r.success)throw new Error(r.error||"Failed to update agent");const b=r.document.filename.replace(/\.md$/,"");U(`/agents/${b}`)}catch(a){const s=a instanceof Error?a.message:"Failed to update agent";c(s)}finally{A(!1)}};return q?e.jsx("div",{className:"space-y-6",children:e.jsx(N,{children:e.jsx(C,{className:"pt-6",children:"Loading agent..."})})}):d?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Edit Agent"}),e.jsx("p",{className:"text-muted-foreground",children:"Unable to load agent"})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(m,{variant:"ghost",size:"sm",asChild:!0,children:e.jsx(v,{to:`/agents/${i}`,className:"flex items-center gap-1 text-muted-foreground hover:text-foreground transition-colors",children:e.jsx(z,{className:"h-4 w-4"})})})})]}),e.jsx(N,{children:e.jsx(C,{className:"pt-6",children:e.jsx("div",{className:"text-destructive",children:d})})})]}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Edit Agent"}),e.jsxs("p",{className:"text-muted-foreground",children:["File: ",H]})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(m,{variant:"ghost",size:"sm",asChild:!0,children:e.jsx(v,{to:`/agents/${i}`,className:"flex items-center gap-1 text-muted-foreground hover:text-foreground transition-colors",children:e.jsx(z,{className:"h-4 w-4"})})})})]}),e.jsxs(N,{children:[e.jsx(se,{children:e.jsxs(ae,{className:"flex items-center gap-2",children:[e.jsx(O,{className:"h-5 w-5"}),"Agent Configuration"]})}),e.jsx(C,{children:e.jsxs("form",{onSubmit:W,className:"space-y-6",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(l,{htmlFor:"name",children:"Name *"}),e.jsx(D,{id:"name",value:u,onChange:t=>E(t.target.value),disabled:o})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(l,{htmlFor:"description",children:"Description *"}),e.jsx(D,{id:"description",value:g,onChange:t=>F(t.target.value),disabled:o})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(l,{children:"Color"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:G.map(t=>{const a=K[t];return e.jsx("button",{type:"button",onClick:()=>P(t),disabled:o,className:`w-10 h-10 rounded-md border-2 transition-all ${f===t?"ring-2 ring-offset-2 shadow-md":"hover:scale-110 hover:shadow-sm"}`,style:{backgroundColor:a.bg,borderColor:f===t?a.border:"hsl(var(--border))",...f===t&&{"--tw-ring-color":a.border}},title:t,children:e.jsx("span",{className:"sr-only",children:t})},t)})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(l,{htmlFor:"content",children:"Agent Instructions *"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["System prompt or instructions for this agent's behavior."," ","Insert ",e.jsx("code",{className:"text-xs bg-muted px-1.5 py-0.5 rounded font-mono",children:".nut/config.json"})," ",e.jsx("button",{type:"button",onClick:V,className:"inline-flex items-center align-middle text-muted-foreground hover:text-foreground transition-colors",title:"Copy .nut/config.json to clipboard",children:J?e.jsx(oe,{className:"h-3.5 w-3.5 ml-0.5"}):e.jsx(ie,{className:"h-3.5 w-3.5 ml-0.5"})})," ","if you want the agent to be able to access its name, role, or email address."]}),e.jsx(ee,{id:"content",value:h,onChange:t=>$(t.target.value),rows:8,disabled:o,required:!0})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(l,{children:"Tools (Optional)"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Choose which MCP servers this agent should be able to use. Leave empty to inherit all available servers."}),e.jsx("div",{className:"space-y-2",children:_?e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading MCP servers…"}):L.length===0?e.jsx("div",{className:"text-sm text-muted-foreground border border-dashed rounded-md p-3",children:"No MCP servers configured yet. Configure servers in Settings → MCP."}):L.map(t=>e.jsxs("label",{className:"flex items-start gap-3 rounded-md border border-transparent bg-muted/30 px-3 py-2 hover:border-muted transition-colors",children:[e.jsx(te,{checked:x.includes(t.name),onCheckedChange:a=>{k(s=>a===!0?s.includes(t.name)?s:[...s,t.name]:s.filter(r=>r!==t.name))},disabled:o||!t.enabled}),e.jsxs("div",{className:"flex flex-col",children:[e.jsxs("span",{className:"text-sm font-medium",children:[t.name,!t.enabled&&e.jsx(re,{variant:"secondary",className:"ml-2 text-xs",children:"Disabled"})]}),e.jsx("span",{className:"text-xs text-muted-foreground",children:t.enabled?t.description||"Enabled MCP server":"Enable this server in Settings to allow agents to use it"})]})]},t.name))})]}),d&&e.jsx("div",{className:"text-sm text-destructive bg-destructive/10 p-3 rounded-md",children:d}),e.jsxs("div",{className:"flex gap-2 justify-end",children:[e.jsx(m,{type:"button",variant:"outline",asChild:!0,disabled:o,children:e.jsx(v,{to:`/agents/${i}`,children:"Cancel"})}),e.jsx(m,{type:"submit",disabled:o,children:o?"Saving...":"Save Changes"})]})]})})]})]})}export{xe as default};
1
+ import{E as X,u as Y,H as Z,r as n,j as e,B as m,L as v,i as O,I as D,a0 as ee,ac as te,A as y}from"./index-B0JO3x3V.js";import{C as N,a as C,b as se,c as ae}from"./card-B9ym6neB.js";import{L as l}from"./label-BHOOQ99D.js";import{B as re}from"./badge-DaM4gF82.js";import{c as ne}from"./clipboard-B9ndUJKl.js";import{A as z}from"./arrow-left-BRSAC1N6.js";import{C as oe,a as ie}from"./clipboard-BFF6-pdC.js";function xe(){const{id:i}=X(),U=Y(),{toast:w}=Z(),[q,S]=n.useState(!0),[o,A]=n.useState(!1),[d,c]=n.useState(null),[H,R]=n.useState(""),[u,E]=n.useState(""),[g,F]=n.useState(""),[f,P]=n.useState("blue"),[x,k]=n.useState([]),[h,$]=n.useState(""),[L,p]=n.useState([]),[_,M]=n.useState(!0),[J,T]=n.useState(!1),G=["blue","green","red","emerald","purple","orange","yellow","teal","indigo","pink","cyan","slate","gray"],K={blue:{bg:"#3b82f6",border:"#1e40af",text:"#ffffff"},green:{bg:"#22c55e",border:"#15803d",text:"#ffffff"},red:{bg:"#ef4444",border:"#b91c1c",text:"#ffffff"},emerald:{bg:"#10b981",border:"#047857",text:"#ffffff"},purple:{bg:"#a855f7",border:"#7e22ce",text:"#ffffff"},orange:{bg:"#f97316",border:"#c2410c",text:"#ffffff"},yellow:{bg:"#eab308",border:"#a16207",text:"#ffffff"},teal:{bg:"#14b8a6",border:"#0f766e",text:"#ffffff"},indigo:{bg:"#6366f1",border:"#4338ca",text:"#ffffff"},pink:{bg:"#ec4899",border:"#be185d",text:"#ffffff"},cyan:{bg:"#06b6d4",border:"#0e7490",text:"#ffffff"},slate:{bg:"#64748b",border:"#475569",text:"#ffffff"},gray:{bg:"#6b7280",border:"#4b5563",text:"#ffffff"}},Q=t=>{if(!t)return[];if(Array.isArray(t)){const a=t.filter(s=>typeof s=="string").map(s=>s.trim()).filter(Boolean);return Array.from(new Set(a))}return typeof t=="string"?Array.from(new Set(t.split(",").map(a=>a.trim()).filter(Boolean))):[]};n.useEffect(()=>{async function t(){try{S(!0);const s=await(await fetch(`${y}/api/v1/agents/${i}`)).json();if(!s.success)throw new Error(s.error||"Failed to load agent");const r=s.document;R(r.filename),E(r.metadata.name||""),F(r.metadata.description||""),P(r.metadata.color||"blue"),$(r.content||""),k(Q(r.metadata.tools))}catch(a){const s=a instanceof Error?a.message:"Failed to load agent";c(s)}finally{S(!1)}}i&&t()},[i]),n.useEffect(()=>{let t=!0;return(async()=>{M(!0);try{const s=await fetch(`${y}/api/v1/mcp`);if(!s.ok)throw new Error("Failed to fetch MCP servers");const r=await s.json();if(!r?.success||!Array.isArray(r.servers)){t&&p([]);return}const B=r.mcpServers&&typeof r.mcpServers=="object"?r.mcpServers:{},b=r.servers.map(I=>{const j=B[I]??{};return{name:I,enabled:j?.enabled!==!1,description:typeof j?.description=="string"?j.description:void 0}});t&&p(b)}catch(s){console.error("Failed to load MCP servers",s),t&&p([])}finally{t&&M(!1)}})(),()=>{t=!1}},[]);const V=async()=>{const t=".nut/config.json";try{await ne(t),T(!0),w({title:"Copied!",description:`${t} copied to clipboard`}),setTimeout(()=>T(!1),2e3)}catch(a){console.error("Failed to copy config path:",a),w({title:"Error",description:"Failed to copy to clipboard",variant:"destructive"})}},W=async t=>{if(t.preventDefault(),!u.trim()||!g.trim()||!h.trim()){c("Name, description, and agent instructions are required");return}try{A(!0),c(null);const a={name:u.trim(),description:g.trim(),content:h.trim(),metadata:{color:f,tools:x.length?x:void 0}},r=await(await fetch(`${y}/api/v1/agents/${i}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)})).json();if(!r.success)throw new Error(r.error||"Failed to update agent");const b=r.document.filename.replace(/\.md$/,"");U(`/agents/${b}`)}catch(a){const s=a instanceof Error?a.message:"Failed to update agent";c(s)}finally{A(!1)}};return q?e.jsx("div",{className:"space-y-6",children:e.jsx(N,{children:e.jsx(C,{className:"pt-6",children:"Loading agent..."})})}):d?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Edit Agent"}),e.jsx("p",{className:"text-muted-foreground",children:"Unable to load agent"})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(m,{variant:"ghost",size:"sm",asChild:!0,children:e.jsx(v,{to:`/agents/${i}`,className:"flex items-center gap-1 text-muted-foreground hover:text-foreground transition-colors",children:e.jsx(z,{className:"h-4 w-4"})})})})]}),e.jsx(N,{children:e.jsx(C,{className:"pt-6",children:e.jsx("div",{className:"text-destructive",children:d})})})]}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Edit Agent"}),e.jsxs("p",{className:"text-muted-foreground",children:["File: ",H]})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(m,{variant:"ghost",size:"sm",asChild:!0,children:e.jsx(v,{to:`/agents/${i}`,className:"flex items-center gap-1 text-muted-foreground hover:text-foreground transition-colors",children:e.jsx(z,{className:"h-4 w-4"})})})})]}),e.jsxs(N,{children:[e.jsx(se,{children:e.jsxs(ae,{className:"flex items-center gap-2",children:[e.jsx(O,{className:"h-5 w-5"}),"Agent Configuration"]})}),e.jsx(C,{children:e.jsxs("form",{onSubmit:W,className:"space-y-6",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(l,{htmlFor:"name",children:"Name *"}),e.jsx(D,{id:"name",value:u,onChange:t=>E(t.target.value),disabled:o})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(l,{htmlFor:"description",children:"Description *"}),e.jsx(D,{id:"description",value:g,onChange:t=>F(t.target.value),disabled:o})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(l,{children:"Color"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:G.map(t=>{const a=K[t];return e.jsx("button",{type:"button",onClick:()=>P(t),disabled:o,className:`w-10 h-10 rounded-md border-2 transition-all ${f===t?"ring-2 ring-offset-2 shadow-md":"hover:scale-110 hover:shadow-sm"}`,style:{backgroundColor:a.bg,borderColor:f===t?a.border:"hsl(var(--border))",...f===t&&{"--tw-ring-color":a.border}},title:t,children:e.jsx("span",{className:"sr-only",children:t})},t)})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(l,{htmlFor:"content",children:"Agent Instructions *"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["System prompt or instructions for this agent's behavior."," ","Insert ",e.jsx("code",{className:"text-xs bg-muted px-1.5 py-0.5 rounded font-mono",children:".nut/config.json"})," ",e.jsx("button",{type:"button",onClick:V,className:"inline-flex items-center align-middle text-muted-foreground hover:text-foreground transition-colors",title:"Copy .nut/config.json to clipboard",children:J?e.jsx(oe,{className:"h-3.5 w-3.5 ml-0.5"}):e.jsx(ie,{className:"h-3.5 w-3.5 ml-0.5"})})," ","if you want the agent to be able to access its name, role, or email address."]}),e.jsx(ee,{id:"content",value:h,onChange:t=>$(t.target.value),rows:8,disabled:o,required:!0})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(l,{children:"Tools (Optional)"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Choose which MCP servers this agent should be able to use. Leave empty to inherit all available servers."}),e.jsx("div",{className:"space-y-2",children:_?e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading MCP servers…"}):L.length===0?e.jsx("div",{className:"text-sm text-muted-foreground border border-dashed rounded-md p-3",children:"No MCP servers configured yet. Configure servers in Settings → MCP."}):L.map(t=>e.jsxs("label",{className:"flex items-start gap-3 rounded-md border border-transparent bg-muted/30 px-3 py-2 hover:border-muted transition-colors",children:[e.jsx(te,{checked:x.includes(t.name),onCheckedChange:a=>{k(s=>a===!0?s.includes(t.name)?s:[...s,t.name]:s.filter(r=>r!==t.name))},disabled:o||!t.enabled}),e.jsxs("div",{className:"flex flex-col",children:[e.jsxs("span",{className:"text-sm font-medium",children:[t.name,!t.enabled&&e.jsx(re,{variant:"secondary",className:"ml-2 text-xs",children:"Disabled"})]}),e.jsx("span",{className:"text-xs text-muted-foreground",children:t.enabled?t.description||"Enabled MCP server":"Enable this server in Settings to allow agents to use it"})]})]},t.name))})]}),d&&e.jsx("div",{className:"text-sm text-destructive bg-destructive/10 p-3 rounded-md",children:d}),e.jsxs("div",{className:"flex gap-2 justify-end",children:[e.jsx(m,{type:"button",variant:"outline",asChild:!0,disabled:o,children:e.jsx(v,{to:`/agents/${i}`,children:"Cancel"})}),e.jsx(m,{type:"submit",disabled:o,children:o?"Saving...":"Save Changes"})]})]})})]})]})}export{xe as default};
@@ -1,3 +1,3 @@
1
- import{j as e,S as I,Y as L,r as x,H as O,A as S,n as M,B as b,L as v,i as E,ah as $,ai as _}from"./index-B8vejVRZ.js";import{C as N,a as w,b as D,c as H}from"./card-CvaBJsG6.js";import{B as y}from"./badge-NJasrAx_.js";import{c as U}from"./clipboard-B9ndUJKl.js";import{R as Y,a as G,f as J,L as F}from"./browser-modal-x3ise3M1.js";import{P as T}from"./plus-Bon5P_OK.js";import{T as K}from"./tag--U3Nuedb.js";import"./search-BR37JgJ3.js";const V=["color","tools","createdAt","updatedAt","version","focusAreas","contextPreferences","tags"];function P(t){if(t){if(Array.isArray(t)){const r=t.map(n=>{if(typeof n=="string")return n.trim();if(typeof n=="number")return`${n}`}).filter(n=>typeof n=="string"&&n.length>0);return r.length>0?r:void 0}if(typeof t=="string"){const r=t.split(",").map(n=>n.trim()).filter(n=>n.length>0);return r.length>0?r:void 0}}}function q(t,r){const n=[];if(t.content&&typeof t.content=="object")for(const o of Object.values(t.content))typeof o=="string"&&o.trim().length>0&&n.push(o.trim());const i=[];return i.push(`# ${r}`),t.description?.trim()&&i.push(t.description.trim()),[...i,...n].join(`
1
+ import{j as e,S as I,Y as L,r as x,H as O,A as S,n as M,B as b,L as v,i as E,ah as $,ai as _}from"./index-B0JO3x3V.js";import{C as N,a as w,b as D,c as H}from"./card-B9ym6neB.js";import{B as y}from"./badge-DaM4gF82.js";import{c as U}from"./clipboard-B9ndUJKl.js";import{R as Y,L as F}from"./browser-modal-CyeEbzDK.js";import{R as G,f as J}from"./registry-ANRa5WBi.js";import{P as T}from"./plus-D737EJ5S.js";import{T as K}from"./tag-C_HL28Xd.js";import"./search-cntvIhnF.js";const V=["color","tools","createdAt","updatedAt","version","focusAreas","contextPreferences","tags"];function P(t){if(t){if(Array.isArray(t)){const r=t.map(n=>{if(typeof n=="string")return n.trim();if(typeof n=="number")return`${n}`}).filter(n=>typeof n=="string"&&n.length>0);return r.length>0?r:void 0}if(typeof t=="string"){const r=t.split(",").map(n=>n.trim()).filter(n=>n.length>0);return r.length>0?r:void 0}}}function q(t,r){const n=[];if(t.content&&typeof t.content=="object")for(const o of Object.values(t.content))typeof o=="string"&&o.trim().length>0&&n.push(o.trim());const i=[];return i.push(`# ${r}`),t.description?.trim()&&i.push(t.description.trim()),[...i,...n].join(`
2
2
 
3
- `).trim()}function z(t,r){const n=t.name||r.name,i=r.description||t.description||"",a={registryId:t.id,registryEndpoint:t.endpoint,registrySource:Y,author:t.author};for(const o of V){const d=r[o];if(d!==void 0)if(o==="tools"||o==="focusAreas"||o==="contextPreferences"||o==="tags"){const f=P(d);f&&(a[o]=f)}else a[o]=d}!a.version&&t.version&&(a.version=t.version),a.color||(a.color="blue"),!a.tags&&t.tags&&(a.tags=P(t.tags));for(const[o,d]of Object.entries(a))d==null&&delete a[o];return{name:n,description:i,content:q(r,n),metadata:Object.keys(a).length>0?a:void 0}}function B({open:t,onOpenChange:r,onImport:n}){return e.jsx(G,{open:t,onOpenChange:r,categoryId:"agents",title:"Coconut Registry – Agents",confirmLabel:"Import Agent",getDetail:i=>J(i.endpoint),renderPreview:(i,a)=>{if(!a)return e.jsx("div",{className:"flex h-full items-center justify-center text-muted-foreground",children:"Select an agent to preview"});const o=z(i,a),d=o.metadata??{},f=typeof d.version=="string"?d.version:void 0,u=Array.isArray(i.tags)?i.tags:[],j=Array.isArray(d.tools)?d.tools.filter(l=>typeof l=="string"):[],p=Array.isArray(d.focusAreas)?d.focusAreas.filter(l=>typeof l=="string"):[];return e.jsx("div",{className:"h-full min-h-0 overflow-hidden rounded-md border",children:e.jsx(I,{className:"h-full",children:e.jsxs("div",{className:"space-y-6 p-4",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-2",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold",children:i.name}),e.jsx("p",{className:"text-sm text-muted-foreground",children:a.description})]}),f&&e.jsxs(y,{variant:"outline",children:["v",f]})]}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:["Registry ID: ",e.jsx("span",{className:"font-mono",children:i.id})]}),u.length>0&&e.jsx("div",{className:"flex flex-wrap gap-2",children:u.map(l=>e.jsx(y,{variant:"secondary",children:l},l))}),j.length>0&&e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[e.jsx("span",{className:"font-medium",children:"Tools:"}),j.map(l=>e.jsx(y,{variant:"outline",children:l},l))]}),p.length>0&&e.jsxs("div",{className:"space-y-1",children:[e.jsx("div",{className:"text-sm font-medium",children:"Focus Areas"}),e.jsx("ul",{className:"list-disc pl-5 text-sm text-muted-foreground",children:p.map(l=>e.jsx("li",{children:l},l))})]})]}),e.jsx(L,{className:"[&_.prose]:max-w-none",children:o.content})]})})})},onConfirm:async(i,a)=>{const o=z(i,a);await n({summary:i,detail:a,payload:o})}})}const Q=t=>t?Array.isArray(t)?t.filter(r=>typeof r=="string").map(r=>r.trim()).filter(Boolean):typeof t=="string"?t.split(",").map(r=>r.trim()).filter(Boolean):[]:[],g={blue:{bg:"#dbeafe",border:"#2563eb",text:"#1e40af"},green:{bg:"#dcfce7",border:"#16a34a",text:"#166534"},red:{bg:"#fee2e2",border:"#dc2626",text:"#991b1b"},emerald:{bg:"#d1fae5",border:"#10b981",text:"#047857"},purple:{bg:"#f3e8ff",border:"#9333ea",text:"#6b21a8"},orange:{bg:"#fed7aa",border:"#ea580c",text:"#9a3412"},yellow:{bg:"#fef9c3",border:"#eab308",text:"#854d0e"},teal:{bg:"#ccfbf1",border:"#14b8a6",text:"#0f766e"},indigo:{bg:"#e0e7ff",border:"#6366f1",text:"#4338ca"},pink:{bg:"#fce7f3",border:"#ec4899",text:"#9f1239"},cyan:{bg:"#cffafe",border:"#06b6d4",text:"#155e75"},slate:{bg:"#f1f5f9",border:"#475569",text:"#334155"},gray:{bg:"#f3f4f6",border:"#6b7280",text:"#374151"}};function oe(){const[t,r]=x.useState([]),[n,i]=x.useState(!0),[a,o]=x.useState({}),[d,f]=x.useState(!1),[u,j]=x.useState(!1),{toast:p}=O(),l=x.useCallback(async()=>{i(!0);try{const s=await fetch(`${S}/api/v1/agents`);if(!s.ok)throw new Error("Failed to load agents");const m=await s.json();r(Array.isArray(m.documents)?m.documents:[])}catch(s){console.error("Failed to load agents:",s),r([])}finally{i(!1)}},[]);x.useEffect(()=>{l()},[l]);const A=async s=>{const m=`.nut/agents/${s}`;try{await U(m),o(c=>({...c,[s]:!0})),setTimeout(()=>{o(c=>({...c,[s]:!1}))},2e3),p({title:"Path copied!",description:`Copied ${m} to clipboard`})}catch(c){console.error("Failed to copy path:",c),p({title:"Failed to copy",description:"Unable to copy path to clipboard",variant:"destructive"})}},C=x.useCallback(async({payload:s})=>{let m=!1;j(!0);try{const c=await fetch(`${S}/api/v1/agents`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:s.name,description:s.description,content:s.content,metadata:s.metadata})});let h=null;try{h=await c.json()}catch(k){console.error("Failed to parse registry import response:",k)}if(!(c.ok&&h?.success)){const R=(typeof h?.error=="string"?h.error:h?.error?.message)||c.statusText||"Failed to import agent from registry";throw p({title:"Failed to import agent",description:R,variant:"destructive"}),m=!0,new Error(R)}p({title:"Agent imported",description:`${s.name} is now available in Coconut`}),await l()}catch(c){if(!m){const h=c instanceof Error&&c.message?c.message:"Failed to import agent from registry";p({title:"Failed to import agent",description:h,variant:"destructive"})}throw c}finally{j(!1)}},[l,p]);return n?e.jsx("div",{className:"space-y-6",children:e.jsx(N,{children:e.jsx(w,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center justify-center",children:[e.jsx(M,{className:"h-8 w-8 animate-spin text-muted-foreground"}),e.jsx("span",{className:"ml-2 text-muted-foreground",children:"Loading agents..."})]})})})}):t.length===0?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"mb-6 flex items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold tracking-tight",children:"Agents"}),e.jsx("p",{className:"text-muted-foreground",children:"Manage agents for your development workflows"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(b,{variant:"outline",size:"sm",onClick:()=>f(!0),disabled:u,children:[e.jsx(F,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Registry"})]}),e.jsx(b,{size:"sm",asChild:!0,children:e.jsxs(v,{to:"/agents/new",children:[e.jsx(T,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Create New"})]})})]})]}),e.jsx(N,{children:e.jsx(w,{className:"pt-6",children:e.jsxs("div",{className:"text-center",children:[e.jsx(E,{className:"mx-auto h-12 w-12 text-muted-foreground"}),e.jsx("h3",{className:"mt-4 text-lg font-semibold",children:"No Agents Found"}),e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:"Specialized agents help you automate your development and business workflows."})]})})})]}),e.jsx(B,{open:d,onOpenChange:f,onImport:C})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold tracking-tight",children:"Agents"}),e.jsx("p",{className:"text-muted-foreground",children:"Manage agents for your development workflows"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(b,{variant:"outline",size:"sm",onClick:()=>f(!0),disabled:u,children:[e.jsx(F,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Registry"})]}),e.jsx(b,{size:"sm",asChild:!0,children:e.jsxs(v,{to:"/agents/new",children:[e.jsx(T,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Create New"})]})})]})]}),e.jsx("div",{className:"grid gap-4",children:t.map(s=>{const m=Q(s.metadata.tools);return e.jsx(v,{to:`/agents/${s.filename.replace(".md","")}`,className:"block",children:e.jsxs(N,{className:"group hover:shadow-md hover:bg-muted/30 transition-all cursor-pointer",children:[e.jsx(D,{children:e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"space-y-1 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(H,{className:"text-lg",children:s.title}),e.jsx(b,{variant:"ghost",size:"sm",onClick:c=>{c.preventDefault(),A(s.filename)},className:"h-6 w-6 p-0 hover:bg-muted opacity-0 group-hover:opacity-100 transition-opacity",title:"Copy file path to clipboard",children:a[s.filename]?e.jsx($,{className:"w-3 h-3 text-green-600"}):e.jsx(_,{className:"w-3 h-3"})})]}),e.jsxs("div",{className:"text-xs text-muted-foreground font-mono bg-muted/50 px-2 py-1 rounded inline-block cursor-pointer hover:bg-muted/70 transition-colors",onClick:c=>{c.preventDefault(),A(s.filename)},title:"Click to copy file path to clipboard",children:[".nut/agents/",s.filename]}),e.jsxs("div",{className:"flex items-center gap-4 text-sm text-muted-foreground",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(K,{className:"w-3 h-3"}),s.metadata.color||"blue"]}),m.length>0&&e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(E,{className:"w-3 h-3"}),m.join(", ")]})]})]}),s.metadata.color&&e.jsx(y,{variant:"outline",className:"capitalize border-2",style:{backgroundColor:g[s.metadata.color]?.bg||g.blue.bg,color:g[s.metadata.color]?.text||g.blue.text,borderColor:g[s.metadata.color]?.border||g.blue.border},children:s.metadata.color})]})}),e.jsx(w,{children:e.jsx("div",{className:"space-y-4",children:e.jsx("div",{className:"prose prose-sm max-w-none dark:prose-invert",children:e.jsx("p",{className:"text-sm text-muted-foreground line-clamp-2",children:s.metadata.description})})})})]})},s.filename)})})]}),e.jsx(B,{open:d,onOpenChange:f,onImport:C})]})}export{oe as default};
3
+ `).trim()}function z(t,r){const n=t.name||r.name,i=r.description||t.description||"",a={registryId:t.id,registryEndpoint:t.endpoint,registrySource:G,author:t.author};for(const o of V){const d=r[o];if(d!==void 0)if(o==="tools"||o==="focusAreas"||o==="contextPreferences"||o==="tags"){const f=P(d);f&&(a[o]=f)}else a[o]=d}!a.version&&t.version&&(a.version=t.version),a.color||(a.color="blue"),!a.tags&&t.tags&&(a.tags=P(t.tags));for(const[o,d]of Object.entries(a))d==null&&delete a[o];return{name:n,description:i,content:q(r,n),metadata:Object.keys(a).length>0?a:void 0}}function B({open:t,onOpenChange:r,onImport:n}){return e.jsx(Y,{open:t,onOpenChange:r,categoryId:"agents",title:"Coconut Registry – Agents",confirmLabel:"Import Agent",getDetail:i=>J(i.endpoint),renderPreview:(i,a)=>{if(!a)return e.jsx("div",{className:"flex h-full items-center justify-center text-muted-foreground",children:"Select an agent to preview"});const o=z(i,a),d=o.metadata??{},f=typeof d.version=="string"?d.version:void 0,u=Array.isArray(i.tags)?i.tags:[],j=Array.isArray(d.tools)?d.tools.filter(l=>typeof l=="string"):[],p=Array.isArray(d.focusAreas)?d.focusAreas.filter(l=>typeof l=="string"):[];return e.jsx("div",{className:"h-full min-h-0 overflow-hidden rounded-md border",children:e.jsx(I,{className:"h-full",children:e.jsxs("div",{className:"space-y-6 p-4",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-2",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold",children:i.name}),e.jsx("p",{className:"text-sm text-muted-foreground",children:a.description})]}),f&&e.jsxs(y,{variant:"outline",children:["v",f]})]}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:["Registry ID: ",e.jsx("span",{className:"font-mono",children:i.id})]}),u.length>0&&e.jsx("div",{className:"flex flex-wrap gap-2",children:u.map(l=>e.jsx(y,{variant:"secondary",children:l},l))}),j.length>0&&e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm",children:[e.jsx("span",{className:"font-medium",children:"Tools:"}),j.map(l=>e.jsx(y,{variant:"outline",children:l},l))]}),p.length>0&&e.jsxs("div",{className:"space-y-1",children:[e.jsx("div",{className:"text-sm font-medium",children:"Focus Areas"}),e.jsx("ul",{className:"list-disc pl-5 text-sm text-muted-foreground",children:p.map(l=>e.jsx("li",{children:l},l))})]})]}),e.jsx(L,{className:"[&_.prose]:max-w-none",children:o.content})]})})})},onConfirm:async(i,a)=>{const o=z(i,a);await n({summary:i,detail:a,payload:o})}})}const Q=t=>t?Array.isArray(t)?t.filter(r=>typeof r=="string").map(r=>r.trim()).filter(Boolean):typeof t=="string"?t.split(",").map(r=>r.trim()).filter(Boolean):[]:[],g={blue:{bg:"#dbeafe",border:"#2563eb",text:"#1e40af"},green:{bg:"#dcfce7",border:"#16a34a",text:"#166534"},red:{bg:"#fee2e2",border:"#dc2626",text:"#991b1b"},emerald:{bg:"#d1fae5",border:"#10b981",text:"#047857"},purple:{bg:"#f3e8ff",border:"#9333ea",text:"#6b21a8"},orange:{bg:"#fed7aa",border:"#ea580c",text:"#9a3412"},yellow:{bg:"#fef9c3",border:"#eab308",text:"#854d0e"},teal:{bg:"#ccfbf1",border:"#14b8a6",text:"#0f766e"},indigo:{bg:"#e0e7ff",border:"#6366f1",text:"#4338ca"},pink:{bg:"#fce7f3",border:"#ec4899",text:"#9f1239"},cyan:{bg:"#cffafe",border:"#06b6d4",text:"#155e75"},slate:{bg:"#f1f5f9",border:"#475569",text:"#334155"},gray:{bg:"#f3f4f6",border:"#6b7280",text:"#374151"}};function ie(){const[t,r]=x.useState([]),[n,i]=x.useState(!0),[a,o]=x.useState({}),[d,f]=x.useState(!1),[u,j]=x.useState(!1),{toast:p}=O(),l=x.useCallback(async()=>{i(!0);try{const s=await fetch(`${S}/api/v1/agents`);if(!s.ok)throw new Error("Failed to load agents");const m=await s.json();r(Array.isArray(m.documents)?m.documents:[])}catch(s){console.error("Failed to load agents:",s),r([])}finally{i(!1)}},[]);x.useEffect(()=>{l()},[l]);const A=async s=>{const m=`.nut/agents/${s}`;try{await U(m),o(c=>({...c,[s]:!0})),setTimeout(()=>{o(c=>({...c,[s]:!1}))},2e3),p({title:"Path copied!",description:`Copied ${m} to clipboard`})}catch(c){console.error("Failed to copy path:",c),p({title:"Failed to copy",description:"Unable to copy path to clipboard",variant:"destructive"})}},C=x.useCallback(async({payload:s})=>{let m=!1;j(!0);try{const c=await fetch(`${S}/api/v1/agents`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:s.name,description:s.description,content:s.content,metadata:s.metadata})});let h=null;try{h=await c.json()}catch(k){console.error("Failed to parse registry import response:",k)}if(!(c.ok&&h?.success)){const R=(typeof h?.error=="string"?h.error:h?.error?.message)||c.statusText||"Failed to import agent from registry";throw p({title:"Failed to import agent",description:R,variant:"destructive"}),m=!0,new Error(R)}p({title:"Agent imported",description:`${s.name} is now available in Coconut`}),await l()}catch(c){if(!m){const h=c instanceof Error&&c.message?c.message:"Failed to import agent from registry";p({title:"Failed to import agent",description:h,variant:"destructive"})}throw c}finally{j(!1)}},[l,p]);return n?e.jsx("div",{className:"space-y-6",children:e.jsx(N,{children:e.jsx(w,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center justify-center",children:[e.jsx(M,{className:"h-8 w-8 animate-spin text-muted-foreground"}),e.jsx("span",{className:"ml-2 text-muted-foreground",children:"Loading agents..."})]})})})}):t.length===0?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"mb-6 flex items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold tracking-tight",children:"Agents"}),e.jsx("p",{className:"text-muted-foreground",children:"Manage agents for your development workflows"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(b,{variant:"outline",size:"sm",onClick:()=>f(!0),disabled:u,children:[e.jsx(F,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Registry"})]}),e.jsx(b,{size:"sm",asChild:!0,children:e.jsxs(v,{to:"/agents/new",children:[e.jsx(T,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Create New"})]})})]})]}),e.jsx(N,{children:e.jsx(w,{className:"pt-6",children:e.jsxs("div",{className:"text-center",children:[e.jsx(E,{className:"mx-auto h-12 w-12 text-muted-foreground"}),e.jsx("h3",{className:"mt-4 text-lg font-semibold",children:"No Agents Found"}),e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:"Specialized agents help you automate your development and business workflows."})]})})})]}),e.jsx(B,{open:d,onOpenChange:f,onImport:C})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold tracking-tight",children:"Agents"}),e.jsx("p",{className:"text-muted-foreground",children:"Manage agents for your development workflows"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(b,{variant:"outline",size:"sm",onClick:()=>f(!0),disabled:u,children:[e.jsx(F,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Registry"})]}),e.jsx(b,{size:"sm",asChild:!0,children:e.jsxs(v,{to:"/agents/new",children:[e.jsx(T,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Create New"})]})})]})]}),e.jsx("div",{className:"grid gap-4",children:t.map(s=>{const m=Q(s.metadata.tools);return e.jsx(v,{to:`/agents/${s.filename.replace(".md","")}`,className:"block",children:e.jsxs(N,{className:"group hover:shadow-md hover:bg-muted/30 transition-all cursor-pointer",children:[e.jsx(D,{children:e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"space-y-1 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(H,{className:"text-lg",children:s.title}),e.jsx(b,{variant:"ghost",size:"sm",onClick:c=>{c.preventDefault(),A(s.filename)},className:"h-6 w-6 p-0 hover:bg-muted opacity-0 group-hover:opacity-100 transition-opacity",title:"Copy file path to clipboard",children:a[s.filename]?e.jsx($,{className:"w-3 h-3 text-green-600"}):e.jsx(_,{className:"w-3 h-3"})})]}),e.jsxs("div",{className:"text-xs text-muted-foreground font-mono bg-muted/50 px-2 py-1 rounded inline-block cursor-pointer hover:bg-muted/70 transition-colors",onClick:c=>{c.preventDefault(),A(s.filename)},title:"Click to copy file path to clipboard",children:[".nut/agents/",s.filename]}),e.jsxs("div",{className:"flex items-center gap-4 text-sm text-muted-foreground",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(K,{className:"w-3 h-3"}),s.metadata.color||"blue"]}),m.length>0&&e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(E,{className:"w-3 h-3"}),m.join(", ")]})]})]}),s.metadata.color&&e.jsx(y,{variant:"outline",className:"capitalize border-2",style:{backgroundColor:g[s.metadata.color]?.bg||g.blue.bg,color:g[s.metadata.color]?.text||g.blue.text,borderColor:g[s.metadata.color]?.border||g.blue.border},children:s.metadata.color})]})}),e.jsx(w,{children:e.jsx("div",{className:"space-y-4",children:e.jsx("div",{className:"prose prose-sm max-w-none dark:prose-invert",children:e.jsx("p",{className:"text-sm text-muted-foreground line-clamp-2",children:s.metadata.description})})})})]})},s.filename)})})]}),e.jsx(B,{open:d,onOpenChange:f,onImport:C})]})}export{ie as default};
@@ -1,4 +1,4 @@
1
- import{c as b,j as e,a1 as w,B as t,ad as C,T as A,I as r,v as l,w as c,x as d,y as o,z as i}from"./index-B8vejVRZ.js";import{C as x,b as m,c as u,d as h,a as j}from"./card-CvaBJsG6.js";import{L as a}from"./label-DtNTh--4.js";import{B as n}from"./badge-NJasrAx_.js";import{P as S}from"./plus-Bon5P_OK.js";import{P as p}from"./pause-COIsHZIp.js";import{P as R}from"./play-a8BsF4gF.js";import{Z as T}from"./zap-C0eIGEl_.js";/**
1
+ import{c as b,j as e,a1 as w,B as t,ad as C,T as A,I as r,v as l,w as c,x as d,y as o,z as i}from"./index-B0JO3x3V.js";import{C as x,b as m,c as u,d as h,a as j}from"./card-B9ym6neB.js";import{L as a}from"./label-BHOOQ99D.js";import{B as n}from"./badge-DaM4gF82.js";import{P as S}from"./plus-D737EJ5S.js";import{P as p}from"./pause-DqQ7Twc6.js";import{P as R}from"./play-Y2N8OVBu.js";import{Z as T}from"./zap-CrLPiVyl.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.