@lovelybunch/api 1.0.71-alpha.4 → 1.0.71-alpha.6

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 (97) 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/generate-video/index.d.ts +3 -0
  11. package/dist/routes/api/v1/resources/generate-video/index.js +5 -0
  12. package/dist/routes/api/v1/resources/generate-video/route.d.ts +19 -0
  13. package/dist/routes/api/v1/resources/generate-video/route.js +235 -0
  14. package/dist/routes/api/v1/resources/index.js +4 -0
  15. package/dist/routes/api/v1/resources/route.js +3 -3
  16. package/package.json +4 -4
  17. package/static/assets/{AgentDetailPage-BkWRFbPj.js → AgentDetailPage-Bw8wHgla.js} +1 -1
  18. package/static/assets/{AgentEditPage-DN0TouUG.js → AgentEditPage-CQ9Y3ez8.js} +1 -1
  19. package/static/assets/{AgentsPage-DW6eV7oU.js → AgentsPage-DcgU1MPa.js} +1 -1
  20. package/static/assets/{AgentsSettingsPage-BJKnn0R0.js → AgentsSettingsPage-CgoXxqGL.js} +1 -1
  21. package/static/assets/{ApiKeysSettingsPage-ChFu9Eo6.js → ApiKeysSettingsPage-BgqGOa4p.js} +3 -3
  22. package/static/assets/{ArchitectureEditPage-DWrvSS5U.js → ArchitectureEditPage-DrEnTloL.js} +1 -1
  23. package/static/assets/{ArchitecturePage-BdQG779E.js → ArchitecturePage-Dpd6cyyT.js} +1 -1
  24. package/static/assets/{AuthSettingsPage-BXMn4xXd.js → AuthSettingsPage-wu1zFEx-.js} +2 -2
  25. package/static/assets/{CallbackPage-AxQqTxCV.js → CallbackPage-DYzikcPp.js} +1 -1
  26. package/static/assets/{CodePage-CfKZ52Zo.js → CodePage-CtM-PEHU.js} +1 -1
  27. package/static/assets/{CollapsibleSection-ZFq6LSXW.js → CollapsibleSection-B23j-nZD.js} +1 -1
  28. package/static/assets/{DashboardPage-Df-d3-fG.js → DashboardPage-BoPCq6M9.js} +1 -1
  29. package/static/assets/{GitPage-DAWR8rrg.js → GitPage-DYicFQBx.js} +1 -1
  30. package/static/assets/{GitSettingsPage-CzGuiY9j.js → GitSettingsPage-B-1Nnid8.js} +2 -2
  31. package/static/assets/{IdentityPage-DbsNwWtP.js → IdentityPage-Cvj6SDPj.js} +2 -2
  32. package/static/assets/{ImplementationStepsEditor-DZq7KcDP.js → ImplementationStepsEditor-CCfJKk2U.js} +1 -1
  33. package/static/assets/{IntegrationsSettingsPage-qvvsp1_G.js → IntegrationsSettingsPage-BgLXCF-u.js} +1 -1
  34. package/static/assets/{KnowledgeDetailPage-BMnj1qiH.js → KnowledgeDetailPage-I9erHJXN.js} +1 -1
  35. package/static/assets/{KnowledgeEditPage-BZa4E2M9.js → KnowledgeEditPage-BfaWotPl.js} +1 -1
  36. package/static/assets/{KnowledgePage-Dtq9BKZi.js → KnowledgePage-x9ShzjoT.js} +2 -2
  37. package/static/assets/{LoginPage-BnlCd8Cm.js → LoginPage-CZtwhbdN.js} +1 -1
  38. package/static/assets/{McpSettingsPage-COPMqimV.js → McpSettingsPage-BHPjMqOX.js} +1 -1
  39. package/static/assets/{NewAgentPage-Dtvey1oU.js → NewAgentPage-D-Pj_KgZ.js} +1 -1
  40. package/static/assets/{NewKnowledgePage-CbiRD2V3.js → NewKnowledgePage-CoVnCUx6.js} +1 -1
  41. package/static/assets/{NewProposalPage-B1tUJIZz.js → NewProposalPage-nCTq2mBC.js} +1 -1
  42. package/static/assets/{ProjectEditPage-CwM8LXHy.js → ProjectEditPage-d1cMZArt.js} +1 -1
  43. package/static/assets/{ProjectPage-BHa8M3vI.js → ProjectPage-KwwOjk5b.js} +1 -1
  44. package/static/assets/{PromptsSettingsPage-CwGmsIAW.js → PromptsSettingsPage-fSs6HBAk.js} +1 -1
  45. package/static/assets/{ProposalDetailPage-DC7NMuFi.js → ProposalDetailPage-BnLOBPPT.js} +1 -1
  46. package/static/assets/{ProposalEditPage-CfUidv6D.js → ProposalEditPage-bIYTFTmG.js} +1 -1
  47. package/static/assets/{ProposalsPage-V8ut_TsU.js → ProposalsPage-D8W2d6g6.js} +1 -1
  48. package/static/assets/ResourcesPage-Dq9DZFd7.js +71 -0
  49. package/static/assets/{RulesSettingsPage-BJ72X2Y3.js → RulesSettingsPage-SWRxKVNH.js} +1 -1
  50. package/static/assets/{SchedulePage-DBYxTZMb.js → SchedulePage-DGxD8ZaL.js} +1 -1
  51. package/static/assets/{TagInput-Cqju3cXZ.js → TagInput-CYcNHzrk.js} +1 -1
  52. package/static/assets/{TerminalPage-Iow1ciWG.js → TerminalPage-fabajZvk.js} +1 -1
  53. package/static/assets/{TerminalSessionPage-CZdzhFhY.js → TerminalSessionPage-DuJsKT9f.js} +1 -1
  54. package/static/assets/{UserPreferencesPage-CAuJ7yO4.js → UserPreferencesPage-DQMtobsK.js} +1 -1
  55. package/static/assets/{UserSettingsPage-0j7ha-RI.js → UserSettingsPage-CFEb7pD0.js} +1 -1
  56. package/static/assets/{UtilitiesPage-OgkcmaOS.js → UtilitiesPage-qStPGLN_.js} +1 -1
  57. package/static/assets/{alert-D2VTq6m-.js → alert-Baaj8mli.js} +1 -1
  58. package/static/assets/{arrow-down-vmWOjyjO.js → arrow-down-CSpiROUo.js} +1 -1
  59. package/static/assets/{arrow-left-Do2jUSS9.js → arrow-left-CdJt7_wH.js} +1 -1
  60. package/static/assets/{arrow-up-hMM1cdZm.js → arrow-up-ugn3lusK.js} +1 -1
  61. package/static/assets/{badge-D7ZZbMEG.js → badge-fHjW-wEe.js} +1 -1
  62. package/static/assets/{browser-modal-CWDhylx7.js → browser-modal-D6BB5mxm.js} +1 -1
  63. package/static/assets/{calendar-C5JtKp_F.js → calendar-DXMWQL-h.js} +1 -1
  64. package/static/assets/{card-D_zGBKua.js → card-C9ekeZtD.js} +1 -1
  65. package/static/assets/{chevron-left-JjvWea8A.js → chevron-left-BkP_F3xd.js} +1 -1
  66. package/static/assets/{circle-alert-DQD0CPB3.js → circle-alert-DnIYekt3.js} +1 -1
  67. package/static/assets/{circle-check-xj41FKuF.js → circle-check-BO-qmBFl.js} +1 -1
  68. package/static/assets/{circle-check-big-KfJvKA9H.js → circle-check-big-BUVglreY.js} +1 -1
  69. package/static/assets/{circle-play-BlGnYWUU.js → circle-play-84ZOWBDG.js} +1 -1
  70. package/static/assets/{circle-x-Ds97aY1x.js → circle-x-EQNlLpRR.js} +1 -1
  71. package/static/assets/{clipboard-D3NA8gb4.js → clipboard-Dv0iwZO9.js} +1 -1
  72. package/static/assets/{clock-9dU_D6sL.js → clock-BxO7xcX9.js} +1 -1
  73. package/static/assets/{download-CNckZYWh.js → download-CpaVC4DU.js} +1 -1
  74. package/static/assets/{eye-Dp6wEoME.js → eye-BSR7OEmk.js} +1 -1
  75. package/static/assets/{folder-git-2-B9ILjFN2.js → folder-git-2-9fWvFiHp.js} +1 -1
  76. package/static/assets/index-BAEEeZzi.js +458 -0
  77. package/static/assets/index-DdGUrKz8.css +2 -0
  78. package/static/assets/label-CRsu1MwQ.js +1 -0
  79. package/static/assets/{markdown-editor-BiM9h5iI.js → markdown-editor-Dop22vuJ.js} +1 -1
  80. package/static/assets/{pause-BNL49HvB.js → pause-C7KYrzQF.js} +1 -1
  81. package/static/assets/{play-8b83f5X0.js → play-DhUf2mKM.js} +1 -1
  82. package/static/assets/{plus-Be79gWKj.js → plus-CemYz5Fm.js} +1 -1
  83. package/static/assets/radio-group-Dz2cO4IQ.js +1 -0
  84. package/static/assets/{refresh-cw-C0_Ot2Zc.js → refresh-cw-BL3y7jJo.js} +1 -1
  85. package/static/assets/{search-CrIdR7ah.js → search-BvRo_rak.js} +1 -1
  86. package/static/assets/{switch-BYPAX9oF.js → switch-CDOrVL8G.js} +1 -1
  87. package/static/assets/{tabs-Ug7Ug5Ha.js → tabs-CP_A6r0A.js} +1 -1
  88. package/static/assets/{tag-BgO5mxYK.js → tag-BpNIhvRX.js} +1 -1
  89. package/static/assets/{terminal-preview-CDrLQbSE.js → terminal-preview-CbgoHEQH.js} +1 -1
  90. package/static/assets/{use-terminal-CNk4WtA6.js → use-terminal-ZvK-kdxE.js} +1 -1
  91. package/static/assets/{zap-cD8GAJPg.js → zap-DOtH7YrV.js} +1 -1
  92. package/static/index.html +2 -2
  93. package/static/assets/ResourcesPage-Cofgbx3H.js +0 -66
  94. package/static/assets/index-Bbxvuj4b.js +0 -458
  95. package/static/assets/index-Ca98xZVe.css +0 -2
  96. package/static/assets/label-CZGCmBD7.js +0 -1
  97. package/static/assets/radio-group-DpxssBzw.js +0 -1
@@ -0,0 +1,235 @@
1
+ import Replicate from 'replicate';
2
+ import { promises as fs } from 'fs';
3
+ import path from 'path';
4
+ import { homedir } from 'os';
5
+ import { existsSync, readFileSync } from 'fs';
6
+ /**
7
+ * Get Replicate API token from global config or environment variable
8
+ */
9
+ function getReplicateApiToken() {
10
+ // First try global config
11
+ try {
12
+ const platform = process.platform;
13
+ let configDir;
14
+ if (platform === 'win32') {
15
+ configDir = path.join(process.env.APPDATA || homedir(), 'coconuts');
16
+ }
17
+ else if (platform === 'darwin') {
18
+ configDir = path.join(homedir(), 'Library', 'Application Support', 'coconuts');
19
+ }
20
+ else {
21
+ configDir = path.join(process.env.XDG_CONFIG_HOME || path.join(homedir(), '.config'), 'coconuts');
22
+ }
23
+ const configPath = path.join(configDir, 'config.json');
24
+ if (existsSync(configPath)) {
25
+ const config = JSON.parse(readFileSync(configPath, 'utf-8'));
26
+ if (config.apiKeys?.replicate) {
27
+ return config.apiKeys.replicate;
28
+ }
29
+ }
30
+ }
31
+ catch (error) {
32
+ console.warn('Failed to load Replicate token from config:', error);
33
+ }
34
+ // Fallback to environment variable
35
+ return process.env.REPLICATE_API_TOKEN || null;
36
+ }
37
+ // Initialize Replicate client lazily to ensure token is loaded at request time
38
+ function getReplicateClient() {
39
+ const token = getReplicateApiToken();
40
+ if (!token) {
41
+ throw new Error('Replicate API token not configured');
42
+ }
43
+ return new Replicate({
44
+ auth: token,
45
+ });
46
+ }
47
+ function getResourcesPath() {
48
+ let basePath;
49
+ if (process.env.NODE_ENV === 'development' && process.env.GAIT_DEV_ROOT) {
50
+ basePath = process.env.GAIT_DEV_ROOT;
51
+ }
52
+ else if (process.env.GAIT_DATA_PATH) {
53
+ basePath = path.resolve(process.env.GAIT_DATA_PATH, '.nut');
54
+ }
55
+ else {
56
+ basePath = path.resolve(process.cwd(), '.nut');
57
+ }
58
+ return path.join(basePath, 'resources');
59
+ }
60
+ const RESOURCES_DIR = getResourcesPath();
61
+ const FILES_DIR = path.join(RESOURCES_DIR, 'files');
62
+ const METADATA_DIR = path.join(RESOURCES_DIR, 'metadata');
63
+ const THUMBNAILS_DIR = path.join(RESOURCES_DIR, 'thumbnails');
64
+ async function getResourceMetadata(id) {
65
+ try {
66
+ const metadataPath = path.join(METADATA_DIR, `${id}.json`);
67
+ const content = await fs.readFile(metadataPath, 'utf-8');
68
+ return JSON.parse(content);
69
+ }
70
+ catch (error) {
71
+ if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT')
72
+ return null;
73
+ throw error;
74
+ }
75
+ }
76
+ function extractResourceId(imageRef) {
77
+ if (typeof imageRef !== 'string')
78
+ return null;
79
+ // Allow direct resource IDs or URLs containing the ID
80
+ const directMatch = imageRef.match(/^(res-[A-Za-z0-9-]+)/);
81
+ if (directMatch && directMatch[1]) {
82
+ return directMatch[1];
83
+ }
84
+ const urlMatch = imageRef.match(/\/resources\/([^/?]+)/);
85
+ if (urlMatch && urlMatch[1]) {
86
+ return urlMatch[1];
87
+ }
88
+ return null;
89
+ }
90
+ async function uploadResourceToReplicate(resourceId) {
91
+ const resource = await getResourceMetadata(resourceId);
92
+ if (!resource) {
93
+ console.warn(`Resource metadata not found for id ${resourceId}`);
94
+ return null;
95
+ }
96
+ const candidatePaths = [];
97
+ if (resource.path) {
98
+ candidatePaths.push(path.join(FILES_DIR, resource.path));
99
+ }
100
+ if (resource.thumbnailPath) {
101
+ candidatePaths.push(path.join(THUMBNAILS_DIR, resource.thumbnailPath));
102
+ }
103
+ let filePath = null;
104
+ for (const candidate of candidatePaths) {
105
+ try {
106
+ await fs.access(candidate);
107
+ filePath = candidate;
108
+ break;
109
+ }
110
+ catch {
111
+ // Try next candidate
112
+ }
113
+ }
114
+ if (!filePath) {
115
+ console.warn(`No accessible file found for resource ${resourceId}`);
116
+ return null;
117
+ }
118
+ const fileBuffer = await fs.readFile(filePath);
119
+ const replicateClient = getReplicateClient();
120
+ const uploadedFile = await replicateClient.files.create(fileBuffer, {
121
+ resourceId,
122
+ originalName: resource.name,
123
+ });
124
+ const fileUrl = uploadedFile?.urls?.get;
125
+ if (!fileUrl) {
126
+ console.warn(`Replicate file upload did not return a URL for resource ${resourceId}`);
127
+ return null;
128
+ }
129
+ return fileUrl;
130
+ }
131
+ export async function POST(c) {
132
+ try {
133
+ // Check if Replicate API token is configured
134
+ const replicateToken = getReplicateApiToken();
135
+ if (!replicateToken) {
136
+ return c.json({
137
+ success: false,
138
+ error: {
139
+ code: 'MISSING_API_TOKEN',
140
+ message: 'Replicate API token not configured. Please add it in Settings → Integrations.'
141
+ }
142
+ }, 400);
143
+ }
144
+ const body = await c.req.json();
145
+ const { prompt, image, last_frame, duration = 8, resolution = '720p', aspect_ratio = '16:9', generate_audio = true } = body;
146
+ if (!prompt || !prompt.trim()) {
147
+ return c.json({
148
+ success: false,
149
+ error: {
150
+ code: 'MISSING_PROMPT',
151
+ message: 'Prompt is required for video generation'
152
+ }
153
+ }, 400);
154
+ }
155
+ // Build input for google/veo-3.1-fast
156
+ const input = {
157
+ prompt: prompt.trim(),
158
+ duration,
159
+ resolution,
160
+ aspect_ratio,
161
+ generate_audio
162
+ };
163
+ // Upload start frame if provided
164
+ if (image) {
165
+ const resourceId = extractResourceId(image);
166
+ if (resourceId) {
167
+ try {
168
+ const imageUrl = await uploadResourceToReplicate(resourceId);
169
+ if (imageUrl) {
170
+ input.image = imageUrl;
171
+ }
172
+ }
173
+ catch (error) {
174
+ console.error(`Error uploading start frame ${image}:`, error);
175
+ }
176
+ }
177
+ }
178
+ // Upload end frame if provided
179
+ if (last_frame) {
180
+ const resourceId = extractResourceId(last_frame);
181
+ if (resourceId) {
182
+ try {
183
+ const lastFrameUrl = await uploadResourceToReplicate(resourceId);
184
+ if (lastFrameUrl) {
185
+ input.last_frame = lastFrameUrl;
186
+ }
187
+ }
188
+ catch (error) {
189
+ console.error(`Error uploading end frame ${last_frame}:`, error);
190
+ }
191
+ }
192
+ }
193
+ // Run the model
194
+ const replicateClient = getReplicateClient();
195
+ const output = await replicateClient.run('google/veo-3.1-fast', { input });
196
+ // Extract URL from output
197
+ let videoUrl;
198
+ if (typeof output === 'string') {
199
+ videoUrl = output;
200
+ }
201
+ else if (output && typeof output === 'object') {
202
+ // Check for url() method (FileOutput object)
203
+ const outputObj = output;
204
+ if (typeof outputObj.url === 'function') {
205
+ videoUrl = outputObj.url();
206
+ }
207
+ else if ('url' in outputObj && typeof outputObj.url === 'string') {
208
+ videoUrl = outputObj.url;
209
+ }
210
+ else {
211
+ throw new Error('Unexpected output format from Replicate');
212
+ }
213
+ }
214
+ else {
215
+ throw new Error('Unexpected output format from Replicate');
216
+ }
217
+ return c.json({
218
+ success: true,
219
+ data: {
220
+ videoUrl
221
+ }
222
+ });
223
+ }
224
+ catch (error) {
225
+ console.error('Error generating video:', error);
226
+ const message = error instanceof Error ? error.message : 'Failed to generate video';
227
+ return c.json({
228
+ success: false,
229
+ error: {
230
+ code: 'GENERATION_ERROR',
231
+ message
232
+ }
233
+ }, 500);
234
+ }
235
+ }
@@ -1,8 +1,12 @@
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';
5
+ import generateVideo from './generate-video/index.js';
4
6
  const app = new Hono();
5
7
  app.get('/', GET);
6
8
  app.post('/', POST);
7
9
  app.route('/generate', generate);
10
+ app.route('/generate-audio', generateAudio);
11
+ app.route('/generate-video', generateVideo);
8
12
  export default app;
@@ -69,10 +69,10 @@ async function generateThumbnail(imageBuffer, id, mimeType) {
69
69
  const thumbnailName = `${id}_thumb.jpg`;
70
70
  const thumbnailPath = path.join(THUMBNAILS_DIR, thumbnailName);
71
71
  try {
72
- // Resize to max 300x300 (2x retina for 128px UI display), preserve aspect ratio
72
+ // Resize to max 640x640 (5x retina for 128px UI display), preserve aspect ratio
73
73
  await sharp(imageBuffer)
74
- .resize(300, 300, { fit: 'inside', withoutEnlargement: true })
75
- .jpeg({ quality: 80 })
74
+ .resize(640, 640, { fit: 'inside', withoutEnlargement: true })
75
+ .jpeg({ quality: 85 })
76
76
  .toFile(thumbnailPath);
77
77
  return thumbnailName;
78
78
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovelybunch/api",
3
- "version": "1.0.71-alpha.4",
3
+ "version": "1.0.71-alpha.6",
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.4",
40
- "@lovelybunch/mcp": "^1.0.71-alpha.4",
41
- "@lovelybunch/types": "^1.0.71-alpha.4",
39
+ "@lovelybunch/core": "^1.0.71-alpha.6",
40
+ "@lovelybunch/mcp": "^1.0.71-alpha.6",
41
+ "@lovelybunch/types": "^1.0.71-alpha.6",
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-Bbxvuj4b.js";import{C as l,b as o,a as m,c as f,d as z}from"./card-D_zGBKua.js";import{B as v}from"./badge-D7ZZbMEG.js";import{A as u}from"./arrow-left-Do2jUSS9.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-BAEEeZzi.js";import{C as l,b as o,a as m,c as f,d as z}from"./card-C9ekeZtD.js";import{B as v}from"./badge-fHjW-wEe.js";import{A as u}from"./arrow-left-CdJt7_wH.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-Bbxvuj4b.js";import{C as N,a as C,b as se,c as ae}from"./card-D_zGBKua.js";import{L as l}from"./label-CZGCmBD7.js";import{B as re}from"./badge-D7ZZbMEG.js";import{c as ne}from"./clipboard-B9ndUJKl.js";import{A as z}from"./arrow-left-Do2jUSS9.js";import{C as oe,a as ie}from"./clipboard-D3NA8gb4.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-BAEEeZzi.js";import{C as N,a as C,b as se,c as ae}from"./card-C9ekeZtD.js";import{L as l}from"./label-CRsu1MwQ.js";import{B as re}from"./badge-fHjW-wEe.js";import{c as ne}from"./clipboard-B9ndUJKl.js";import{A as z}from"./arrow-left-CdJt7_wH.js";import{C as oe,a as ie}from"./clipboard-Dv0iwZO9.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-Bbxvuj4b.js";import{C as N,a as w,b as D,c as H}from"./card-D_zGBKua.js";import{B as y}from"./badge-D7ZZbMEG.js";import{c as U}from"./clipboard-B9ndUJKl.js";import{R as Y,L as F}from"./browser-modal-CWDhylx7.js";import{R as G,f as J}from"./registry-ANRa5WBi.js";import{P as T}from"./plus-Be79gWKj.js";import{T as K}from"./tag-BgO5mxYK.js";import"./search-CrIdR7ah.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-BAEEeZzi.js";import{C as N,a as w,b as D,c as H}from"./card-C9ekeZtD.js";import{B as y}from"./badge-fHjW-wEe.js";import{c as U}from"./clipboard-B9ndUJKl.js";import{R as Y,L as F}from"./browser-modal-D6BB5mxm.js";import{R as G,f as J}from"./registry-ANRa5WBi.js";import{P as T}from"./plus-CemYz5Fm.js";import{T as K}from"./tag-BpNIhvRX.js";import"./search-BvRo_rak.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
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-Bbxvuj4b.js";import{C as x,b as m,c as u,d as h,a as j}from"./card-D_zGBKua.js";import{L as a}from"./label-CZGCmBD7.js";import{B as n}from"./badge-D7ZZbMEG.js";import{P as S}from"./plus-Be79gWKj.js";import{P as p}from"./pause-BNL49HvB.js";import{P as R}from"./play-8b83f5X0.js";import{Z as T}from"./zap-cD8GAJPg.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-BAEEeZzi.js";import{C as x,b as m,c as u,d as h,a as j}from"./card-C9ekeZtD.js";import{L as a}from"./label-CRsu1MwQ.js";import{B as n}from"./badge-fHjW-wEe.js";import{P as S}from"./plus-CemYz5Fm.js";import{P as p}from"./pause-C7KYrzQF.js";import{P as R}from"./play-DhUf2mKM.js";import{Z as T}from"./zap-DOtH7YrV.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,7 +1,7 @@
1
- import{c as q,m as z,r as t,aX as y,j as e,B as a,aY as R,T as _,D as j,a as g,b as v,d as f,e as A,I as F,$ as N,ai as J,t as i}from"./index-Bbxvuj4b.js";import{C as W,b as G,c as Q,d as V,a as Z}from"./card-D_zGBKua.js";import{L as w}from"./label-CZGCmBD7.js";import{B as ee}from"./badge-D7ZZbMEG.js";import{A as I,a as C}from"./alert-D2VTq6m-.js";import{P as se}from"./plus-Be79gWKj.js";import{C as te}from"./circle-alert-DQD0CPB3.js";/**
1
+ import{c as R,m as X,r as t,b5 as y,j as e,B as a,b6 as Y,T as _,D as j,a as g,b as v,d as f,e as A,I as F,$ as N,ai as J,t as i}from"./index-BAEEeZzi.js";import{C as W,b as G,c as Q,d as V,a as Z}from"./card-C9ekeZtD.js";import{L as w}from"./label-CRsu1MwQ.js";import{B as ee}from"./badge-fHjW-wEe.js";import{A as I,a as C}from"./alert-Baaj8mli.js";import{P as se}from"./plus-CemYz5Fm.js";import{C as te}from"./circle-alert-DnIYekt3.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
- */const ae=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]],L=q("info",ae);function he(){const{authEnabled:n}=z(),[k,P]=t.useState([]),[b,K]=t.useState(!0),[M,o]=t.useState(!1),[O,d]=t.useState(!1),[h,D]=t.useState(""),[x,E]=t.useState("never"),[c,S]=t.useState(null),[m,l]=t.useState(null);t.useEffect(()=>{p()},[]);const p=async()=>{K(!0);try{const s=await y("/api/v1/api-keys");s.success&&P(s.data?.apiKeys||[])}catch(s){console.error("Failed to load API keys:",s),P([])}finally{K(!1)}},U=async()=>{if(!h.trim()){i({title:"Error",description:"Please provide a name for the API key",variant:"destructive"});return}try{const s={name:h,scopes:["*"]};x!=="never"&&(s.expiresIn=x);const r=await y("/api/v1/api-keys",{method:"POST",body:JSON.stringify(s)});r.success&&(S(r.data),o(!1),d(!0),D(""),E("never"),await p(),i({title:"API Key Created",description:"Make sure to copy your API key now. You won't be able to see it again!"}))}catch(s){console.error("Failed to create API key:",s),i({title:"Error",description:"Failed to create API key",variant:"destructive"})}},B=async s=>{try{(await y(`/api/v1/api-keys/${s}`,{method:"DELETE"})).success&&(await p(),l(null),i({title:"API Key Deleted",description:"The API key has been permanently deleted"}))}catch(r){console.error("Failed to delete API key:",r),i({title:"Error",description:"Failed to delete API key",variant:"destructive"})}},$=async s=>{try{await navigator.clipboard.writeText(s),i({title:"Copied",description:"API key copied to clipboard"})}catch{i({title:"Error",description:"Failed to copy to clipboard",variant:"destructive"})}},u=s=>new Date(s).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}),H=s=>s?new Date(s)<new Date:!1,X=typeof window<"u"?window.location.origin:"http://localhost:3000",Y=c?`curl -H "X-API-Key: ${c.key}" \\
7
- + ${X}/api/v1/proposals`:"",T=n?null:e.jsxs(I,{children:[e.jsx(L,{className:"h-4 w-4"}),e.jsxs(C,{children:["Authentication is currently disabled. API keys will only be required once you enable authentication in the ",e.jsx("a",{href:"/settings/authentication",className:"underline",children:"Authentication settings"}),"."]})]});return!n&&b?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"API Keys"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage API keys for programmatic access"})]}),T]}):b?e.jsx("div",{className:"space-y-6",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"API Keys"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading..."})]})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"API Keys"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage API keys for programmatic access to your Coconut instance"})]}),T,n&&e.jsxs(I,{children:[e.jsx(L,{className:"h-4 w-4"}),e.jsxs(C,{children:["API keys provide programmatic access to your Coconut instance. Use them in CI/CD pipelines or automation scripts by including the key in the ",e.jsx("code",{className:"bg-muted px-1 py-0.5 rounded",children:"X-API-Key"})," header."]})]}),e.jsxs(W,{children:[e.jsx(G,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(Q,{children:"Active API Keys"}),e.jsx(V,{children:"API keys you've created for programmatic access"})]}),e.jsxs(a,{onClick:()=>o(!0),disabled:!n,children:[e.jsx(se,{className:"mr-2 h-4 w-4"}),"Create API Key"]})]})}),e.jsx(Z,{children:k.length===0?e.jsxs("div",{className:"text-center py-8 text-muted-foreground",children:[e.jsx(R,{className:"h-12 w-12 mx-auto mb-4 opacity-20"}),e.jsx("p",{children:"No API keys yet"}),e.jsx("p",{className:"text-sm",children:"Create an API key to get started with programmatic access"})]}):e.jsx("div",{className:"space-y-4",children:k.map(s=>e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("p",{className:"font-medium",children:s.name}),H(s.expiresAt)&&e.jsx(ee,{variant:"destructive",children:"Expired"})]}),e.jsx("p",{className:"text-sm text-muted-foreground font-mono",children:s.keyPreview}),e.jsxs("div",{className:"flex items-center gap-4 mt-2 text-xs text-muted-foreground",children:[e.jsxs("span",{children:["Created: ",u(s.createdAt)]}),s.expiresAt&&e.jsxs("span",{children:["Expires: ",u(s.expiresAt)]}),s.lastUsedAt&&e.jsxs("span",{children:["Last used: ",u(s.lastUsedAt)]})]})]}),e.jsx(a,{variant:"ghost",size:"icon",onClick:()=>l(s.id),children:e.jsx(_,{className:"h-4 w-4 text-destructive"})})]},s.id))})})]}),e.jsx(j,{open:M,onOpenChange:o,children:e.jsxs(g,{children:[e.jsxs(v,{children:[e.jsx(f,{children:"Create API Key"}),e.jsx(A,{children:"Create a new API key for programmatic access. The key will only be shown once."})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(w,{htmlFor:"keyName",children:"Name"}),e.jsx(F,{id:"keyName",placeholder:"CI/CD Pipeline",value:h,onChange:s=>D(s.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"A descriptive name to identify this API key"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(w,{htmlFor:"keyExpiry",children:"Expiration"}),e.jsxs("select",{id:"keyExpiry",className:"w-full rounded-md border border-input bg-background px-3 py-2 text-sm",value:x,onChange:s=>E(s.target.value),children:[e.jsx("option",{value:"never",children:"Never"}),e.jsx("option",{value:"30d",children:"30 days"}),e.jsx("option",{value:"90d",children:"90 days"}),e.jsx("option",{value:"1y",children:"1 year"})]})]})]}),e.jsxs(N,{children:[e.jsx(a,{variant:"outline",onClick:()=>o(!1),children:"Cancel"}),e.jsx(a,{onClick:U,disabled:!n,children:"Create API Key"})]})]})}),e.jsx(j,{open:O,onOpenChange:d,children:e.jsxs(g,{className:"sm:max-w-[600px]",children:[e.jsxs(v,{children:[e.jsx(f,{children:"API Key Created"}),e.jsx(A,{children:"Make sure to copy your API key now. You won't be able to see it again!"})]}),e.jsxs(I,{variant:"destructive",className:"my-4",children:[e.jsx(te,{className:"h-4 w-4"}),e.jsx(C,{children:"This is the only time you will see this key. Store it securely."})]}),c&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(w,{children:"API Key"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(F,{readOnly:!0,value:c.key,className:"font-mono text-sm"}),e.jsx(a,{variant:"outline",size:"icon",onClick:()=>$(c.key),children:e.jsx(J,{className:"h-4 w-4"})})]})]}),e.jsxs("div",{className:"text-sm text-muted-foreground",children:[e.jsx("p",{className:"mb-2",children:"Usage example:"}),e.jsx("pre",{className:"bg-muted p-3 rounded-md whitespace-pre-wrap break-words",children:e.jsx("code",{className:"font-mono text-xs",children:Y})})]})]}),e.jsx(N,{children:e.jsx(a,{onClick:()=>{d(!1),S(null)},children:"I've Saved My Key"})})]})}),e.jsx(j,{open:!!m,onOpenChange:s=>!s&&l(null),children:e.jsxs(g,{children:[e.jsxs(v,{children:[e.jsx(f,{children:"Delete API Key"}),e.jsx(A,{children:"Are you sure you want to delete this API key? This action cannot be undone and any scripts using this key will stop working."})]}),e.jsxs(N,{children:[e.jsx(a,{variant:"outline",onClick:()=>l(null),children:"Cancel"}),e.jsx(a,{variant:"destructive",onClick:()=>m&&B(m),children:"Delete API Key"})]})]})})]})}export{he as default};
6
+ */const ae=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]],L=R("info",ae);function he(){const{authEnabled:n}=X(),[k,P]=t.useState([]),[b,K]=t.useState(!0),[M,o]=t.useState(!1),[O,d]=t.useState(!1),[h,D]=t.useState(""),[x,E]=t.useState("never"),[c,S]=t.useState(null),[m,l]=t.useState(null);t.useEffect(()=>{p()},[]);const p=async()=>{K(!0);try{const s=await y("/api/v1/api-keys");s.success&&P(s.data?.apiKeys||[])}catch(s){console.error("Failed to load API keys:",s),P([])}finally{K(!1)}},U=async()=>{if(!h.trim()){i({title:"Error",description:"Please provide a name for the API key",variant:"destructive"});return}try{const s={name:h,scopes:["*"]};x!=="never"&&(s.expiresIn=x);const r=await y("/api/v1/api-keys",{method:"POST",body:JSON.stringify(s)});r.success&&(S(r.data),o(!1),d(!0),D(""),E("never"),await p(),i({title:"API Key Created",description:"Make sure to copy your API key now. You won't be able to see it again!"}))}catch(s){console.error("Failed to create API key:",s),i({title:"Error",description:"Failed to create API key",variant:"destructive"})}},B=async s=>{try{(await y(`/api/v1/api-keys/${s}`,{method:"DELETE"})).success&&(await p(),l(null),i({title:"API Key Deleted",description:"The API key has been permanently deleted"}))}catch(r){console.error("Failed to delete API key:",r),i({title:"Error",description:"Failed to delete API key",variant:"destructive"})}},$=async s=>{try{await navigator.clipboard.writeText(s),i({title:"Copied",description:"API key copied to clipboard"})}catch{i({title:"Error",description:"Failed to copy to clipboard",variant:"destructive"})}},u=s=>new Date(s).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}),H=s=>s?new Date(s)<new Date:!1,q=typeof window<"u"?window.location.origin:"http://localhost:3000",z=c?`curl -H "X-API-Key: ${c.key}" \\
7
+ + ${q}/api/v1/proposals`:"",T=n?null:e.jsxs(I,{children:[e.jsx(L,{className:"h-4 w-4"}),e.jsxs(C,{children:["Authentication is currently disabled. API keys will only be required once you enable authentication in the ",e.jsx("a",{href:"/settings/authentication",className:"underline",children:"Authentication settings"}),"."]})]});return!n&&b?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"API Keys"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage API keys for programmatic access"})]}),T]}):b?e.jsx("div",{className:"space-y-6",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"API Keys"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading..."})]})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"API Keys"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage API keys for programmatic access to your Coconut instance"})]}),T,n&&e.jsxs(I,{children:[e.jsx(L,{className:"h-4 w-4"}),e.jsxs(C,{children:["API keys provide programmatic access to your Coconut instance. Use them in CI/CD pipelines or automation scripts by including the key in the ",e.jsx("code",{className:"bg-muted px-1 py-0.5 rounded",children:"X-API-Key"})," header."]})]}),e.jsxs(W,{children:[e.jsx(G,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(Q,{children:"Active API Keys"}),e.jsx(V,{children:"API keys you've created for programmatic access"})]}),e.jsxs(a,{onClick:()=>o(!0),disabled:!n,children:[e.jsx(se,{className:"mr-2 h-4 w-4"}),"Create API Key"]})]})}),e.jsx(Z,{children:k.length===0?e.jsxs("div",{className:"text-center py-8 text-muted-foreground",children:[e.jsx(Y,{className:"h-12 w-12 mx-auto mb-4 opacity-20"}),e.jsx("p",{children:"No API keys yet"}),e.jsx("p",{className:"text-sm",children:"Create an API key to get started with programmatic access"})]}):e.jsx("div",{className:"space-y-4",children:k.map(s=>e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("p",{className:"font-medium",children:s.name}),H(s.expiresAt)&&e.jsx(ee,{variant:"destructive",children:"Expired"})]}),e.jsx("p",{className:"text-sm text-muted-foreground font-mono",children:s.keyPreview}),e.jsxs("div",{className:"flex items-center gap-4 mt-2 text-xs text-muted-foreground",children:[e.jsxs("span",{children:["Created: ",u(s.createdAt)]}),s.expiresAt&&e.jsxs("span",{children:["Expires: ",u(s.expiresAt)]}),s.lastUsedAt&&e.jsxs("span",{children:["Last used: ",u(s.lastUsedAt)]})]})]}),e.jsx(a,{variant:"ghost",size:"icon",onClick:()=>l(s.id),children:e.jsx(_,{className:"h-4 w-4 text-destructive"})})]},s.id))})})]}),e.jsx(j,{open:M,onOpenChange:o,children:e.jsxs(g,{children:[e.jsxs(v,{children:[e.jsx(f,{children:"Create API Key"}),e.jsx(A,{children:"Create a new API key for programmatic access. The key will only be shown once."})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(w,{htmlFor:"keyName",children:"Name"}),e.jsx(F,{id:"keyName",placeholder:"CI/CD Pipeline",value:h,onChange:s=>D(s.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"A descriptive name to identify this API key"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(w,{htmlFor:"keyExpiry",children:"Expiration"}),e.jsxs("select",{id:"keyExpiry",className:"w-full rounded-md border border-input bg-background px-3 py-2 text-sm",value:x,onChange:s=>E(s.target.value),children:[e.jsx("option",{value:"never",children:"Never"}),e.jsx("option",{value:"30d",children:"30 days"}),e.jsx("option",{value:"90d",children:"90 days"}),e.jsx("option",{value:"1y",children:"1 year"})]})]})]}),e.jsxs(N,{children:[e.jsx(a,{variant:"outline",onClick:()=>o(!1),children:"Cancel"}),e.jsx(a,{onClick:U,disabled:!n,children:"Create API Key"})]})]})}),e.jsx(j,{open:O,onOpenChange:d,children:e.jsxs(g,{className:"sm:max-w-[600px]",children:[e.jsxs(v,{children:[e.jsx(f,{children:"API Key Created"}),e.jsx(A,{children:"Make sure to copy your API key now. You won't be able to see it again!"})]}),e.jsxs(I,{variant:"destructive",className:"my-4",children:[e.jsx(te,{className:"h-4 w-4"}),e.jsx(C,{children:"This is the only time you will see this key. Store it securely."})]}),c&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(w,{children:"API Key"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(F,{readOnly:!0,value:c.key,className:"font-mono text-sm"}),e.jsx(a,{variant:"outline",size:"icon",onClick:()=>$(c.key),children:e.jsx(J,{className:"h-4 w-4"})})]})]}),e.jsxs("div",{className:"text-sm text-muted-foreground",children:[e.jsx("p",{className:"mb-2",children:"Usage example:"}),e.jsx("pre",{className:"bg-muted p-3 rounded-md whitespace-pre-wrap break-words",children:e.jsx("code",{className:"font-mono text-xs",children:z})})]})]}),e.jsx(N,{children:e.jsx(a,{onClick:()=>{d(!1),S(null)},children:"I've Saved My Key"})})]})}),e.jsx(j,{open:!!m,onOpenChange:s=>!s&&l(null),children:e.jsxs(g,{children:[e.jsxs(v,{children:[e.jsx(f,{children:"Delete API Key"}),e.jsx(A,{children:"Are you sure you want to delete this API key? This action cannot be undone and any scripts using this key will stop working."})]}),e.jsxs(N,{children:[e.jsx(a,{variant:"outline",onClick:()=>l(null),children:"Cancel"}),e.jsx(a,{variant:"destructive",onClick:()=>m&&B(m),children:"Delete API Key"})]})]})})]})}export{he as default};
@@ -1,4 +1,4 @@
1
- import{u as D,H as M,r as l,A as b,j as e,B as S,L as I,a2 as _,I as d,a0 as B}from"./index-Bbxvuj4b.js";import{C as u,a as p,b as j,c as v}from"./card-D_zGBKua.js";import{L as o}from"./label-CZGCmBD7.js";import{M as P}from"./markdown-editor-BiM9h5iI.js";import{A as R}from"./arrow-left-Do2jUSS9.js";import{C as $}from"./circle-check-big-KfJvKA9H.js";function Q(){const F=D(),{toast:h}=M(),[n,x]=l.useState({stack:{runtime:"",framework:"",language:"",database:"",deployment:"",repository:""},commands:{}}),[y,f]=l.useState(""),[E,k]=l.useState(""),[L,N]=l.useState(!0),[C,w]=l.useState(!1);l.useEffect(()=>{fetch(`${b}/api/v1/context/architecture`).then(t=>t.json()).then(t=>{if(t.success){const a=t.document,m={stack:{runtime:a.metadata.stack?.runtime||"",framework:a.metadata.stack?.framework||"",language:a.metadata.stack?.language||"",database:a.metadata.stack?.database||"",deployment:a.metadata.stack?.deployment||"",repository:a.metadata.stack?.repository||""},commands:a.metadata.commands||{}};x(m);const s=Object.entries(m.commands).map(([r,c])=>`${r}: ${c}`).join(`
1
+ import{u as D,H as M,r as l,A as b,j as e,B as S,L as I,a2 as _,I as d,a0 as B}from"./index-BAEEeZzi.js";import{C as u,a as p,b as j,c as v}from"./card-C9ekeZtD.js";import{L as o}from"./label-CRsu1MwQ.js";import{M as P}from"./markdown-editor-Dop22vuJ.js";import{A as R}from"./arrow-left-CdJt7_wH.js";import{C as $}from"./circle-check-big-BUVglreY.js";function Q(){const F=D(),{toast:h}=M(),[n,x]=l.useState({stack:{runtime:"",framework:"",language:"",database:"",deployment:"",repository:""},commands:{}}),[y,f]=l.useState(""),[E,k]=l.useState(""),[L,N]=l.useState(!0),[C,w]=l.useState(!1);l.useEffect(()=>{fetch(`${b}/api/v1/context/architecture`).then(t=>t.json()).then(t=>{if(t.success){const a=t.document,m={stack:{runtime:a.metadata.stack?.runtime||"",framework:a.metadata.stack?.framework||"",language:a.metadata.stack?.language||"",database:a.metadata.stack?.database||"",deployment:a.metadata.stack?.deployment||"",repository:a.metadata.stack?.repository||""},commands:a.metadata.commands||{}};x(m);const s=Object.entries(m.commands).map(([r,c])=>`${r}: ${c}`).join(`
2
2
  `);k(s),f(a.content.trim())}N(!1)}).catch(t=>{console.error("Failed to load context:",t),h({title:"Error",description:"Failed to load architecture documentation",variant:"destructive"}),N(!1)})},[h]);const A=async()=>{w(!0);try{const a=await(await fetch(`${b}/api/v1/context/architecture`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:y,metadata:{stack:n.stack,commands:n.commands}})})).json();if(a.success)h({title:"Success",description:"Architecture documentation saved successfully",action:e.jsx($,{className:"h-4 w-4"})}),F("/context/architecture");else throw new Error(a.error||"Failed to save context")}catch(t){console.error("Save error:",t),h({title:"Error",description:"Failed to save architecture documentation",variant:"destructive"})}finally{w(!1)}},i=(t,a)=>{x(m=>{const s={...m},r=t.split(".");let c=s;for(let g=0;g<r.length-1;g++)c=c[r[g]];return c[r[r.length-1]]=a,s})},T=t=>{k(t);const a={};t.split(`
3
3
  `).filter(s=>s.trim()).forEach(s=>{const[r,...c]=s.split(":");r&&c.length>0&&(a[r.trim()]=c.join(":").trim())}),x(s=>({...s,commands:a}))};return L?e.jsx("div",{className:"space-y-6",children:e.jsx(u,{children:e.jsx(p,{className:"pt-6",children:e.jsx("div",{className:"text-center",children:e.jsx("p",{children:"Loading..."})})})})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("h1",{className:"text-xl sm:text-2xl font-bold tracking-tight",children:"Edit Architecture"}),e.jsx("p",{className:"text-muted-foreground text-sm hidden sm:block",children:"Edit technical architecture and supporting metadata"})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-shrink-0",children:[e.jsx(S,{variant:"ghost",size:"sm",asChild:!0,children:e.jsx(I,{to:"/context/architecture",className:"text-muted-foreground hover:text-foreground transition-colors",children:e.jsx(R,{className:"w-4 h-4"})})}),e.jsxs(S,{onClick:A,disabled:C,size:"sm",children:[e.jsx(_,{className:"w-4 h-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:C?"Saving...":"Save"})]})]})]}),e.jsxs(u,{children:[e.jsx(j,{children:e.jsx(v,{children:"Technology Stack"})}),e.jsxs(p,{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"runtime",children:"Runtime"}),e.jsx(d,{id:"runtime",value:n.stack.runtime,onChange:t=>i("stack.runtime",t.target.value),placeholder:"node|python|go|etc"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"framework",children:"Framework"}),e.jsx(d,{id:"framework",value:n.stack.framework,onChange:t=>i("stack.framework",t.target.value),placeholder:"express|fastify|django|gin|etc"})]})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"language",children:"Language"}),e.jsx(d,{id:"language",value:n.stack.language,onChange:t=>i("stack.language",t.target.value),placeholder:"typescript|javascript|python|go|etc"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"database",children:"Database"}),e.jsx(d,{id:"database",value:n.stack.database,onChange:t=>i("stack.database",t.target.value),placeholder:"postgresql|mysql|mongodb|sqlite|etc"})]})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"deployment",children:"Deployment"}),e.jsx(d,{id:"deployment",value:n.stack.deployment,onChange:t=>i("stack.deployment",t.target.value),placeholder:"docker|kubernetes|vercel|aws|etc"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"repository",children:"Repository"}),e.jsx(d,{id:"repository",value:n.stack.repository,onChange:t=>i("stack.repository",t.target.value),placeholder:"https://github.com/yourorg/yourproject"})]})]})]})]}),e.jsxs(u,{children:[e.jsx(j,{children:e.jsx(v,{children:"Quick Commands"})}),e.jsx(p,{className:"space-y-4",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx(o,{htmlFor:"commands",children:"Commands (format: command_name: command_to_run)"}),e.jsx(B,{id:"commands",value:E,onChange:t=>T(t.target.value),placeholder:`install: npm install
4
4
  dev: npm run dev
@@ -1 +1 @@
1
- import{H as g,r as n,A as v,j as e,n as y,g as k,B as l,ap as b,ao as w,L as C,J as E,al as A}from"./index-Bbxvuj4b.js";import{C as a,a as c,b as o,c as m}from"./card-D_zGBKua.js";import{c as D}from"./clipboard-B9ndUJKl.js";function F(){const{toast:h}=g(),[r,x]=n.useState(null),[u,p]=n.useState(!0),[j,i]=n.useState(!1);n.useEffect(()=>{fetch(`${v}/api/v1/context/architecture`).then(t=>{if(t.ok)return t.json();throw new Error("Not found")}).then(t=>{t.success?(x(t.document),i(!0)):i(!1)}).catch(()=>{i(!1)}).finally(()=>{p(!1)})},[]);const N=async()=>{const t=".nut/context/architecture.md";try{await D(t),h({title:"Copied!",description:`Path ${t} copied to clipboard`})}catch(d){console.error("Failed to copy path:",d),h({title:"Error",description:"Failed to copy path to clipboard",variant:"destructive"})}},f=()=>{const t=new CustomEvent("discuss-in-chat",{detail:{type:"context",id:"architecture-md",filename:"architecture.md",name:"architecture.md",path:".nut/context/architecture.md"}});window.dispatchEvent(t)};if(u)return e.jsx("div",{className:"space-y-6",children:e.jsx(a,{children:e.jsx(c,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center justify-center",children:[e.jsx(y,{className:"h-8 w-8 animate-spin text-muted-foreground"}),e.jsx("span",{className:"ml-2 text-muted-foreground",children:"Loading architecture documentation..."})]})})})});if(!j||!r)return e.jsx("div",{className:"space-y-6",children:e.jsx(a,{children:e.jsx(c,{className:"pt-6",children:e.jsxs("div",{className:"text-center",children:[e.jsx(k,{className:"mx-auto h-12 w-12 text-muted-foreground"}),e.jsx("h3",{className:"mt-4 text-lg font-semibold",children:"No Architecture Documentation Found"}),e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:"Architecture documentation will appear here once created."})]})})})});const s=r.metadata;return 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("h1",{className:"text-2xl font-bold tracking-tight",children:"Technical Architecture"}),e.jsx("p",{className:"text-muted-foreground",children:"System design, components, and technical patterns"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(l,{variant:"outline",size:"sm",onClick:f,children:[e.jsx(b,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Discuss"})]}),e.jsxs(l,{variant:"outline",size:"sm",onClick:N,children:[e.jsx(w,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Copy Path"})]}),e.jsx(l,{size:"sm",asChild:!0,children:e.jsxs(C,{to:"/context/architecture/edit",children:[e.jsx(E,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Edit"})]})})]})]}),s&&e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs(a,{children:[e.jsx(o,{className:"pb-3",children:e.jsx(m,{className:"text-lg font-semibold",children:"Technology Stack"})}),e.jsx(c,{className:"space-y-3",children:s.stack&&e.jsxs("div",{className:"space-y-1 text-sm",children:[s.stack.runtime&&e.jsxs("div",{children:["Runtime: ",s.stack.runtime]}),s.stack.framework&&e.jsxs("div",{children:["Framework: ",s.stack.framework]}),s.stack.language&&e.jsxs("div",{children:["Language: ",s.stack.language]}),s.stack.database&&e.jsxs("div",{children:["Database: ",s.stack.database]}),s.stack.deployment&&e.jsxs("div",{children:["Deployment: ",s.stack.deployment]}),s.stack.repository&&e.jsxs("div",{children:["Repository:"," ",e.jsx("a",{href:s.stack.repository,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:s.stack.repository})]})]})})]}),e.jsxs(a,{children:[e.jsx(o,{className:"pb-3",children:e.jsx(m,{className:"text-lg font-semibold",children:"Quick Commands"})}),e.jsx(c,{className:"space-y-3",children:s.commands&&e.jsxs("div",{className:"space-y-1",children:[Object.entries(s.commands).slice(0,5).map(([t,d])=>e.jsxs("div",{className:"text-sm",children:[e.jsxs("span",{className:"font-medium capitalize",children:[t,": "]}),e.jsx("code",{className:"bg-muted px-2 py-1 rounded text-xs",children:d})]},t)),Object.entries(s.commands).length>5&&e.jsxs("div",{className:"text-xs text-muted-foreground",children:["+ ",Object.entries(s.commands).length-5," more commands"]})]})})]})]}),e.jsxs(a,{children:[e.jsx(o,{children:e.jsx(m,{className:"text-lg font-semibold",children:"Architecture Documentation"})}),e.jsx(c,{children:e.jsx("div",{className:"prose prose-sm max-w-none dark:prose-invert",children:e.jsx(A,{children:r.content||"No content available"})})})]})]})}export{F as default};
1
+ import{H as g,r as n,A as v,j as e,n as y,g as k,B as l,az as b,ay as w,L as C,J as E,av as A}from"./index-BAEEeZzi.js";import{C as a,a as c,b as o,c as m}from"./card-C9ekeZtD.js";import{c as D}from"./clipboard-B9ndUJKl.js";function F(){const{toast:h}=g(),[r,x]=n.useState(null),[u,p]=n.useState(!0),[j,i]=n.useState(!1);n.useEffect(()=>{fetch(`${v}/api/v1/context/architecture`).then(t=>{if(t.ok)return t.json();throw new Error("Not found")}).then(t=>{t.success?(x(t.document),i(!0)):i(!1)}).catch(()=>{i(!1)}).finally(()=>{p(!1)})},[]);const N=async()=>{const t=".nut/context/architecture.md";try{await D(t),h({title:"Copied!",description:`Path ${t} copied to clipboard`})}catch(d){console.error("Failed to copy path:",d),h({title:"Error",description:"Failed to copy path to clipboard",variant:"destructive"})}},f=()=>{const t=new CustomEvent("discuss-in-chat",{detail:{type:"context",id:"architecture-md",filename:"architecture.md",name:"architecture.md",path:".nut/context/architecture.md"}});window.dispatchEvent(t)};if(u)return e.jsx("div",{className:"space-y-6",children:e.jsx(a,{children:e.jsx(c,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center justify-center",children:[e.jsx(y,{className:"h-8 w-8 animate-spin text-muted-foreground"}),e.jsx("span",{className:"ml-2 text-muted-foreground",children:"Loading architecture documentation..."})]})})})});if(!j||!r)return e.jsx("div",{className:"space-y-6",children:e.jsx(a,{children:e.jsx(c,{className:"pt-6",children:e.jsxs("div",{className:"text-center",children:[e.jsx(k,{className:"mx-auto h-12 w-12 text-muted-foreground"}),e.jsx("h3",{className:"mt-4 text-lg font-semibold",children:"No Architecture Documentation Found"}),e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:"Architecture documentation will appear here once created."})]})})})});const s=r.metadata;return 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("h1",{className:"text-2xl font-bold tracking-tight",children:"Technical Architecture"}),e.jsx("p",{className:"text-muted-foreground",children:"System design, components, and technical patterns"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(l,{variant:"outline",size:"sm",onClick:f,children:[e.jsx(b,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Discuss"})]}),e.jsxs(l,{variant:"outline",size:"sm",onClick:N,children:[e.jsx(w,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Copy Path"})]}),e.jsx(l,{size:"sm",asChild:!0,children:e.jsxs(C,{to:"/context/architecture/edit",children:[e.jsx(E,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Edit"})]})})]})]}),s&&e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs(a,{children:[e.jsx(o,{className:"pb-3",children:e.jsx(m,{className:"text-lg font-semibold",children:"Technology Stack"})}),e.jsx(c,{className:"space-y-3",children:s.stack&&e.jsxs("div",{className:"space-y-1 text-sm",children:[s.stack.runtime&&e.jsxs("div",{children:["Runtime: ",s.stack.runtime]}),s.stack.framework&&e.jsxs("div",{children:["Framework: ",s.stack.framework]}),s.stack.language&&e.jsxs("div",{children:["Language: ",s.stack.language]}),s.stack.database&&e.jsxs("div",{children:["Database: ",s.stack.database]}),s.stack.deployment&&e.jsxs("div",{children:["Deployment: ",s.stack.deployment]}),s.stack.repository&&e.jsxs("div",{children:["Repository:"," ",e.jsx("a",{href:s.stack.repository,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:s.stack.repository})]})]})})]}),e.jsxs(a,{children:[e.jsx(o,{className:"pb-3",children:e.jsx(m,{className:"text-lg font-semibold",children:"Quick Commands"})}),e.jsx(c,{className:"space-y-3",children:s.commands&&e.jsxs("div",{className:"space-y-1",children:[Object.entries(s.commands).slice(0,5).map(([t,d])=>e.jsxs("div",{className:"text-sm",children:[e.jsxs("span",{className:"font-medium capitalize",children:[t,": "]}),e.jsx("code",{className:"bg-muted px-2 py-1 rounded text-xs",children:d})]},t)),Object.entries(s.commands).length>5&&e.jsxs("div",{className:"text-xs text-muted-foreground",children:["+ ",Object.entries(s.commands).length-5," more commands"]})]})})]})]}),e.jsxs(a,{children:[e.jsx(o,{children:e.jsx(m,{className:"text-lg font-semibold",children:"Architecture Documentation"})}),e.jsx(c,{children:e.jsx("div",{className:"prose prose-sm max-w-none dark:prose-invert",children:e.jsx(A,{children:r.content||"No content available"})})})]})]})}export{F as default};
@@ -1,4 +1,4 @@
1
- import{c as Y,m as le,r as n,aX as c,j as e,a1 as O,aW as ce,D as I,_ as M,B as l,a as $,b as V,d as _,e as z,I as j,v as H,w as J,x as W,y as q,z as a,$ as B,M as oe,N as de,T as he,O as ue,P as xe,Q as me,R as ge,U as je,V as pe,W as ve,t as r}from"./index-Bbxvuj4b.js";import{C as p,b as v,c as w,d as f,a as y}from"./card-D_zGBKua.js";import{L as o}from"./label-CZGCmBD7.js";import{S as U}from"./switch-BYPAX9oF.js";import{B as k}from"./badge-D7ZZbMEG.js";import{C as we}from"./circle-alert-DQD0CPB3.js";/**
1
+ import{c as Y,m as le,r as n,b5 as c,j as e,a1 as O,b4 as ce,D as I,_ as M,B as l,a as $,b as V,d as _,e as z,I as j,v as H,w as J,x as W,y as q,z as a,$ as B,M as oe,N as de,T as he,O as ue,P as xe,Q as me,R as ge,U as je,V as pe,W as ve,t as r}from"./index-BAEEeZzi.js";import{C as p,b as v,c as w,d as f,a as y}from"./card-C9ekeZtD.js";import{L as o}from"./label-CRsu1MwQ.js";import{S as U}from"./switch-CDOrVL8G.js";import{B as k}from"./badge-fHjW-wEe.js";import{C as we}from"./circle-alert-DnIYekt3.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -8,4 +8,4 @@ import{c as Y,m as le,r as n,aX as c,j as e,a1 as O,aW as ce,D as I,_ as M,B as
8
8
  *
9
9
  * This source code is licensed under the ISC license.
10
10
  * See the LICENSE file in the root directory of this source tree.
11
- */const Ne=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]],Se=Y("user-plus",Ne);function Fe(){const{user:N,authEnabled:K,checkAuthStatus:Q}=le(),[i,d]=n.useState(null),[X,F]=n.useState(!0),[S,P]=n.useState(!1),[G,C]=n.useState(!1),[b,D]=n.useState(""),[A,R]=n.useState(""),[T,L]=n.useState("viewer"),[E,u]=n.useState(null),[x,m]=n.useState(""),Z=!K||N?.role==="admin";n.useEffect(()=>{h()},[]);const h=async()=>{try{F(!0);const s=await c("/api/v1/auth-settings");s.success?d(s.data):d(null)}catch(s){console.error("Failed to load auth settings:",s),d(null)}finally{F(!1)}},ee=async()=>{if(!i)return;const s=!i.enabled;try{const t=await c("/api/v1/auth-settings",{method:"PUT",body:JSON.stringify({enabled:s})});if(t.success)d({...i,enabled:s}),await Q(),r({title:"Success",description:`Authentication ${s?"enabled":"disabled"}`});else throw new Error(t.error||"Failed to toggle auth")}catch(t){r({title:"Error",description:t.message||"Failed to toggle authentication",variant:"destructive"})}},se=async()=>{if(!i)return;const s=!i.allowRegistration;try{const t=await c("/api/v1/auth-settings",{method:"PUT",body:JSON.stringify({allowRegistration:s})});if(t.success)d({...i,allowRegistration:s}),r({title:"Success",description:`Self-registration ${s?"enabled":"disabled"}`});else throw new Error(t.error||"Failed to update setting")}catch(t){r({title:"Error",description:t.message||"Failed to update setting",variant:"destructive"})}},te=async()=>{if(!b||!A){r({title:"Error",description:"Please provide email and name",variant:"destructive"});return}try{const s=await c("/api/v1/auth-settings/users",{method:"POST",body:JSON.stringify({email:b,name:A,role:T})});if(s.success)await h(),C(!1),D(""),R(""),L("viewer"),r({title:"Success",description:"User added to whitelist"});else throw new Error(s.error||"Failed to add user")}catch(s){r({title:"Error",description:s.message||"Failed to add user",variant:"destructive"})}},ie=async s=>{try{const t=await c(`/api/v1/auth-settings/users/${s}`,{method:"DELETE"});if(t.success)await h(),r({title:"Success",description:"User removed from whitelist"});else throw new Error(t.error||"Failed to remove user")}catch(t){r({title:"Error",description:t.message||"Failed to remove user",variant:"destructive"})}},re=async(s,t)=>{try{const g=await c(`/api/v1/auth-settings/users/${s}`,{method:"PUT",body:JSON.stringify({role:t})});if(g.success)await h(),r({title:"Success",description:"User role updated"});else throw new Error(g.error||"Failed to update role")}catch(g){r({title:"Error",description:g.message||"Failed to update role",variant:"destructive"})}},ae=async()=>{if(!(!E||!x)){if(x.length<8){r({title:"Error",description:"Password must be at least 8 characters",variant:"destructive"});return}try{const s=await c(`/api/v1/auth-settings/users/${E}/reset-password`,{method:"POST",body:JSON.stringify({newPassword:x})});if(s.success)u(null),m(""),r({title:"Success",description:"Password reset successfully"});else throw new Error(s.error||"Failed to reset password")}catch(s){r({title:"Error",description:s.message||"Failed to reset password",variant:"destructive"})}}},ne=async()=>{if(i)try{P(!0);const s=await c("/api/v1/auth-settings",{method:"PUT",body:JSON.stringify({session:i.session})});if(s.success)r({title:"Success",description:"Session settings updated"});else throw new Error(s.error||"Failed to update settings")}catch(s){r({title:"Error",description:s.message||"Failed to update settings",variant:"destructive"})}finally{P(!1)}};return X?e.jsx("div",{children:"Loading..."}):i?Z?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage authentication settings and user access."})]}),e.jsx(O,{}),e.jsxs(p,{children:[e.jsxs(v,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ce,{className:"h-5 w-5"}),e.jsx(w,{children:"Authentication Status"})]}),e.jsx(f,{children:"Control whether authentication is required to access Coconut."})]}),e.jsxs(y,{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"auth-enabled",children:"Require Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"When enabled, users must log in to access Coconut"})]}),e.jsx(U,{id:"auth-enabled",checked:i.enabled,onCheckedChange:ee})]}),i.enabled&&e.jsxs("div",{className:"flex items-center justify-between pt-2 border-t",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"allow-registration",children:"Allow Self-Registration"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Whitelisted users can create their own accounts"})]}),e.jsx(U,{id:"allow-registration",checked:i.allowRegistration,onCheckedChange:se})]})]})]}),e.jsxs(p,{children:[e.jsx(v,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(w,{children:"Whitelisted Users"}),e.jsx(f,{children:"Manage users who can access this Coconut instance."})]}),e.jsxs(I,{open:G,onOpenChange:C,children:[e.jsx(M,{asChild:!0,children:e.jsxs(l,{size:"sm",children:[e.jsx(Se,{className:"h-4 w-4 mr-2"}),"Add User"]})}),e.jsxs($,{children:[e.jsxs(V,{children:[e.jsx(_,{children:"Add User to Whitelist"}),e.jsx(z,{children:"Add a user's email to allow them to register and access Coconut."})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"new-email",children:"Email"}),e.jsx(j,{id:"new-email",type:"email",value:b,onChange:s=>D(s.target.value),placeholder:"user@example.com"})]}),e.jsxs("div",{children:[e.jsx(o,{htmlFor:"new-name",children:"Name"}),e.jsx(j,{id:"new-name",value:A,onChange:s=>R(s.target.value),placeholder:"User Name"})]}),e.jsxs("div",{children:[e.jsx(o,{htmlFor:"new-role",children:"Role"}),e.jsxs(H,{value:T,onValueChange:s=>L(s),children:[e.jsx(J,{children:e.jsx(W,{})}),e.jsxs(q,{children:[e.jsx(a,{value:"viewer",children:"Viewer"}),e.jsx(a,{value:"engineer",children:"Engineer"}),e.jsx(a,{value:"designer",children:"Designer"}),e.jsx(a,{value:"product_manager",children:"Product Manager"}),e.jsx(a,{value:"manager",children:"Manager"}),e.jsx(a,{value:"admin",children:"Admin"})]})]})]})]}),e.jsxs(B,{children:[e.jsx(l,{variant:"outline",onClick:()=>C(!1),children:"Cancel"}),e.jsx(l,{onClick:te,children:"Add User"})]})]})]})]})}),e.jsx(y,{children:e.jsx("div",{className:"space-y-4",children:i.providers.local.users.map(s=>e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{className:"space-y-1 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("p",{className:"font-medium",children:s.name}),s.registered?e.jsx(k,{variant:"default",className:"text-xs",children:"Registered"}):e.jsx(k,{variant:"secondary",className:"text-xs",children:"Pending"}),s.id===N?.id&&e.jsx(k,{variant:"outline",className:"text-xs",children:"You"})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:s.email}),s.lastLoginAt&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Last login: ",new Date(s.lastLoginAt).toLocaleString()]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(H,{value:s.role,onValueChange:t=>re(s.id,t),children:[e.jsx(J,{className:"w-40",children:e.jsx(W,{})}),e.jsxs(q,{children:[e.jsx(a,{value:"viewer",children:"Viewer"}),e.jsx(a,{value:"engineer",children:"Engineer"}),e.jsx(a,{value:"designer",children:"Designer"}),e.jsx(a,{value:"product_manager",children:"Product Manager"}),e.jsx(a,{value:"manager",children:"Manager"}),e.jsx(a,{value:"admin",children:"Admin"})]})]}),e.jsxs(I,{open:E===s.id,onOpenChange:t=>{t||(u(null),m(""))},children:[e.jsx(M,{asChild:!0,children:e.jsx(l,{size:"sm",variant:"outline",onClick:()=>u(s.id),children:e.jsx(ye,{className:"h-4 w-4"})})}),e.jsxs($,{children:[e.jsxs(V,{children:[e.jsx(_,{children:"Reset Password"}),e.jsxs(z,{children:["Set a new password for ",s.name]})]}),e.jsx("div",{className:"space-y-4 py-4",children:e.jsxs("div",{children:[e.jsx(o,{htmlFor:"reset-password",children:"New Password"}),e.jsx(j,{id:"reset-password",type:"password",value:x,onChange:t=>m(t.target.value),placeholder:"At least 8 characters",minLength:8})]})}),e.jsxs(B,{children:[e.jsx(l,{variant:"outline",onClick:()=>{u(null),m("")},children:"Cancel"}),e.jsx(l,{onClick:ae,children:"Reset Password"})]})]})]}),s.id!==N?.id&&e.jsxs(oe,{children:[e.jsx(de,{asChild:!0,children:e.jsx(l,{size:"sm",variant:"destructive",children:e.jsx(he,{className:"h-4 w-4"})})}),e.jsxs(ue,{children:[e.jsxs(xe,{children:[e.jsx(me,{children:"Remove User"}),e.jsxs(ge,{children:["Are you sure you want to remove ",s.name," from the whitelist? They will no longer be able to access Coconut."]})]}),e.jsxs(je,{children:[e.jsx(pe,{children:"Cancel"}),e.jsx(ve,{onClick:()=>ie(s.id),children:"Remove"})]})]})]})]})]},s.id))})})]}),e.jsxs(p,{children:[e.jsxs(v,{children:[e.jsx(w,{children:"Session Settings"}),e.jsx(f,{children:"Configure session behavior and security."})]}),e.jsxs(y,{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"session-expiry",children:"Session Expiry"}),e.jsx(j,{id:"session-expiry",value:i.session.expiresIn,onChange:s=>d({...i,session:{...i.session,expiresIn:s.target.value}}),placeholder:"7d"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"Format: 30s, 15m, 24h, 7d"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"secure-cookies",children:"Secure Cookies (HTTPS only)"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Enable in production with HTTPS"})]}),e.jsx(U,{id:"secure-cookies",checked:i.session.secure||!1,onCheckedChange:s=>d({...i,session:{...i.session,secure:s}})})]})]})]}),e.jsxs("div",{className:"flex justify-end space-x-2",children:[e.jsx(l,{variant:"outline",onClick:h,disabled:S,children:"Cancel"}),e.jsx(l,{onClick:ne,disabled:S,children:S?"Saving...":"Save Session Settings"})]})]}):e.jsx("div",{className:"space-y-6",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"You don't have permission to manage authentication settings."})]})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Secure your Coconut instance with authentication."})]}),e.jsx(O,{}),e.jsxs(p,{children:[e.jsxs(v,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(we,{className:"h-5 w-5 text-muted-foreground"}),e.jsx(w,{children:"Authentication Not Configured"})]}),e.jsx(f,{children:"Authentication has not been initialized. Use the CLI to set up authentication."})]}),e.jsxs(y,{children:[e.jsx("div",{className:"bg-muted p-4 rounded-md",children:e.jsxs("code",{className:"text-sm",children:["$ nut auth init",e.jsx("br",{}),"$ nut auth toggle"]})}),e.jsx("p",{className:"text-sm text-muted-foreground mt-4",children:"This will create an admin user and enable authentication for your Coconut instance."})]})]})]})}export{Fe as default};
11
+ */const Ne=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]],Se=Y("user-plus",Ne);function Fe(){const{user:N,authEnabled:K,checkAuthStatus:Q}=le(),[i,d]=n.useState(null),[G,F]=n.useState(!0),[S,P]=n.useState(!1),[X,C]=n.useState(!1),[b,D]=n.useState(""),[A,R]=n.useState(""),[T,L]=n.useState("viewer"),[E,u]=n.useState(null),[x,m]=n.useState(""),Z=!K||N?.role==="admin";n.useEffect(()=>{h()},[]);const h=async()=>{try{F(!0);const s=await c("/api/v1/auth-settings");s.success?d(s.data):d(null)}catch(s){console.error("Failed to load auth settings:",s),d(null)}finally{F(!1)}},ee=async()=>{if(!i)return;const s=!i.enabled;try{const t=await c("/api/v1/auth-settings",{method:"PUT",body:JSON.stringify({enabled:s})});if(t.success)d({...i,enabled:s}),await Q(),r({title:"Success",description:`Authentication ${s?"enabled":"disabled"}`});else throw new Error(t.error||"Failed to toggle auth")}catch(t){r({title:"Error",description:t.message||"Failed to toggle authentication",variant:"destructive"})}},se=async()=>{if(!i)return;const s=!i.allowRegistration;try{const t=await c("/api/v1/auth-settings",{method:"PUT",body:JSON.stringify({allowRegistration:s})});if(t.success)d({...i,allowRegistration:s}),r({title:"Success",description:`Self-registration ${s?"enabled":"disabled"}`});else throw new Error(t.error||"Failed to update setting")}catch(t){r({title:"Error",description:t.message||"Failed to update setting",variant:"destructive"})}},te=async()=>{if(!b||!A){r({title:"Error",description:"Please provide email and name",variant:"destructive"});return}try{const s=await c("/api/v1/auth-settings/users",{method:"POST",body:JSON.stringify({email:b,name:A,role:T})});if(s.success)await h(),C(!1),D(""),R(""),L("viewer"),r({title:"Success",description:"User added to whitelist"});else throw new Error(s.error||"Failed to add user")}catch(s){r({title:"Error",description:s.message||"Failed to add user",variant:"destructive"})}},ie=async s=>{try{const t=await c(`/api/v1/auth-settings/users/${s}`,{method:"DELETE"});if(t.success)await h(),r({title:"Success",description:"User removed from whitelist"});else throw new Error(t.error||"Failed to remove user")}catch(t){r({title:"Error",description:t.message||"Failed to remove user",variant:"destructive"})}},re=async(s,t)=>{try{const g=await c(`/api/v1/auth-settings/users/${s}`,{method:"PUT",body:JSON.stringify({role:t})});if(g.success)await h(),r({title:"Success",description:"User role updated"});else throw new Error(g.error||"Failed to update role")}catch(g){r({title:"Error",description:g.message||"Failed to update role",variant:"destructive"})}},ae=async()=>{if(!(!E||!x)){if(x.length<8){r({title:"Error",description:"Password must be at least 8 characters",variant:"destructive"});return}try{const s=await c(`/api/v1/auth-settings/users/${E}/reset-password`,{method:"POST",body:JSON.stringify({newPassword:x})});if(s.success)u(null),m(""),r({title:"Success",description:"Password reset successfully"});else throw new Error(s.error||"Failed to reset password")}catch(s){r({title:"Error",description:s.message||"Failed to reset password",variant:"destructive"})}}},ne=async()=>{if(i)try{P(!0);const s=await c("/api/v1/auth-settings",{method:"PUT",body:JSON.stringify({session:i.session})});if(s.success)r({title:"Success",description:"Session settings updated"});else throw new Error(s.error||"Failed to update settings")}catch(s){r({title:"Error",description:s.message||"Failed to update settings",variant:"destructive"})}finally{P(!1)}};return G?e.jsx("div",{children:"Loading..."}):i?Z?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage authentication settings and user access."})]}),e.jsx(O,{}),e.jsxs(p,{children:[e.jsxs(v,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ce,{className:"h-5 w-5"}),e.jsx(w,{children:"Authentication Status"})]}),e.jsx(f,{children:"Control whether authentication is required to access Coconut."})]}),e.jsxs(y,{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"auth-enabled",children:"Require Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"When enabled, users must log in to access Coconut"})]}),e.jsx(U,{id:"auth-enabled",checked:i.enabled,onCheckedChange:ee})]}),i.enabled&&e.jsxs("div",{className:"flex items-center justify-between pt-2 border-t",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"allow-registration",children:"Allow Self-Registration"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Whitelisted users can create their own accounts"})]}),e.jsx(U,{id:"allow-registration",checked:i.allowRegistration,onCheckedChange:se})]})]})]}),e.jsxs(p,{children:[e.jsx(v,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(w,{children:"Whitelisted Users"}),e.jsx(f,{children:"Manage users who can access this Coconut instance."})]}),e.jsxs(I,{open:X,onOpenChange:C,children:[e.jsx(M,{asChild:!0,children:e.jsxs(l,{size:"sm",children:[e.jsx(Se,{className:"h-4 w-4 mr-2"}),"Add User"]})}),e.jsxs($,{children:[e.jsxs(V,{children:[e.jsx(_,{children:"Add User to Whitelist"}),e.jsx(z,{children:"Add a user's email to allow them to register and access Coconut."})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"new-email",children:"Email"}),e.jsx(j,{id:"new-email",type:"email",value:b,onChange:s=>D(s.target.value),placeholder:"user@example.com"})]}),e.jsxs("div",{children:[e.jsx(o,{htmlFor:"new-name",children:"Name"}),e.jsx(j,{id:"new-name",value:A,onChange:s=>R(s.target.value),placeholder:"User Name"})]}),e.jsxs("div",{children:[e.jsx(o,{htmlFor:"new-role",children:"Role"}),e.jsxs(H,{value:T,onValueChange:s=>L(s),children:[e.jsx(J,{children:e.jsx(W,{})}),e.jsxs(q,{children:[e.jsx(a,{value:"viewer",children:"Viewer"}),e.jsx(a,{value:"engineer",children:"Engineer"}),e.jsx(a,{value:"designer",children:"Designer"}),e.jsx(a,{value:"product_manager",children:"Product Manager"}),e.jsx(a,{value:"manager",children:"Manager"}),e.jsx(a,{value:"admin",children:"Admin"})]})]})]})]}),e.jsxs(B,{children:[e.jsx(l,{variant:"outline",onClick:()=>C(!1),children:"Cancel"}),e.jsx(l,{onClick:te,children:"Add User"})]})]})]})]})}),e.jsx(y,{children:e.jsx("div",{className:"space-y-4",children:i.providers.local.users.map(s=>e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{className:"space-y-1 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("p",{className:"font-medium",children:s.name}),s.registered?e.jsx(k,{variant:"default",className:"text-xs",children:"Registered"}):e.jsx(k,{variant:"secondary",className:"text-xs",children:"Pending"}),s.id===N?.id&&e.jsx(k,{variant:"outline",className:"text-xs",children:"You"})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:s.email}),s.lastLoginAt&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Last login: ",new Date(s.lastLoginAt).toLocaleString()]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(H,{value:s.role,onValueChange:t=>re(s.id,t),children:[e.jsx(J,{className:"w-40",children:e.jsx(W,{})}),e.jsxs(q,{children:[e.jsx(a,{value:"viewer",children:"Viewer"}),e.jsx(a,{value:"engineer",children:"Engineer"}),e.jsx(a,{value:"designer",children:"Designer"}),e.jsx(a,{value:"product_manager",children:"Product Manager"}),e.jsx(a,{value:"manager",children:"Manager"}),e.jsx(a,{value:"admin",children:"Admin"})]})]}),e.jsxs(I,{open:E===s.id,onOpenChange:t=>{t||(u(null),m(""))},children:[e.jsx(M,{asChild:!0,children:e.jsx(l,{size:"sm",variant:"outline",onClick:()=>u(s.id),children:e.jsx(ye,{className:"h-4 w-4"})})}),e.jsxs($,{children:[e.jsxs(V,{children:[e.jsx(_,{children:"Reset Password"}),e.jsxs(z,{children:["Set a new password for ",s.name]})]}),e.jsx("div",{className:"space-y-4 py-4",children:e.jsxs("div",{children:[e.jsx(o,{htmlFor:"reset-password",children:"New Password"}),e.jsx(j,{id:"reset-password",type:"password",value:x,onChange:t=>m(t.target.value),placeholder:"At least 8 characters",minLength:8})]})}),e.jsxs(B,{children:[e.jsx(l,{variant:"outline",onClick:()=>{u(null),m("")},children:"Cancel"}),e.jsx(l,{onClick:ae,children:"Reset Password"})]})]})]}),s.id!==N?.id&&e.jsxs(oe,{children:[e.jsx(de,{asChild:!0,children:e.jsx(l,{size:"sm",variant:"destructive",children:e.jsx(he,{className:"h-4 w-4"})})}),e.jsxs(ue,{children:[e.jsxs(xe,{children:[e.jsx(me,{children:"Remove User"}),e.jsxs(ge,{children:["Are you sure you want to remove ",s.name," from the whitelist? They will no longer be able to access Coconut."]})]}),e.jsxs(je,{children:[e.jsx(pe,{children:"Cancel"}),e.jsx(ve,{onClick:()=>ie(s.id),children:"Remove"})]})]})]})]})]},s.id))})})]}),e.jsxs(p,{children:[e.jsxs(v,{children:[e.jsx(w,{children:"Session Settings"}),e.jsx(f,{children:"Configure session behavior and security."})]}),e.jsxs(y,{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"session-expiry",children:"Session Expiry"}),e.jsx(j,{id:"session-expiry",value:i.session.expiresIn,onChange:s=>d({...i,session:{...i.session,expiresIn:s.target.value}}),placeholder:"7d"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"Format: 30s, 15m, 24h, 7d"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(o,{htmlFor:"secure-cookies",children:"Secure Cookies (HTTPS only)"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Enable in production with HTTPS"})]}),e.jsx(U,{id:"secure-cookies",checked:i.session.secure||!1,onCheckedChange:s=>d({...i,session:{...i.session,secure:s}})})]})]})]}),e.jsxs("div",{className:"flex justify-end space-x-2",children:[e.jsx(l,{variant:"outline",onClick:h,disabled:S,children:"Cancel"}),e.jsx(l,{onClick:ne,disabled:S,children:S?"Saving...":"Save Session Settings"})]})]}):e.jsx("div",{className:"space-y-6",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"You don't have permission to manage authentication settings."})]})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Secure your Coconut instance with authentication."})]}),e.jsx(O,{}),e.jsxs(p,{children:[e.jsxs(v,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(we,{className:"h-5 w-5 text-muted-foreground"}),e.jsx(w,{children:"Authentication Not Configured"})]}),e.jsx(f,{children:"Authentication has not been initialized. Use the CLI to set up authentication."})]}),e.jsxs(y,{children:[e.jsx("div",{className:"bg-muted p-4 rounded-md",children:e.jsxs("code",{className:"text-sm",children:["$ nut auth init",e.jsx("br",{}),"$ nut auth toggle"]})}),e.jsx("p",{className:"text-sm text-muted-foreground mt-4",children:"This will create an admin user and enable authentication for your Coconut instance."})]})]})]})}export{Fe as default};