@lovelybunch/api 1.0.75-alpha.5 → 1.0.75-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 (108) hide show
  1. package/dist/routes/api/v1/ai/route.js +4 -3
  2. package/dist/routes/api/v1/events/status/route.d.ts +1 -1
  3. package/dist/routes/api/v1/jobs/[id]/run/route.d.ts +2 -2
  4. package/dist/routes/api/v1/jobs/[id]/runs/[runId]/route.d.ts +2 -2
  5. package/dist/routes/api/v1/jobs/status/route.d.ts +1 -1
  6. package/dist/routes/api/v1/proposals/[id]/route.d.ts +8 -8
  7. package/dist/routes/api/v1/skills/[id]/index.d.ts +1 -0
  8. package/dist/routes/api/v1/skills/[id]/index.js +1 -0
  9. package/dist/routes/api/v1/skills/[id]/route.d.ts +3 -0
  10. package/dist/routes/api/v1/skills/[id]/route.js +199 -0
  11. package/dist/routes/api/v1/skills/index.d.ts +1 -0
  12. package/dist/routes/api/v1/skills/index.js +1 -0
  13. package/dist/routes/api/v1/skills/route.d.ts +3 -0
  14. package/dist/routes/api/v1/skills/route.js +329 -0
  15. package/dist/server-with-static.js +4 -4
  16. package/dist/server.js +4 -4
  17. package/package.json +6 -4
  18. package/static/assets/{ActivityPage-6xf2Jxp0.js → ActivityPage-QmXUVEPm.js} +1 -1
  19. package/static/assets/{ApiKeysSettingsPage-DlWMBuQb.js → ApiKeysSettingsPage-qie8F6gb.js} +1 -1
  20. package/static/assets/{ArchitectureEditPage-C6MWFHCp.js → ArchitectureEditPage-CPQnvHk4.js} +1 -1
  21. package/static/assets/{ArchitecturePage-CxQtPG4d.js → ArchitecturePage-CJNygJU2.js} +1 -1
  22. package/static/assets/{AuthSettingsPage-w0blkw8Q.js → AuthSettingsPage-B204F8bT.js} +1 -1
  23. package/static/assets/{CallbackPage-ByjWTMuG.js → CallbackPage-MGCRI7r_.js} +1 -1
  24. package/static/assets/CodePage-BxEsUJP-.js +2 -0
  25. package/static/assets/{CollapsibleSection-B1AU3exJ.js → CollapsibleSection-CtALgJpu.js} +1 -1
  26. package/static/assets/{DashboardPage-CAToLPqr.js → DashboardPage-DbvVqN24.js} +1 -1
  27. package/static/assets/{GitPage-DGjEzIUs.js → GitPage-D2bnwXyJ.js} +1 -1
  28. package/static/assets/{GitSettingsPage-X1GEO1Ti.js → GitSettingsPage-ZDdKMZl1.js} +1 -1
  29. package/static/assets/{IdentityPage-L0foq6qN.js → IdentityPage-Bu-duoN6.js} +1 -1
  30. package/static/assets/{ImplementationStepsEditor-Dn88eiVP.js → ImplementationStepsEditor-PDSNPMod.js} +1 -1
  31. package/static/assets/{IntegrationsSettingsPage-WX1lSaWr.js → IntegrationsSettingsPage-DsM2vBgQ.js} +1 -1
  32. package/static/assets/{JobDetailPage-CvNs3cEP.js → JobDetailPage-BBCASAAb.js} +1 -1
  33. package/static/assets/{KnowledgeDetailPage-DXjmZdQl.js → KnowledgeDetailPage-D1EptY9f.js} +1 -1
  34. package/static/assets/{KnowledgeEditPage-C70yoVFM.js → KnowledgeEditPage-Dd4B0Zol.js} +1 -1
  35. package/static/assets/{KnowledgePage-EUJ9c9By.js → KnowledgePage-ibFc3y1K.js} +1 -1
  36. package/static/assets/{LoginPage-Df_q-ACP.js → LoginPage-v8StIMKr.js} +1 -1
  37. package/static/assets/{McpSettingsPage-4b5M8tpH.js → McpSettingsPage-m5Wzim08.js} +1 -1
  38. package/static/assets/{NewKnowledgePage-CqKz6_K-.js → NewKnowledgePage-rmXqT_ay.js} +1 -1
  39. package/static/assets/{NewProposalPage-DR9UZich.js → NewProposalPage-CmMTQLo5.js} +1 -1
  40. package/static/assets/NewSkillPage-D3Fffhkj.js +1 -0
  41. package/static/assets/{ProjectEditPage-5YxG7Xxd.js → ProjectEditPage-C37nAWFP.js} +1 -1
  42. package/static/assets/{ProjectPage-BBhGv2fS.js → ProjectPage--_Q_QLC1.js} +1 -1
  43. package/static/assets/{PromptsSettingsPage-DLrpZcDA.js → PromptsSettingsPage-CGXj9CAs.js} +1 -1
  44. package/static/assets/{ProposalDetailPage-C4tagoNE.js → ProposalDetailPage-BUHhxZ3l.js} +1 -1
  45. package/static/assets/{ProposalEditPage-Bz-oEsLL.js → ProposalEditPage-C0eEdxJc.js} +1 -1
  46. package/static/assets/{ProposalsPage-BKRjNF4y.js → ProposalsPage-DyQC5FFd.js} +1 -1
  47. package/static/assets/{ResourcesPage-BZrToY-V.js → ResourcesPage-IrMHiK53.js} +1 -1
  48. package/static/assets/{RoleEditPage-C2vWadxy.js → RoleEditPage-Bw35Wz-d.js} +1 -1
  49. package/static/assets/{RolePage-CE9y3rMd.js → RolePage-BOjMgEYI.js} +1 -1
  50. package/static/assets/{RulesSettingsPage-BidnZaAT.js → RulesSettingsPage-B0eW6OmX.js} +1 -1
  51. package/static/assets/{SchedulePage-DU7ng6Gq.js → SchedulePage-CrfWjM5k.js} +1 -1
  52. package/static/assets/SkillDetailPage-CKDNJYXm.js +1 -0
  53. package/static/assets/SkillEditPage-DnBv-wu9.js +1 -0
  54. package/static/assets/SkillsPage-C5VD2DNt.js +8 -0
  55. package/static/assets/SkillsSettingsPage-D3M6mo3a.js +1 -0
  56. package/static/assets/{SourceInput-CCa7okhU.js → SourceInput-BN8ZVkqs.js} +1 -1
  57. package/static/assets/{TagInput-Chn207ze.js → TagInput-CICgcKUW.js} +1 -1
  58. package/static/assets/{TerminalPage-CEYgdKT2.js → TerminalPage-PJ6jkMN5.js} +1 -1
  59. package/static/assets/TerminalSessionPage-DuJ2n3mT.js +13 -0
  60. package/static/assets/{UserPreferencesPage-lPgr1ngr.js → UserPreferencesPage-CyNuAJru.js} +1 -1
  61. package/static/assets/{UserSettingsPage-ctHFqz6e.js → UserSettingsPage-Bq2TlR-8.js} +1 -1
  62. package/static/assets/{UtilitiesPage-BVxyh0Ce.js → UtilitiesPage-mZb2CtxF.js} +1 -1
  63. package/static/assets/{alert-D5jzRTa5.js → alert-CrqaDLRU.js} +1 -1
  64. package/static/assets/{arrow-down-4I_8gyhd.js → arrow-down-CfqDgiIx.js} +1 -1
  65. package/static/assets/{arrow-left-DZzHrGWA.js → arrow-left-CIkDScAO.js} +1 -1
  66. package/static/assets/{arrow-up-B4VxSS3_.js → arrow-up-DoOW0Uek.js} +1 -1
  67. package/static/assets/{badge-DvLOhob-.js → badge-ikmjXCY_.js} +1 -1
  68. package/static/assets/{browser-modal-DzaD2oDW.js → browser-modal-BJ16icY9.js} +1 -1
  69. package/static/assets/{calendar-BNe2rz1T.js → calendar-B3EFURS-.js} +1 -1
  70. package/static/assets/{card-BguljVtN.js → card-C0a11V0T.js} +1 -1
  71. package/static/assets/{chevron-left-DZQ_tMvU.js → chevron-left-Cbq2vuK_.js} +1 -1
  72. package/static/assets/{chevrons-up-BCenbxtV.js → chevrons-up-C3zGaueJ.js} +1 -1
  73. package/static/assets/{circle-alert-CZtpB74t.js → circle-alert-BZyc7kNR.js} +1 -1
  74. package/static/assets/{circle-check-hWIEYAMH.js → circle-check-CC67C1b-.js} +1 -1
  75. package/static/assets/{circle-check-big-CTApxALS.js → circle-check-big-tNM4uoO8.js} +1 -1
  76. package/static/assets/{circle-play-BF3gDlvZ.js → circle-play-DgDKRctX.js} +1 -1
  77. package/static/assets/{circle-x-BtYTEkcT.js → circle-x-CbIXbCmI.js} +1 -1
  78. package/static/assets/{clipboard-B8Tnfm3W.js → clipboard-Bhg2iYmV.js} +1 -1
  79. package/static/assets/{clock-_sj3uVNp.js → clock-DUwjJehj.js} +1 -1
  80. package/static/assets/{download-CPGv4d5Q.js → download-CAr6POG8.js} +1 -1
  81. package/static/assets/{droid-BWtMgfPD.js → droid-DqWsM2dp.js} +5 -5
  82. package/static/assets/{external-link-CtxWkvSs.js → external-link-C552Tasx.js} +1 -1
  83. package/static/assets/{eye-_nXnan_b.js → eye-F-BxEo2B.js} +1 -1
  84. package/static/assets/{folder-git-2-C_Zkp5wq.js → folder-git-2-BCO-gmji.js} +1 -1
  85. package/static/assets/{index-BlLRLvWP.js → index-Cb4mP03_.js} +9 -9
  86. package/static/assets/{info-fJ-d5-p-.js → info-DZ6rfcGz.js} +1 -1
  87. package/static/assets/{label-PINvlQb-.js → label-VXwOLYGm.js} +1 -1
  88. package/static/assets/{markdown-editor-B7Zxgu1u.js → markdown-editor-DKBU3Sgf.js} +1 -1
  89. package/static/assets/{pause-C9zNWRax.js → pause-CJhh_zgy.js} +1 -1
  90. package/static/assets/{play-BpXD0Ub0.js → play-DqF_TESp.js} +1 -1
  91. package/static/assets/{plus-DBJTL6qk.js → plus-B-nP-2Bc.js} +1 -1
  92. package/static/assets/{radio-group-DBaY5DVP.js → radio-group-CkXoX9re.js} +1 -1
  93. package/static/assets/{refresh-cw-SQsUc3_C.js → refresh-cw-DNCHo2vd.js} +1 -1
  94. package/static/assets/{search-CBNlhD-8.js → search-pT3zGN1p.js} +1 -1
  95. package/static/assets/{switch-C3ys7mIF.js → switch-DKgMJKx9.js} +1 -1
  96. package/static/assets/{tabs-BpxOu6UL.js → tabs-LRqYZP6q.js} +1 -1
  97. package/static/assets/{tag-Cu4oj34X.js → tag-CNJNVCjj.js} +1 -1
  98. package/static/assets/{terminal-preview-B5-BekLC.js → terminal-preview-C_hF2vLs.js} +1 -1
  99. package/static/assets/{use-terminal-CDMgbskg.js → use-terminal-B3kcgG1Q.js} +1 -1
  100. package/static/assets/{zap-LrtVPxxV.js → zap-DeMKwLsi.js} +1 -1
  101. package/static/index.html +1 -1
  102. package/static/assets/AgentDetailPage-1hbFBTeB.js +0 -1
  103. package/static/assets/AgentEditPage-qMmg057j.js +0 -1
  104. package/static/assets/AgentsPage-DyyJrXqo.js +0 -3
  105. package/static/assets/AgentsSettingsPage-Bf61k6i0.js +0 -6
  106. package/static/assets/CodePage-aWl0jKwx.js +0 -2
  107. package/static/assets/NewAgentPage-BqvZZJmC.js +0 -1
  108. package/static/assets/TerminalSessionPage-C8YA0AmM.js +0 -13
@@ -0,0 +1,329 @@
1
+ import { Hono } from 'hono';
2
+ import { promises as fs } from 'fs';
3
+ import path from 'path';
4
+ import matter from 'gray-matter';
5
+ import AdmZip from 'adm-zip';
6
+ const app = new Hono();
7
+ const ALLOWED_ARCHIVE_HOSTS = [
8
+ 'registry.coconut.dev',
9
+ ];
10
+ const MAX_ARCHIVE_SIZE = 50 * 1024 * 1024; // 50 MB
11
+ /** Paths to skip entirely when extracting zip archives (macOS resource forks, etc.) */
12
+ const IGNORED_ZIP_PREFIXES = ['__MACOSX/', '.DS_Store'];
13
+ function isIgnoredZipEntry(entryName) {
14
+ return IGNORED_ZIP_PREFIXES.some(prefix => entryName.startsWith(prefix) || entryName === prefix);
15
+ }
16
+ /**
17
+ * Detect if all zip entries share a single wrapping directory (e.g., `pptx/...`).
18
+ * Returns the prefix (with trailing slash) to strip, or null if no wrapper.
19
+ * Ignores macOS resource fork entries (__MACOSX/) when detecting the prefix.
20
+ */
21
+ function detectWrapperPrefix(entries) {
22
+ const paths = entries
23
+ .map(e => e.entryName)
24
+ .filter(name => name !== '/' && name !== '' && !isIgnoredZipEntry(name));
25
+ if (paths.length === 0)
26
+ return null;
27
+ const prefixes = new Set(paths.map(p => {
28
+ const firstSlash = p.indexOf('/');
29
+ return firstSlash >= 0 ? p.substring(0, firstSlash + 1) : null;
30
+ }));
31
+ // If all entries share exactly one prefix directory, strip it
32
+ if (prefixes.size === 1) {
33
+ const prefix = [...prefixes][0];
34
+ if (prefix !== null)
35
+ return prefix;
36
+ }
37
+ return null;
38
+ }
39
+ /**
40
+ * Download a zip archive from a trusted URL and extract it into destDir.
41
+ * Returns true if extraction succeeded and SKILL.md exists in the output.
42
+ */
43
+ async function downloadAndExtractArchive(archiveUrl, destDir) {
44
+ // Validate URL against allow-list
45
+ let parsed;
46
+ try {
47
+ parsed = new URL(archiveUrl);
48
+ }
49
+ catch {
50
+ throw new Error('Invalid archive URL');
51
+ }
52
+ if (!ALLOWED_ARCHIVE_HOSTS.includes(parsed.hostname)) {
53
+ throw new Error(`Archive host '${parsed.hostname}' is not trusted`);
54
+ }
55
+ // Download the zip
56
+ const response = await fetch(archiveUrl, {
57
+ headers: { 'User-Agent': 'coconut-api' },
58
+ });
59
+ if (!response.ok) {
60
+ throw new Error(`Failed to download archive: ${response.status} ${response.statusText}`);
61
+ }
62
+ const contentLength = Number(response.headers.get('content-length') || '0');
63
+ if (contentLength > MAX_ARCHIVE_SIZE) {
64
+ throw new Error(`Archive too large (${contentLength} bytes, max ${MAX_ARCHIVE_SIZE})`);
65
+ }
66
+ const buffer = Buffer.from(await response.arrayBuffer());
67
+ if (buffer.length > MAX_ARCHIVE_SIZE) {
68
+ throw new Error(`Archive too large (${buffer.length} bytes, max ${MAX_ARCHIVE_SIZE})`);
69
+ }
70
+ // Extract with path-traversal protection
71
+ const zip = new AdmZip(buffer);
72
+ const entries = zip.getEntries();
73
+ const wrapperPrefix = detectWrapperPrefix(entries);
74
+ await fs.mkdir(destDir, { recursive: true });
75
+ for (const entry of entries) {
76
+ let entryName = entry.entryName;
77
+ // Skip macOS resource fork junk and other ignored entries
78
+ if (isIgnoredZipEntry(entryName))
79
+ continue;
80
+ // Strip single wrapping directory if detected (e.g., pptx/SKILL.md -> SKILL.md)
81
+ if (wrapperPrefix && entryName.startsWith(wrapperPrefix)) {
82
+ entryName = entryName.substring(wrapperPrefix.length);
83
+ }
84
+ if (!entryName || entryName === '/')
85
+ continue;
86
+ // Reject paths that attempt directory traversal
87
+ const resolved = path.resolve(destDir, entryName);
88
+ if (!resolved.startsWith(path.resolve(destDir) + path.sep) && resolved !== path.resolve(destDir)) {
89
+ console.warn(`Skipping zip entry with path traversal: ${entryName}`);
90
+ continue;
91
+ }
92
+ if (entry.isDirectory) {
93
+ await fs.mkdir(resolved, { recursive: true });
94
+ }
95
+ else {
96
+ await fs.mkdir(path.dirname(resolved), { recursive: true });
97
+ await fs.writeFile(resolved, entry.getData());
98
+ }
99
+ }
100
+ // Check if SKILL.md was extracted
101
+ try {
102
+ await fs.access(path.join(destDir, 'SKILL.md'));
103
+ return true;
104
+ }
105
+ catch {
106
+ return false;
107
+ }
108
+ }
109
+ /**
110
+ * Validate skill name per Agent Skills spec:
111
+ * - 1-64 characters
112
+ * - Lowercase letters, numbers, hyphens only
113
+ * - No leading/trailing hyphens
114
+ * - No consecutive hyphens
115
+ */
116
+ function validateSkillName(name) {
117
+ if (!name || name.length === 0)
118
+ return 'Name is required';
119
+ if (name.length > 64)
120
+ return 'Name must be 64 characters or fewer';
121
+ if (!/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(name)) {
122
+ return 'Name must contain only lowercase letters, numbers, and hyphens, and must not start or end with a hyphen';
123
+ }
124
+ if (/--/.test(name))
125
+ return 'Name must not contain consecutive hyphens';
126
+ return null;
127
+ }
128
+ function generateSkillId(name) {
129
+ return name
130
+ .toLowerCase()
131
+ .replace(/[^a-z0-9\s-]/g, '')
132
+ .replace(/\s+/g, '-')
133
+ .replace(/--+/g, '-')
134
+ .replace(/^-|-$/g, '');
135
+ }
136
+ function getSkillsPath() {
137
+ let basePath;
138
+ if (process.env.NODE_ENV === 'development' && process.env.GAIT_DEV_ROOT) {
139
+ basePath = process.env.GAIT_DEV_ROOT;
140
+ }
141
+ else if (process.env.GAIT_DATA_PATH) {
142
+ basePath = path.resolve(process.env.GAIT_DATA_PATH, '.nut');
143
+ }
144
+ else {
145
+ basePath = path.resolve(process.cwd(), '.nut');
146
+ }
147
+ return path.join(basePath, 'skills');
148
+ }
149
+ /**
150
+ * GET /api/v1/skills
151
+ * Load all skill documents
152
+ */
153
+ app.get('/', async (c) => {
154
+ try {
155
+ const skillsPath = getSkillsPath();
156
+ await fs.mkdir(skillsPath, { recursive: true });
157
+ const entries = await fs.readdir(skillsPath, { withFileTypes: true });
158
+ const skills = await Promise.all(entries
159
+ .filter(entry => entry.isDirectory())
160
+ .map(async (entry) => {
161
+ const skillFile = path.join(skillsPath, entry.name, 'SKILL.md');
162
+ try {
163
+ const fileContent = await fs.readFile(skillFile, 'utf-8');
164
+ const { data, content } = matter(fileContent);
165
+ const nestedMeta = typeof data.metadata === 'object' ? data.metadata : undefined;
166
+ const doc = {
167
+ id: entry.name,
168
+ name: data.name || entry.name,
169
+ description: data.description || '',
170
+ ...(data.license ? { license: data.license } : {}),
171
+ ...(data.compatibility ? { compatibility: data.compatibility } : {}),
172
+ ...(data['allowed-tools'] || data.allowedTools ? { allowedTools: data['allowed-tools'] || data.allowedTools } : {}),
173
+ metadata: {
174
+ name: data.name || entry.name,
175
+ description: data.description || '',
176
+ ...(nestedMeta || {}),
177
+ },
178
+ content,
179
+ };
180
+ return doc;
181
+ }
182
+ catch {
183
+ // Skip directories without valid SKILL.md
184
+ return null;
185
+ }
186
+ }));
187
+ const validSkills = skills.filter((s) => s !== null);
188
+ return c.json({
189
+ success: true,
190
+ documents: validSkills.sort((a, b) => a.id.localeCompare(b.id))
191
+ });
192
+ }
193
+ catch (error) {
194
+ console.error('Error loading skill documents:', error);
195
+ return c.json({
196
+ success: false,
197
+ error: 'Failed to load skill documents',
198
+ documents: []
199
+ }, 500);
200
+ }
201
+ });
202
+ /**
203
+ * POST /api/v1/skills
204
+ * Create a new skill document
205
+ */
206
+ app.post('/', async (c) => {
207
+ try {
208
+ const body = await c.req.json();
209
+ if (!body.name || !body.description) {
210
+ return c.json({ success: false, error: 'Name and description are required' }, 400);
211
+ }
212
+ const skillId = generateSkillId(body.name);
213
+ const nameError = validateSkillName(skillId);
214
+ if (nameError) {
215
+ return c.json({ success: false, error: nameError }, 400);
216
+ }
217
+ const skillsPath = getSkillsPath();
218
+ const skillDir = path.join(skillsPath, skillId);
219
+ // Check if skill directory already exists
220
+ try {
221
+ await fs.access(path.join(skillDir, 'SKILL.md'));
222
+ return c.json({ success: false, error: 'A skill with this name already exists' }, 409);
223
+ }
224
+ catch {
225
+ // Doesn't exist, proceed
226
+ }
227
+ // Create skill directory
228
+ await fs.mkdir(skillDir, { recursive: true });
229
+ let finalContent = body.content || '';
230
+ if (body.archiveUrl) {
231
+ // Download and extract archive — SKILL.md comes from the zip
232
+ try {
233
+ const hasSkillMd = await downloadAndExtractArchive(body.archiveUrl, skillDir);
234
+ if (!hasSkillMd) {
235
+ // Fallback: generate SKILL.md from JSON fields if the archive didn't include one
236
+ const frontmatter = {
237
+ name: skillId,
238
+ description: body.description,
239
+ };
240
+ if (body.license)
241
+ frontmatter.license = body.license;
242
+ if (body.compatibility)
243
+ frontmatter.compatibility = body.compatibility;
244
+ if (body.allowedTools)
245
+ frontmatter['allowed-tools'] = body.allowedTools;
246
+ if (body.metadata && Object.keys(body.metadata).length > 0) {
247
+ const meta = {};
248
+ for (const [key, value] of Object.entries(body.metadata)) {
249
+ if (value !== undefined && value !== null) {
250
+ meta[key] = value;
251
+ }
252
+ }
253
+ if (Object.keys(meta).length > 0) {
254
+ frontmatter.metadata = meta;
255
+ }
256
+ }
257
+ const fileContent = matter.stringify(finalContent, frontmatter);
258
+ await fs.writeFile(path.join(skillDir, 'SKILL.md'), fileContent, 'utf-8');
259
+ }
260
+ // Read back SKILL.md content for the response
261
+ try {
262
+ const written = await fs.readFile(path.join(skillDir, 'SKILL.md'), 'utf-8');
263
+ const { data: extractedFrontmatter, content: mdContent } = matter(written);
264
+ finalContent = mdContent;
265
+ // If the extracted SKILL.md body is empty but we have registry content,
266
+ // append it as a fallback and rewrite the file
267
+ if (!mdContent.trim() && body.content?.trim()) {
268
+ const rewritten = matter.stringify(body.content, extractedFrontmatter);
269
+ await fs.writeFile(path.join(skillDir, 'SKILL.md'), rewritten, 'utf-8');
270
+ finalContent = body.content;
271
+ }
272
+ }
273
+ catch {
274
+ // best effort
275
+ }
276
+ }
277
+ catch (archiveError) {
278
+ // Clean up the directory on failure
279
+ await fs.rm(skillDir, { recursive: true, force: true }).catch(() => { });
280
+ return c.json({ success: false, error: `Archive extraction failed: ${archiveError.message}` }, 400);
281
+ }
282
+ }
283
+ else {
284
+ // No archive — build SKILL.md from JSON fields (existing behavior)
285
+ const frontmatter = {
286
+ name: skillId,
287
+ description: body.description,
288
+ };
289
+ if (body.license)
290
+ frontmatter.license = body.license;
291
+ if (body.compatibility)
292
+ frontmatter.compatibility = body.compatibility;
293
+ if (body.allowedTools)
294
+ frontmatter['allowed-tools'] = body.allowedTools;
295
+ if (body.metadata && Object.keys(body.metadata).length > 0) {
296
+ const meta = {};
297
+ for (const [key, value] of Object.entries(body.metadata)) {
298
+ if (value !== undefined && value !== null) {
299
+ meta[key] = value;
300
+ }
301
+ }
302
+ if (Object.keys(meta).length > 0) {
303
+ frontmatter.metadata = meta;
304
+ }
305
+ }
306
+ const fileContent = matter.stringify(finalContent, frontmatter);
307
+ await fs.writeFile(path.join(skillDir, 'SKILL.md'), fileContent, 'utf-8');
308
+ }
309
+ return c.json({
310
+ success: true,
311
+ document: {
312
+ id: skillId,
313
+ name: skillId,
314
+ description: body.description,
315
+ metadata: {
316
+ name: skillId,
317
+ description: body.description,
318
+ ...(body.metadata || {}),
319
+ },
320
+ content: finalContent
321
+ }
322
+ }, 201);
323
+ }
324
+ catch (error) {
325
+ console.error('Error creating skill document:', error);
326
+ return c.json({ success: false, error: 'Failed to create skill document' }, 500);
327
+ }
328
+ });
329
+ export default app;
@@ -171,8 +171,8 @@ import resourcesThumbnail from './routes/api/v1/resources/[id]/thumbnail/index.j
171
171
  import context from './routes/api/v1/context/index.js';
172
172
  import config from './routes/api/v1/config/index.js';
173
173
  import user from './routes/api/v1/user/index.js';
174
- import agents from './routes/api/v1/agents/index.js';
175
- import agentsById from './routes/api/v1/agents/[id]/index.js';
174
+ import skills from './routes/api/v1/skills/index.js';
175
+ import skillsById from './routes/api/v1/skills/[id]/index.js';
176
176
  import identity, { readAgentCard, PUBLIC_AGENT_CARD_PATH } from './routes/api/v1/identity/index.js';
177
177
  import git from './routes/api/v1/git/index.js';
178
178
  import mcp from './routes/api/v1/mcp/index.js';
@@ -198,8 +198,8 @@ app.route('/api/v1/resources/:id/thumbnail', resourcesThumbnail);
198
198
  app.route('/api/v1/context', context);
199
199
  app.route('/api/v1/config', config);
200
200
  app.route('/api/v1/user', user);
201
- app.route('/api/v1/agents', agents);
202
- app.route('/api/v1/agents/:id', agentsById);
201
+ app.route('/api/v1/skills', skills);
202
+ app.route('/api/v1/skills/:id', skillsById);
203
203
  app.route('/api/v1/identity', identity);
204
204
  app.route('/api/v1/git', git);
205
205
  app.route('/api/v1/mcp', mcp);
package/dist/server.js CHANGED
@@ -170,8 +170,8 @@ import resourcesThumbnail from './routes/api/v1/resources/[id]/thumbnail/index.j
170
170
  import context from './routes/api/v1/context/index.js';
171
171
  import config from './routes/api/v1/config/index.js';
172
172
  import user from './routes/api/v1/user/index.js';
173
- import agents from './routes/api/v1/agents/index.js';
174
- import agentsById from './routes/api/v1/agents/[id]/index.js';
173
+ import skills from './routes/api/v1/skills/index.js';
174
+ import skillsById from './routes/api/v1/skills/[id]/index.js';
175
175
  import identity, { readAgentCard, PUBLIC_AGENT_CARD_PATH } from './routes/api/v1/identity/index.js';
176
176
  import git from './routes/api/v1/git/index.js';
177
177
  import mcp from './routes/api/v1/mcp/index.js';
@@ -197,8 +197,8 @@ app.route('/api/v1/resources/:id/thumbnail', resourcesThumbnail);
197
197
  app.route('/api/v1/context', context);
198
198
  app.route('/api/v1/config', config);
199
199
  app.route('/api/v1/user', user);
200
- app.route('/api/v1/agents', agents);
201
- app.route('/api/v1/agents/:id', agentsById);
200
+ app.route('/api/v1/skills', skills);
201
+ app.route('/api/v1/skills/:id', skillsById);
202
202
  app.route('/api/v1/identity', identity);
203
203
  app.route('/api/v1/git', git);
204
204
  app.route('/api/v1/mcp', mcp);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovelybunch/api",
3
- "version": "1.0.75-alpha.5",
3
+ "version": "1.0.75-alpha.6",
4
4
  "type": "module",
5
5
  "main": "dist/server-with-static.js",
6
6
  "exports": {
@@ -37,9 +37,10 @@
37
37
  "@ai-sdk/anthropic": "^3.0.41",
38
38
  "@hono/node-server": "^1.13.7",
39
39
  "@hono/node-ws": "^1.0.6",
40
- "@lovelybunch/core": "^1.0.75-alpha.5",
41
- "@lovelybunch/mcp": "^1.0.75-alpha.5",
42
- "@lovelybunch/types": "^1.0.75-alpha.5",
40
+ "@lovelybunch/core": "^1.0.75-alpha.6",
41
+ "@lovelybunch/mcp": "^1.0.75-alpha.6",
42
+ "@lovelybunch/types": "^1.0.75-alpha.6",
43
+ "adm-zip": "^0.5.16",
43
44
  "ai": "^6.0.79",
44
45
  "arctic": "^1.9.2",
45
46
  "bcrypt": "^5.1.1",
@@ -56,6 +57,7 @@
56
57
  "zod": "^3.23.0"
57
58
  },
58
59
  "devDependencies": {
60
+ "@types/adm-zip": "^0.5.7",
59
61
  "@types/bcrypt": "^5.0.2",
60
62
  "@types/cookie": "^0.6.0",
61
63
  "@types/jsonwebtoken": "^9.0.5",
@@ -1 +1 @@
1
- import{r as a,A as p,j as e,H as v,bh as y,B as N,v as w,C as b}from"./index-BlLRLvWP.js";import{C as c,a as d,b as k,c as C}from"./card-BguljVtN.js";import{B as m}from"./badge-DvLOhob-.js";import{R as E}from"./refresh-cw-SQsUc3_C.js";const A=5e3;function $(){const[n,o]=a.useState([]),[i,x]=a.useState(!0),[h,u]=a.useState(new Set),l=a.useCallback(async()=>{x(!0);try{const s=await fetch(`${p}/api/v1/events?limit=${A}`);if(!s.ok)throw new Error("Failed to load events");const t=await s.json();o(Array.isArray(t.items)?[...t.items].reverse():[])}catch(s){console.error("Failed to load events:",s),o([])}finally{x(!1)}},[]),g=a.useCallback(s=>{u(t=>{const r=new Set(t);return r.has(s)?r.delete(s):r.add(s),r})},[]);a.useEffect(()=>{l()},[l]);const f=s=>{if(!s)return"Unknown time";try{return new Date(s).toLocaleString()}catch{return s}},j=s=>{switch(s?.toLowerCase()){case"error":return"bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200";case"warn":case"warning":return"bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200";case"info":return"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200";case"debug":return"bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-200";default:return"bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-200"}};return i?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold tracking-tight",children:"Activity"}),e.jsx("p",{className:"text-muted-foreground",children:"View system activity and events"})]}),e.jsx(c,{children:e.jsx(d,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center justify-center",children:[e.jsx(v,{className:"h-8 w-8 animate-spin text-muted-foreground"}),e.jsx("span",{className:"ml-2 text-muted-foreground",children:"Loading events..."})]})})})]}):n.length===0?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold tracking-tight",children:"Activity"}),e.jsx("p",{className:"text-muted-foreground",children:"View system activity and events"})]}),e.jsx(c,{children:e.jsx(d,{className:"pt-6",children:e.jsxs("div",{className:"text-center",children:[e.jsx(y,{className:"mx-auto h-12 w-12 text-muted-foreground"}),e.jsx("h3",{className:"mt-4 text-lg font-semibold",children:"No Events Found"}),e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:"Activity events will appear here as they occur."})]})})})]}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold tracking-tight",children:"Activity"}),e.jsxs("p",{className:"text-muted-foreground",children:["View system activity and events (",n.length," events)"]})]}),e.jsxs(N,{variant:"outline",size:"sm",onClick:()=>void l(),disabled:i,children:[e.jsx(E,{className:`h-4 w-4 mr-2 ${i?"animate-spin":""}`}),"Refresh"]})]}),e.jsx("div",{className:"space-y-3",children:n.map(s=>{const t=h.has(s.seq);return e.jsxs(c,{className:"transition-colors",children:[e.jsx(k,{className:"py-3 cursor-pointer hover:bg-muted/30",onClick:()=>g(s.seq),children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex items-start gap-2 flex-1 min-w-0",children:[t?e.jsx(w,{className:"h-4 w-4 mt-0.5 text-muted-foreground shrink-0"}):e.jsx(b,{className:"h-4 w-4 mt-0.5 text-muted-foreground shrink-0"}),e.jsxs("div",{className:"space-y-1 flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsxs(C,{className:"text-sm font-medium",children:["#",s.seq]}),s.kind&&e.jsx(m,{variant:"outline",className:"text-xs",children:s.kind}),s.level&&e.jsx(m,{className:`text-xs ${j(s.level)}`,children:s.level})]}),s.message&&e.jsx("p",{className:`text-sm text-muted-foreground ${t?"":"truncate"}`,children:s.message})]})]}),e.jsx("span",{className:"text-xs text-muted-foreground whitespace-nowrap",children:f(s.ts)})]})}),t&&e.jsx(d,{className:"pt-0 pb-4",children:e.jsx("pre",{className:"text-xs bg-muted p-3 rounded-md overflow-x-auto",children:JSON.stringify(s,null,2)})})]},s.seq)})})]})}export{$ as default};
1
+ import{r as a,A as p,j as e,H as v,bh as y,B as N,v as w,C as b}from"./index-Cb4mP03_.js";import{C as c,a as d,b as k,c as C}from"./card-C0a11V0T.js";import{B as m}from"./badge-ikmjXCY_.js";import{R as E}from"./refresh-cw-DNCHo2vd.js";const A=5e3;function $(){const[n,o]=a.useState([]),[i,x]=a.useState(!0),[h,u]=a.useState(new Set),l=a.useCallback(async()=>{x(!0);try{const s=await fetch(`${p}/api/v1/events?limit=${A}`);if(!s.ok)throw new Error("Failed to load events");const t=await s.json();o(Array.isArray(t.items)?[...t.items].reverse():[])}catch(s){console.error("Failed to load events:",s),o([])}finally{x(!1)}},[]),g=a.useCallback(s=>{u(t=>{const r=new Set(t);return r.has(s)?r.delete(s):r.add(s),r})},[]);a.useEffect(()=>{l()},[l]);const f=s=>{if(!s)return"Unknown time";try{return new Date(s).toLocaleString()}catch{return s}},j=s=>{switch(s?.toLowerCase()){case"error":return"bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200";case"warn":case"warning":return"bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200";case"info":return"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200";case"debug":return"bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-200";default:return"bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-200"}};return i?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold tracking-tight",children:"Activity"}),e.jsx("p",{className:"text-muted-foreground",children:"View system activity and events"})]}),e.jsx(c,{children:e.jsx(d,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center justify-center",children:[e.jsx(v,{className:"h-8 w-8 animate-spin text-muted-foreground"}),e.jsx("span",{className:"ml-2 text-muted-foreground",children:"Loading events..."})]})})})]}):n.length===0?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold tracking-tight",children:"Activity"}),e.jsx("p",{className:"text-muted-foreground",children:"View system activity and events"})]}),e.jsx(c,{children:e.jsx(d,{className:"pt-6",children:e.jsxs("div",{className:"text-center",children:[e.jsx(y,{className:"mx-auto h-12 w-12 text-muted-foreground"}),e.jsx("h3",{className:"mt-4 text-lg font-semibold",children:"No Events Found"}),e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:"Activity events will appear here as they occur."})]})})})]}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold tracking-tight",children:"Activity"}),e.jsxs("p",{className:"text-muted-foreground",children:["View system activity and events (",n.length," events)"]})]}),e.jsxs(N,{variant:"outline",size:"sm",onClick:()=>void l(),disabled:i,children:[e.jsx(E,{className:`h-4 w-4 mr-2 ${i?"animate-spin":""}`}),"Refresh"]})]}),e.jsx("div",{className:"space-y-3",children:n.map(s=>{const t=h.has(s.seq);return e.jsxs(c,{className:"transition-colors",children:[e.jsx(k,{className:"py-3 cursor-pointer hover:bg-muted/30",onClick:()=>g(s.seq),children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex items-start gap-2 flex-1 min-w-0",children:[t?e.jsx(w,{className:"h-4 w-4 mt-0.5 text-muted-foreground shrink-0"}):e.jsx(b,{className:"h-4 w-4 mt-0.5 text-muted-foreground shrink-0"}),e.jsxs("div",{className:"space-y-1 flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsxs(C,{className:"text-sm font-medium",children:["#",s.seq]}),s.kind&&e.jsx(m,{variant:"outline",className:"text-xs",children:s.kind}),s.level&&e.jsx(m,{className:`text-xs ${j(s.level)}`,children:s.level})]}),s.message&&e.jsx("p",{className:`text-sm text-muted-foreground ${t?"":"truncate"}`,children:s.message})]})]}),e.jsx("span",{className:"text-xs text-muted-foreground whitespace-nowrap",children:f(s.ts)})]})}),t&&e.jsx(d,{className:"pt-0 pb-4",children:e.jsx("pre",{className:"text-xs bg-muted p-3 rounded-md overflow-x-auto",children:JSON.stringify(s,null,2)})})]},s.seq)})})]})}export{$ as default};
@@ -1,2 +1,2 @@
1
- import{E as J,r as t,b5 as y,j as e,B as a,b6 as R,V as X,D as j,b as g,d as v,f,g as A,I as F,a5 as N,am as Y,J as i}from"./index-BlLRLvWP.js";import{C as V,b as W,c as G,d as Q,a as Z}from"./card-BguljVtN.js";import{L as w}from"./label-PINvlQb-.js";import{B as _}from"./badge-DvLOhob-.js";import{A as I,a as C}from"./alert-D5jzRTa5.js";import{I as L}from"./info-fJ-d5-p-.js";import{P as ee}from"./plus-DBJTL6qk.js";import{C as se}from"./circle-alert-CZtpB74t.js";function de(){const{authEnabled:n}=J(),[P,k]=t.useState([]),[b,K]=t.useState(!0),[O,l]=t.useState(!1),[M,d]=t.useState(!1),[x,D]=t.useState(""),[h,E]=t.useState("never"),[c,S]=t.useState(null),[m,o]=t.useState(null);t.useEffect(()=>{p()},[]);const p=async()=>{K(!0);try{const s=await y("/api/v1/api-keys");s.success&&k(s.data?.apiKeys||[])}catch(s){console.error("Failed to load API keys:",s),k([])}finally{K(!1)}},U=async()=>{if(!x.trim()){i({title:"Error",description:"Please provide a name for the API key",variant:"destructive"});return}try{const s={name:x,scopes:["*"]};h!=="never"&&(s.expiresIn=h);const r=await y("/api/v1/api-keys",{method:"POST",body:JSON.stringify(s)});r.success&&(S(r.data),l(!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(),o(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"})}},H=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"}),$=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}" \\
1
+ import{E as J,r as t,b5 as y,j as e,B as a,b6 as R,V as X,D as j,b as g,d as v,f,g as A,I as F,a5 as N,am as Y,J as i}from"./index-Cb4mP03_.js";import{C as V,b as W,c as G,d as Q,a as Z}from"./card-C0a11V0T.js";import{L as w}from"./label-VXwOLYGm.js";import{B as _}from"./badge-ikmjXCY_.js";import{A as I,a as C}from"./alert-CrqaDLRU.js";import{I as L}from"./info-DZ6rfcGz.js";import{P as ee}from"./plus-B-nP-2Bc.js";import{C as se}from"./circle-alert-BZyc7kNR.js";function de(){const{authEnabled:n}=J(),[P,k]=t.useState([]),[b,K]=t.useState(!0),[O,l]=t.useState(!1),[M,d]=t.useState(!1),[x,D]=t.useState(""),[h,E]=t.useState("never"),[c,S]=t.useState(null),[m,o]=t.useState(null);t.useEffect(()=>{p()},[]);const p=async()=>{K(!0);try{const s=await y("/api/v1/api-keys");s.success&&k(s.data?.apiKeys||[])}catch(s){console.error("Failed to load API keys:",s),k([])}finally{K(!1)}},U=async()=>{if(!x.trim()){i({title:"Error",description:"Please provide a name for the API key",variant:"destructive"});return}try{const s={name:x,scopes:["*"]};h!=="never"&&(s.expiresIn=h);const r=await y("/api/v1/api-keys",{method:"POST",body:JSON.stringify(s)});r.success&&(S(r.data),l(!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(),o(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"})}},H=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"}),$=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}" \\
2
2
  + ${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(V,{children:[e.jsx(W,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(G,{children:"Active API Keys"}),e.jsx(Q,{children:"API keys you've created for programmatic access"})]}),e.jsxs(a,{onClick:()=>l(!0),disabled:!n,children:[e.jsx(ee,{className:"mr-2 h-4 w-4"}),"Create API Key"]})]})}),e.jsx(Z,{children:P.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:P.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}),$(s.expiresAt)&&e.jsx(_,{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:()=>o(s.id),children:e.jsx(X,{className:"h-4 w-4 text-destructive"})})]},s.id))})})]}),e.jsx(j,{open:O,onOpenChange:l,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:x,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:h,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:()=>l(!1),children:"Cancel"}),e.jsx(a,{onClick:U,disabled:!n,children:"Create API Key"})]})]})}),e.jsx(j,{open:M,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(se,{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:()=>H(c.key),children:e.jsx(Y,{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&&o(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:()=>o(null),children:"Cancel"}),e.jsx(a,{variant:"destructive",onClick:()=>m&&B(m),children:"Delete API Key"})]})]})})]})}export{de as default};
@@ -1,4 +1,4 @@
1
- import{u as D,a as M,r as l,A as b,j as e,B as S,L as I,a7 as _,I as d,w as B}from"./index-BlLRLvWP.js";import{C as u,a as p,b as j,c as v}from"./card-BguljVtN.js";import{L as o}from"./label-PINvlQb-.js";import{M as P}from"./markdown-editor-B7Zxgu1u.js";import{A as R}from"./arrow-left-DZzHrGWA.js";import{C as $}from"./circle-check-big-CTApxALS.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,a as M,r as l,A as b,j as e,B as S,L as I,a7 as _,I as d,w as B}from"./index-Cb4mP03_.js";import{C as u,a as p,b as j,c as v}from"./card-C0a11V0T.js";import{L as o}from"./label-VXwOLYGm.js";import{M as P}from"./markdown-editor-DKBU3Sgf.js";import{A as R}from"./arrow-left-CIkDScAO.js";import{C as $}from"./circle-check-big-tNM4uoO8.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{a as g,r as n,A as v,j as e,H as y,F as k,B as l,M as b,aB as w,L as C,Q as E,ay as A}from"./index-BlLRLvWP.js";import{C as a,a as c,b as o,c as m}from"./card-BguljVtN.js";import{c as D}from"./clipboard-B9ndUJKl.js";function S(){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{S as default};
1
+ import{a as g,r as n,A as v,j as e,H as y,F as k,B as l,M as b,aB as w,L as C,Q as E,ay as A}from"./index-Cb4mP03_.js";import{C as a,a as c,b as o,c as m}from"./card-C0a11V0T.js";import{c as D}from"./clipboard-B9ndUJKl.js";function S(){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{S as default};
@@ -1,4 +1,4 @@
1
- import{c as Y,E as le,r as n,b5 as c,j as e,a6 as I,o as ce,D as O,a4 as $,B as l,b as M,d as V,f as J,g as _,I as j,h as H,i as z,k as W,l as q,m as a,a5 as B,R as oe,U as de,V as he,W as ue,Y as xe,Z as me,_ as ge,$ as je,a0 as pe,a1 as ve,J as r}from"./index-BlLRLvWP.js";import{C as p,b as v,c as w,d as f,a as y}from"./card-BguljVtN.js";import{L as o}from"./label-PINvlQb-.js";import{S as U}from"./switch-C3ys7mIF.js";import{B as k}from"./badge-DvLOhob-.js";import{C as we}from"./circle-alert-CZtpB74t.js";/**
1
+ import{c as Y,E as le,r as n,b5 as c,j as e,a6 as I,o as ce,D as O,a4 as $,B as l,b as M,d as V,f as J,g as _,I as j,h as H,i as z,k as W,l as q,m as a,a5 as B,R as oe,U as de,V as he,W as ue,Y as xe,Z as me,_ as ge,$ as je,a0 as pe,a1 as ve,J as r}from"./index-Cb4mP03_.js";import{C as p,b as v,c as w,d as f,a as y}from"./card-C0a11V0T.js";import{L as o}from"./label-VXwOLYGm.js";import{S as U}from"./switch-DKgMJKx9.js";import{B as k}from"./badge-ikmjXCY_.js";import{C as we}from"./circle-alert-BZyc7kNR.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{r as m,j as e,H as x,A as f}from"./index-BlLRLvWP.js";import{C as w}from"./circle-check-hWIEYAMH.js";import{C as b}from"./circle-x-BtYTEkcT.js";const r="coconut/github-auth-state";function j(s){try{window.opener&&window.opener.postMessage({type:"github-auth",...s},window.location.origin)}catch{}}const v=()=>{const[s,d]=m.useState("pending"),[h,p]=m.useState("Authorizing GitHub…");return m.useEffect(()=>{const a=new URLSearchParams(window.location.search),u=a.get("error"),l=a.get("token"),n=a.get("expires_at")||a.get("expiresAt"),c=a.get("state"),o=t=>{j(t),d(t.success?"success":"error"),p(t.message),setTimeout(()=>{try{window.close()}catch{}},1200)};if(u){localStorage.removeItem(r),o({success:!1,message:decodeURIComponent(u)});return}if(!l||!n||!c){localStorage.removeItem(r),o({success:!1,message:"Missing authorization parameters. Please try again."});return}const g=localStorage.getItem(r);if(!g||g!==c){localStorage.removeItem(r),o({success:!1,message:"Authorization state mismatch. Please start again."});return}(async()=>{try{const t=await fetch(`${f}/api/v1/git/providers/github/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:l,expiresAt:n,state:c})}),i=await t.json();if(!t.ok||!i.success)throw new Error(i?.error?.message||"Failed to store GitHub token");localStorage.removeItem(r),o({success:!0,message:"GitHub connected successfully!",expiresAt:i.data?.expiresAt||n})}catch(t){localStorage.removeItem(r),o({success:!1,message:t?.message||"Failed to store GitHub token. Please try again."})}})()},[]),e.jsx("div",{className:"flex h-screen items-center justify-center bg-background px-6",children:e.jsxs("div",{className:"max-w-sm rounded-lg border bg-card p-6 text-center shadow-sm",children:[e.jsxs("div",{className:"mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted",children:[s==="pending"&&e.jsx(x,{className:"h-6 w-6 animate-spin text-muted-foreground"}),s==="success"&&e.jsx(w,{className:"h-6 w-6 text-green-600"}),s==="error"&&e.jsx(b,{className:"h-6 w-6 text-red-600"})]}),e.jsx("h1",{className:"text-lg font-semibold",children:"GitHub Authorization"}),e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:h}),s!=="pending"&&e.jsx("p",{className:"mt-4 text-xs text-muted-foreground",children:"You can close this window and return to Coconut."})]})})};export{v as default};
1
+ import{r as m,j as e,H as x,A as f}from"./index-Cb4mP03_.js";import{C as w}from"./circle-check-CC67C1b-.js";import{C as b}from"./circle-x-CbIXbCmI.js";const r="coconut/github-auth-state";function j(s){try{window.opener&&window.opener.postMessage({type:"github-auth",...s},window.location.origin)}catch{}}const v=()=>{const[s,d]=m.useState("pending"),[h,p]=m.useState("Authorizing GitHub…");return m.useEffect(()=>{const a=new URLSearchParams(window.location.search),u=a.get("error"),l=a.get("token"),n=a.get("expires_at")||a.get("expiresAt"),c=a.get("state"),o=t=>{j(t),d(t.success?"success":"error"),p(t.message),setTimeout(()=>{try{window.close()}catch{}},1200)};if(u){localStorage.removeItem(r),o({success:!1,message:decodeURIComponent(u)});return}if(!l||!n||!c){localStorage.removeItem(r),o({success:!1,message:"Missing authorization parameters. Please try again."});return}const g=localStorage.getItem(r);if(!g||g!==c){localStorage.removeItem(r),o({success:!1,message:"Authorization state mismatch. Please start again."});return}(async()=>{try{const t=await fetch(`${f}/api/v1/git/providers/github/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:l,expiresAt:n,state:c})}),i=await t.json();if(!t.ok||!i.success)throw new Error(i?.error?.message||"Failed to store GitHub token");localStorage.removeItem(r),o({success:!0,message:"GitHub connected successfully!",expiresAt:i.data?.expiresAt||n})}catch(t){localStorage.removeItem(r),o({success:!1,message:t?.message||"Failed to store GitHub token. Please try again."})}})()},[]),e.jsx("div",{className:"flex h-screen items-center justify-center bg-background px-6",children:e.jsxs("div",{className:"max-w-sm rounded-lg border bg-card p-6 text-center shadow-sm",children:[e.jsxs("div",{className:"mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted",children:[s==="pending"&&e.jsx(x,{className:"h-6 w-6 animate-spin text-muted-foreground"}),s==="success"&&e.jsx(w,{className:"h-6 w-6 text-green-600"}),s==="error"&&e.jsx(b,{className:"h-6 w-6 text-red-600"})]}),e.jsx("h1",{className:"text-lg font-semibold",children:"GitHub Authorization"}),e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:h}),s!=="pending"&&e.jsx("p",{className:"mt-4 text-xs text-muted-foreground",children:"You can close this window and return to Coconut."})]})})};export{v as default};
@@ -0,0 +1,2 @@
1
+ import{u as ce,a as de,r as i,j as e,B as l,q as oe,T as me,O as xe,v as M,X as he,F as ue,Q as fe,D as pe,b as je,d as ge,f as ve,h as Ne,i as ye,k as we,l as Se,m as C,p as Ce,a9 as B,aa as R,ab as O,ac as H,ad as L,ai as G,ah as be,w as ke,A as I}from"./index-Cb4mP03_.js";import{C as g,b as Ae,a as _,c as De}from"./card-C0a11V0T.js";import{B as U}from"./badge-ikmjXCY_.js";import{u as Me}from"./use-terminal-B3kcgG1Q.js";import{T as Ie}from"./terminal-preview-C_hF2vLs.js";import{b as Te,d as $e,c as Ee,a as Pe}from"./droid-DqWsM2dp.js";import{R as ze}from"./refresh-cw-DNCHo2vd.js";import{C as Fe,a as Be}from"./chevrons-up-C3zGaueJ.js";import{P as Re}from"./play-DqF_TESp.js";import"./xterm-DTxiCjtJ.js";const Oe=c=>c?Array.isArray(c)?c.filter(x=>typeof x=="string").map(x=>x.trim()).filter(Boolean):typeof c=="string"?c.split(",").map(x=>x.trim()).filter(Boolean):[]:[];function Je(){const c=ce(),{sessions:x,loading:b,error:T,refreshSessions:w,createSession:V,destroySession:q}=Me(),{toast:v}=de(),[$,W]=i.useState([]),[Q,X]=i.useState(!0),[p,k]=i.useState(()=>({})),[A,N]=i.useState(!1),[j,J]=i.useState("claude"),[E,K]=i.useState(""),[D,P]=i.useState(!1),[h,Y]=i.useState([]),[f,y]=i.useState([]),[Z,ee]=i.useState({}),[u,se]=i.useState([]),[o,S]=i.useState([]),te=s=>{const t=Date.now(),a=new Date(s).getTime(),n=Math.max(0,Math.floor((t-a)/1e3));if(n<60)return`${n}s ago`;const d=Math.floor(n/60);if(d<60)return`${d}m ago`;const r=Math.floor(d/60);return r<24?`${r}h ago`:`${Math.floor(r/24)}d ago`};i.useEffect(()=>{(async()=>{try{const t=await fetch(`${I}/api/v1/proposals`);if(t.ok){const a=await t.json(),n=a.data||a;W(Array.isArray(n)?n:[])}}catch(t){console.error("Error loading proposals:",t)}finally{X(!1)}})()},[]),i.useEffect(()=>{w()},[w]),i.useEffect(()=>{if(!A)return;(async()=>{try{const t=await fetch(`${I}/api/v1/mcp`);if(t.ok){const a=await t.json();a?.success&&Array.isArray(a.servers)&&(Y(a.servers),y(n=>n.filter(d=>a.servers.includes(d))),a.mcpServers&&typeof a.mcpServers=="object"&&ee(a.mcpServers))}}catch(t){console.error("Failed to load MCP servers",t)}try{const t=await fetch(`${I}/api/v1/skills`);if(t.ok){const a=await t.json(),d=(Array.isArray(a?.documents)?a.documents:[]).map(r=>({id:r.id,name:r?.metadata?.name||r.id,mcpServers:Oe(r?.metadata?.metadata?.mcpServers)}));se(d),S(r=>r.filter(F=>d.some(re=>re.id===F)))}}catch(t){console.error("Failed to load skills",t)}})()},[A]),i.useEffect(()=>{o.length!==0&&y(s=>{const t=new Set(s),a=h.length>0?new Set(h):void 0;return o.forEach(n=>{const d=u.find(r=>r.id===n);d&&d.mcpServers.forEach(r=>{(!a||a.has(r))&&t.add(r)})}),Array.from(t)})},[o,u,h]);const m=i.useMemo(()=>x.filter(s=>s.proposalId?.startsWith("cp-")||s.proposalId?.startsWith("ag-")).sort((s,t)=>new Date(t.lastActivity).getTime()-new Date(s.lastActivity).getTime()),[x]);i.useEffect(()=>{k(s=>{const t={...s};return m.forEach(a=>{a.id in t||(t[a.id]=!0)}),t})},[m]);const z=i.useMemo(()=>$.filter(s=>s.status==="draft"||s.status==="ready").sort((s,t)=>new Date(t.metadata.createdAt).getTime()-new Date(s.metadata.createdAt).getTime()).slice(0,3),[$]),ae=()=>{const s=m.every(a=>p[a.id]),t={};m.forEach(a=>{t[a.id]=!s}),k(t)},ie=m.length>0&&m.every(s=>p[s.id]),ne=async s=>{await q(s)?(v({title:"Session closed",description:s}),setTimeout(()=>w(),100)):v({title:"Failed to close session",description:s,variant:"destructive"})},le=async()=>{P(!0);try{const s=`cp-${Date.now()}`,t={proposalId:s,contextType:"change-proposal",cliAgent:j,mcpServersMap:Z,selectedMcpServers:f,skills:u,selectedSkillIds:o,automationEnabled:!1,customInstruction:E.trim(),includeDefaultInstructions:!1};let a="";j==="claude"?a=Te(t):j==="gemini"?a=$e(t):j==="codex"?a=Ee(t):j==="droid"&&(a=Pe(t)),await V(s,!1,a)?(v({title:"Coding session started",description:`Session ${s} created`}),N(!1),c(`/terminal/${s}`)):v({title:"Failed to start session",description:"Could not create terminal session",variant:"destructive"})}catch(s){console.error("Error starting coding session:",s),v({title:"Error",description:"Failed to start coding session",variant:"destructive"})}finally{P(!1)}};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:"Code"}),e.jsx("p",{className:"text-muted-foreground hidden sm:block",children:"Terminal sessions and coding agents"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(l,{variant:"outline",size:"sm",onClick:()=>w(),disabled:b,children:[e.jsx(ze,{className:`h-4 w-4 sm:mr-2 ${b?"animate-spin":""}`}),e.jsx("span",{className:"hidden sm:inline",children:"Refresh"})]}),m.length>0&&e.jsx(l,{variant:"outline",size:"sm",onClick:ae,children:ie?e.jsxs(e.Fragment,{children:[e.jsx(Fe,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Hide All"})]}):e.jsxs(e.Fragment,{children:[e.jsx(Be,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Show All"})]})}),e.jsxs(l,{size:"sm",onClick:()=>N(!0),children:[e.jsx(Re,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Interactive Session"})]})]})]}),T&&e.jsx("div",{className:"p-4 bg-red-50 border border-red-200 rounded-lg",children:e.jsx("div",{className:"text-red-600",children:T})}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Sessions"}),b?e.jsx("div",{className:"space-y-2",children:[...Array(2)].map((s,t)=>e.jsx(g,{className:"p-3",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"h-4 w-4 rounded bg-muted animate-pulse"}),e.jsxs("div",{children:[e.jsx("div",{className:"h-4 w-40 bg-muted rounded animate-pulse mb-2"}),e.jsx("div",{className:"h-3 w-24 bg-muted rounded animate-pulse"})]})]}),e.jsx("div",{className:"h-6 w-20 bg-muted rounded animate-pulse"})]})},t))}):m.length===0?e.jsx(g,{className:"p-8",children:e.jsxs("div",{className:"flex flex-col items-center justify-center text-center space-y-3",children:[e.jsx(oe,{className:"h-12 w-12 text-muted-foreground"}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold text-lg mb-2",children:"No active sessions"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Get started by launching an"," ",e.jsx("button",{onClick:()=>N(!0),className:"text-primary hover:underline font-medium",children:"Interactive Session"})," ","or working on a"," ",e.jsx("button",{onClick:()=>c("/proposals"),className:"text-primary hover:underline font-medium",children:"Change Proposal"})]})]})]})}):e.jsx("div",{className:"space-y-2",children:m.slice(0,10).map(s=>e.jsxs(g,{className:"p-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(me,{className:"h-4 w-4 shrink-0"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"font-medium text-sm",children:s.proposalId}),e.jsxs("div",{className:"text-xs text-gray-500",children:["Session ",s.id.split("-").slice(-1)[0].substring(0,8)," • Last activity ",te(s.lastActivity)]})]})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx("div",{className:`flex items-center gap-1 ${s.connected?"text-green-600":"text-gray-400"}`,title:s.connected?"Connected":"Disconnected",children:e.jsx("div",{className:`w-2 h-2 rounded-full ${s.connected?"bg-green-500":"bg-gray-400"}`})}),e.jsx(l,{size:"sm",variant:"outline",onClick:()=>{k(t=>({...t,[s.id]:!t[s.id]}))},"aria-label":p[s.id]?"Hide preview":"Show preview",title:p[s.id]?"Hide preview":"Show preview",children:p[s.id]?e.jsx(xe,{className:"h-4 w-4"}):e.jsx(M,{className:"h-4 w-4"})}),e.jsx(l,{size:"sm",variant:"outline",onClick:()=>c(`/terminal/${s.proposalId}`),children:"Open"}),e.jsx(l,{size:"icon",variant:"destructive",onClick:()=>ne(s.id),title:"Close session","aria-label":"Close session",children:e.jsx(he,{className:"h-4 w-4"})})]})]}),p[s.id]&&e.jsx("div",{className:"mt-2 w-full p-2 cursor-pointer hover:opacity-80 transition-opacity",onClick:()=>c(`/terminal/${s.proposalId}`),title:"Click to open full terminal session",children:e.jsx(Ie,{sessionId:s.id,heightPx:160,maxScrollback:200})})]},s.id))})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"New Tasks"}),Q?e.jsx("div",{className:"space-y-3",children:[...Array(3)].map((s,t)=>e.jsx(g,{children:e.jsx(Ae,{className:"py-3",children:e.jsxs("div",{className:"flex justify-between items-start",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"h-4 bg-muted rounded w-2/3 animate-pulse"}),e.jsx("div",{className:"h-3 bg-muted rounded w-1/3 animate-pulse"})]}),e.jsx("div",{className:"h-5 bg-muted rounded w-16 animate-pulse"})]})})},t))}):z.length===0?e.jsx(g,{children:e.jsx(_,{className:"flex items-center justify-center py-6",children:e.jsx("div",{className:"text-center text-sm text-gray-500",children:"No draft or approved proposals found"})})}):e.jsx("div",{className:"space-y-2",children:z.map(s=>e.jsx(g,{className:"hover:shadow-md transition-all cursor-pointer hover:border-primary/50",onClick:()=>c(`/terminal/${s.id}`),children:e.jsx(_,{className:"py-4",children:e.jsx("div",{className:"flex justify-between items-start gap-4",children:e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsx(De,{className:"text-base leading-tight",children:s.title||s.intent}),e.jsxs("div",{className:"flex gap-1 ml-3 flex-shrink-0",children:[s.priority&&e.jsx(U,{variant:s.priority==="high"||s.priority==="critical"?"destructive":s.priority==="medium"?"secondary":"outline",className:"text-xs",children:s.priority}),e.jsx(U,{variant:"default",className:"text-xs",children:s.status})]})]}),s.content&&e.jsxs("div",{className:"text-sm text-muted-foreground leading-relaxed",children:[s.content.split(`
2
+ `).slice(0,2).join(" ").substring(0,150),s.content.length>150?"...":""]}),e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs("div",{className:"text-xs text-muted-foreground",children:[s.id," • by ",s.author.name," • ",new Date(s.metadata.createdAt).toLocaleDateString()]}),e.jsxs("div",{className:"flex gap-2",onClick:t=>t.stopPropagation(),children:[e.jsxs(l,{variant:"ghost",size:"sm",onClick:()=>c(`/proposals/${s.id}`),className:"h-7 px-2 text-xs",children:[e.jsx(ue,{className:"h-3 w-3 mr-1"})," View"]}),e.jsxs(l,{variant:"ghost",size:"sm",onClick:()=>c(`/proposals/${s.id}/edit`),className:"h-7 px-2 text-xs",children:[e.jsx(fe,{className:"h-3 w-3 mr-1"})," Edit"]})]})]})]})})})},s.id))})]}),e.jsx(pe,{open:A,onOpenChange:N,children:e.jsxs(je,{className:"max-w-lg",children:[e.jsxs(ge,{children:[e.jsx(ve,{children:"Start Coding Agent"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-2",children:"Start an interactive coding session"})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium mb-2 block",children:"Coding Agent"}),e.jsxs(Ne,{value:j,onValueChange:s=>J(s),children:[e.jsx(ye,{className:"w-full",children:e.jsx(we,{placeholder:"Select coding agent"})}),e.jsxs(Se,{children:[e.jsx(C,{value:"claude",children:"Claude Code"}),e.jsx(C,{value:"gemini",children:"Google Gemini"}),e.jsx(C,{value:"codex",children:"OpenAI Codex"}),e.jsx(C,{value:"droid",children:"Factory Droid"})]})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsxs("div",{className:"text-sm font-medium flex items-center gap-2",children:[e.jsx(Ce,{className:"h-4 w-4"}),"Skills"]}),e.jsxs("div",{className:"text-xs text-gray-500",children:[o.length," of ",u.length," selected"]})]}),e.jsxs(B,{children:[e.jsx(R,{asChild:!0,children:e.jsxs(l,{variant:"outline",className:"w-full justify-between",children:[o.length===0?"Select skills...":o.length===u.length?"All skills selected":`${o.length} skill${o.length!==1?"s":""} selected`,e.jsx(M,{className:"h-4 w-4 opacity-50"})]})}),e.jsxs(O,{className:"w-full min-w-[--radix-dropdown-menu-trigger-width]",children:[e.jsxs(H,{className:"flex items-center justify-between",children:[e.jsx("span",{children:"Available Skills"}),e.jsxs("div",{className:"flex gap-1",children:[e.jsx(l,{size:"sm",variant:"ghost",className:"h-5 px-1 text-xs",onClick:s=>{s.preventDefault(),S(u.map(t=>t.id))},children:"All"}),e.jsx(l,{size:"sm",variant:"ghost",className:"h-5 px-1 text-xs",onClick:s=>{s.preventDefault(),S([])},children:"None"})]})]}),e.jsx(L,{}),u.length===0?e.jsx("div",{className:"px-2 py-1.5 text-sm text-gray-500",children:"No skills found"}):u.map(s=>e.jsx(G,{checked:o.includes(s.id),onCheckedChange:t=>{S(a=>t?a.includes(s.id)?a:[...a,s.id]:a.filter(n=>n!==s.id))},children:e.jsxs("div",{className:"flex flex-col",children:[e.jsx("span",{children:s.name}),s.mcpServers.length>0&&e.jsxs("span",{className:"text-xs text-muted-foreground",children:["MCP servers: ",s.mcpServers.join(", ")]}),s.mcpServers.length===0&&e.jsx("span",{className:"text-xs text-muted-foreground",children:"Inherits available MCP servers"})]})},s.id))]})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsxs("div",{className:"text-sm font-medium flex items-center gap-2",children:[e.jsx(be,{className:"h-4 w-4"}),"MCP Servers"]}),e.jsxs("div",{className:"text-xs text-gray-500",children:[f.length," of ",h.length," selected"]})]}),e.jsxs(B,{children:[e.jsx(R,{asChild:!0,children:e.jsxs(l,{variant:"outline",className:"w-full justify-between",children:[f.length===0?"Select MCP servers...":f.length===h.length?"All servers selected":`${f.length} server${f.length!==1?"s":""} selected`,e.jsx(M,{className:"h-4 w-4 opacity-50"})]})}),e.jsxs(O,{className:"w-full min-w-[--radix-dropdown-menu-trigger-width]",children:[e.jsxs(H,{className:"flex items-center justify-between",children:[e.jsx("span",{children:"Available Servers"}),e.jsxs("div",{className:"flex gap-1",children:[e.jsx(l,{size:"sm",variant:"ghost",className:"h-5 px-1 text-xs",onClick:s=>{s.preventDefault(),y(h)},children:"All"}),e.jsx(l,{size:"sm",variant:"ghost",className:"h-5 px-1 text-xs",onClick:s=>{s.preventDefault(),y([])},children:"None"})]})]}),e.jsx(L,{}),h.length===0?e.jsx("div",{className:"px-2 py-1.5 text-sm text-gray-500",children:"No MCP servers found"}):h.map(s=>e.jsx(G,{checked:f.includes(s),onCheckedChange:t=>{y(a=>t?a.includes(s)?a:[...a,s]:a.filter(n=>n!==s))},children:s},s))]})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium mb-2 block",children:"Additional Instructions (optional)"}),e.jsx(ke,{value:E,onChange:s=>K(s.target.value),placeholder:"Add any custom instructions for the coding agent...",rows:4,className:"resize-none"})]}),e.jsxs("div",{className:"flex justify-end gap-2 pt-2",children:[e.jsx(l,{variant:"outline",onClick:()=>N(!1),disabled:D,children:"Cancel"}),e.jsx(l,{onClick:le,disabled:D,children:D?"Starting...":"Start Session"})]})]})]})})]})}export{Je as default};
@@ -1 +1 @@
1
- import{r as x,j as e,e as a,v as m}from"./index-BlLRLvWP.js";function u({title:r,description:t,icon:n,defaultOpen:o=!1,children:i,className:l}){const[s,d]=x.useState(o);return e.jsxs("div",{className:a("rounded-lg border bg-card text-card-foreground",l),children:[e.jsxs("button",{type:"button",onClick:()=>d(c=>!c),className:"flex w-full items-center justify-between gap-4 px-4 py-3 text-left","aria-expanded":s,children:[e.jsxs("div",{className:"flex items-center gap-3",children:[n,e.jsxs("div",{children:[e.jsx("p",{className:"font-medium leading-tight",children:r}),t&&e.jsx("p",{className:"text-sm text-muted-foreground leading-snug",children:t})]})]}),e.jsx(m,{className:a("h-4 w-4 shrink-0 transition-transform duration-200",s?"rotate-180":"rotate-0")})]}),s&&e.jsx("div",{className:"border-t px-4 py-4",children:i})]})}export{u as C};
1
+ import{r as x,j as e,e as a,v as m}from"./index-Cb4mP03_.js";function u({title:r,description:t,icon:n,defaultOpen:o=!1,children:i,className:l}){const[s,d]=x.useState(o);return e.jsxs("div",{className:a("rounded-lg border bg-card text-card-foreground",l),children:[e.jsxs("button",{type:"button",onClick:()=>d(c=>!c),className:"flex w-full items-center justify-between gap-4 px-4 py-3 text-left","aria-expanded":s,children:[e.jsxs("div",{className:"flex items-center gap-3",children:[n,e.jsxs("div",{children:[e.jsx("p",{className:"font-medium leading-tight",children:r}),t&&e.jsx("p",{className:"text-sm text-muted-foreground leading-snug",children:t})]})]}),e.jsx(m,{className:a("h-4 w-4 shrink-0 transition-transform duration-200",s?"rotate-180":"rotate-0")})]}),s&&e.jsx("div",{className:"border-t px-4 py-4",children:i})]})}export{u as C};
@@ -1,4 +1,4 @@
1
- import{c as b,u as Pe,a as Re,r as l,j as e,D as Le,b as De,d as te,e as f,f as ae,g as ne,S as re,B as d,C as le,I as E,h as oe,i as ce,k as ie,l as de,m as V,n as G,o as Ie,G as _e,F as ze,p as ue,q as We,s as qe,t as W,T as me,v as Fe,w as Be,L as v,M as Ee,K as A,x as g,y as Ve,A as Ke}from"./index-BlLRLvWP.js";import{C as h,a as u,b as P,c as R,d as xe}from"./card-BguljVtN.js";import{B as $e}from"./badge-DvLOhob-.js";import{g as Ge}from"./status-utils-BDOyevaX.js";import{L as He}from"./label-PINvlQb-.js";import{u as Oe}from"./use-terminal-CDMgbskg.js";import{T as Ye}from"./terminal-preview-B5-BekLC.js";import{C as Qe}from"./circle-check-hWIEYAMH.js";import{C as Ue}from"./chevron-left-DZQ_tMvU.js";import{S as Ze}from"./search-CBNlhD-8.js";import{Z as Je}from"./zap-LrtVPxxV.js";import{C as Xe}from"./calendar-BNe2rz1T.js";import{F as es}from"./folder-git-2-C_Zkp5wq.js";import{E as ss}from"./external-link-CtxWkvSs.js";import{P as ts}from"./play-BpXD0Ub0.js";import{C as as}from"./clock-_sj3uVNp.js";import{C as ns}from"./circle-check-big-CTApxALS.js";import{P as rs}from"./plus-DBJTL6qk.js";import"./xterm-DTxiCjtJ.js";/**
1
+ import{c as b,u as Pe,a as Re,r as l,j as e,D as Le,b as De,d as te,e as f,f as ae,g as ne,S as re,B as d,C as le,I as E,h as oe,i as ce,k as ie,l as de,m as V,n as G,o as Ie,G as _e,F as ze,p as ue,q as We,s as qe,t as W,T as me,v as Fe,w as Be,L as v,M as Ee,K as A,x as g,y as Ve,A as Ke}from"./index-Cb4mP03_.js";import{C as h,a as u,b as P,c as R,d as xe}from"./card-C0a11V0T.js";import{B as $e}from"./badge-ikmjXCY_.js";import{g as Ge}from"./status-utils-BDOyevaX.js";import{L as He}from"./label-VXwOLYGm.js";import{u as Oe}from"./use-terminal-B3kcgG1Q.js";import{T as Ye}from"./terminal-preview-C_hF2vLs.js";import{C as Qe}from"./circle-check-CC67C1b-.js";import{C as Ue}from"./chevron-left-Cbq2vuK_.js";import{S as Ze}from"./search-pT3zGN1p.js";import{Z as Je}from"./zap-DeMKwLsi.js";import{C as Xe}from"./calendar-B3EFURS-.js";import{F as es}from"./folder-git-2-BCO-gmji.js";import{E as ss}from"./external-link-C552Tasx.js";import{P as ts}from"./play-DqF_TESp.js";import{C as as}from"./clock-DUwjJehj.js";import{C as ns}from"./circle-check-big-tNM4uoO8.js";import{P as rs}from"./plus-B-nP-2Bc.js";import"./xterm-DTxiCjtJ.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as le,A as l,be as ws,r as n,a as vs,ak as ys,j as e,L as ee,s as Fe,B as o,G as D,ag as Ns,X as Cs,I as k,O as Me,v as Be,V as Oe,D as se,b as te,d as ae,f as re,g as ne,b6 as ks,a5 as Re}from"./index-BlLRLvWP.js";import{C as ie}from"./card-BguljVtN.js";import{L as Ge}from"./label-PINvlQb-.js";import{T as Ss,a as Ps,b as We,c as ze}from"./tabs-BpxOu6UL.js";import{C as Ts}from"./circle-check-hWIEYAMH.js";import{C as As}from"./circle-x-BtYTEkcT.js";import{A as Ds}from"./arrow-down-4I_8gyhd.js";import{A as Es}from"./arrow-up-B4VxSS3_.js";import{R as Ue}from"./refresh-cw-SQsUc3_C.js";import{C as ce}from"./circle-alert-CZtpB74t.js";import{F as oe}from"./folder-git-2-C_Zkp5wq.js";/**
1
+ import{c as le,A as l,be as ws,r as n,a as vs,ak as ys,j as e,L as ee,s as Fe,B as o,G as D,ag as Ns,X as Cs,I as k,O as Me,v as Be,V as Oe,D as se,b as te,d as ae,f as re,g as ne,b6 as ks,a5 as Re}from"./index-Cb4mP03_.js";import{C as ie}from"./card-C0a11V0T.js";import{L as Ge}from"./label-VXwOLYGm.js";import{T as Ss,a as Ps,b as We,c as ze}from"./tabs-LRqYZP6q.js";import{C as Ts}from"./circle-check-CC67C1b-.js";import{C as As}from"./circle-x-CbIXbCmI.js";import{A as Ds}from"./arrow-down-CfqDgiIx.js";import{A as Es}from"./arrow-up-DoOW0Uek.js";import{R as Ue}from"./refresh-cw-DNCHo2vd.js";import{C as ce}from"./circle-alert-BZyc7kNR.js";import{F as oe}from"./folder-git-2-BCO-gmji.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as He,r,a as Te,A as u,j as e,a6 as he,B as o,V as Fe,H as De,b6 as ze,I as U,D as W,b as B,d as q,f as J,g as K,a5 as V}from"./index-BlLRLvWP.js";import{C as xe,b as pe,c as ge,d as fe,a as be}from"./card-BguljVtN.js";import{L as f}from"./label-PINvlQb-.js";import{R as Me,a as je}from"./radio-group-DBaY5DVP.js";import{R as A}from"./refresh-cw-SQsUc3_C.js";import{E as ve}from"./external-link-CtxWkvSs.js";import{C as Oe}from"./circle-check-hWIEYAMH.js";import{C as Ie}from"./circle-x-BtYTEkcT.js";/**
1
+ import{c as He,r,a as Te,A as u,j as e,a6 as he,B as o,V as Fe,H as De,b6 as ze,I as U,D as W,b as B,d as q,f as J,g as K,a5 as V}from"./index-Cb4mP03_.js";import{C as xe,b as pe,c as ge,d as fe,a as be}from"./card-C0a11V0T.js";import{L as f}from"./label-VXwOLYGm.js";import{R as Me,a as je}from"./radio-group-CkXoX9re.js";import{R as A}from"./refresh-cw-DNCHo2vd.js";import{E as ve}from"./external-link-C552Tasx.js";import{C as Oe}from"./circle-check-CC67C1b-.js";import{C as Ie}from"./circle-x-CbIXbCmI.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.