@lovelybunch/api 1.0.78-alpha.0 → 1.0.78-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/routes/api/v1/context/architecture/route.d.ts +3 -0
- package/dist/routes/api/v1/context/architecture/route.js +245 -0
- package/dist/routes/api/v1/context/project/route.d.ts +3 -0
- package/dist/routes/api/v1/context/project/route.js +200 -0
- package/dist/routes/api/v1/jobs/[id]/route.d.ts +8 -8
- package/dist/routes/api/v1/jobs/route.d.ts +8 -8
- package/dist/routes/api/v1/mail/route.d.ts +3 -3
- package/package.json +4 -4
- package/static/assets/{ActivityPage-DiwGC2nD.js → ActivityPage-GDXCtp2F.js} +1 -1
- package/static/assets/{AgentsContextEditPage-Xh10BIpD.js → AgentsContextEditPage-DoMluWwB.js} +1 -1
- package/static/assets/{AgentsContextPage-DYLVgjBy.js → AgentsContextPage-CXHbtOdz.js} +1 -1
- package/static/assets/{ApiKeysSettingsPage-21Rz7etb.js → ApiKeysSettingsPage-DbstsqyB.js} +1 -1
- package/static/assets/{AuthSettingsPage-CuDQH02c.js → AuthSettingsPage-CK9eFJo0.js} +1 -1
- package/static/assets/{CallbackPage-Fok1FSep.js → CallbackPage-BFE5x2Hd.js} +1 -1
- package/static/assets/{CoconutCallbackPage-CJCSsq2v.js → CoconutCallbackPage-D2aFrloh.js} +1 -1
- package/static/assets/{CodePage-CzEzWmjy.js → CodePage-BfUucBak.js} +1 -1
- package/static/assets/{CollapsibleSection-CAtdqP8-.js → CollapsibleSection-Cu7uJYqA.js} +1 -1
- package/static/assets/{DashboardPage-i5uE_kdH.js → DashboardPage-xDDYm5-7.js} +1 -1
- package/static/assets/{GitPage-Do-L6D0R.js → GitPage-Ca_CKgGJ.js} +1 -1
- package/static/assets/{GitSettingsPage-GZ5wAGvy.js → GitSettingsPage-Bx0JsYW4.js} +1 -1
- package/static/assets/{IdentityPage-BJe8PLkl.js → IdentityPage-DbG7B63H.js} +1 -1
- package/static/assets/{ImplementationStepsEditor-C5ERpOXx.js → ImplementationStepsEditor-D_eIbq-s.js} +1 -1
- package/static/assets/{IntegrationsSettingsPage-Bw9hlc_l.js → IntegrationsSettingsPage-2lBY2pzo.js} +1 -1
- package/static/assets/{JobDetailPage-DvPv3vVS.js → JobDetailPage-DVIv1yvM.js} +1 -1
- package/static/assets/{KnowledgeDetailPage-BPhauuYL.js → KnowledgeDetailPage-CgR2Sjgu.js} +1 -1
- package/static/assets/{KnowledgeEditPage-CQUswyeH.js → KnowledgeEditPage-XrvVy-Nr.js} +1 -1
- package/static/assets/{KnowledgePage-KTCjoesA.js → KnowledgePage-Bd4yUZve.js} +1 -1
- package/static/assets/{LoginPage-BYAGsbfR.js → LoginPage-BPjBtFbe.js} +1 -1
- package/static/assets/{MailInboxPage-DSTys1-R.js → MailInboxPage-Uv5Yd0V5.js} +1 -1
- package/static/assets/{MailProcessingModal-Ctknm_wU.js → MailProcessingModal-DFCnUJD5.js} +1 -1
- package/static/assets/{MailReadPage-AOANr3XI.js → MailReadPage-BjBTIvdR.js} +1 -1
- package/static/assets/{MailSentPage-BnSYoKkQ.js → MailSentPage-Dsv4mmWO.js} +1 -1
- package/static/assets/{McpSettingsPage-CY3iobWJ.js → McpSettingsPage-ddInKeE_.js} +1 -1
- package/static/assets/{MemoryEditPage-Bh_d-iqV.js → MemoryEditPage-1Duk8_Ep.js} +1 -1
- package/static/assets/{MemoryPage-CMPTTwSH.js → MemoryPage-BsVDrfoH.js} +1 -1
- package/static/assets/{NewKnowledgePage-B00wknYX.js → NewKnowledgePage-QD99jkhw.js} +1 -1
- package/static/assets/{NewSkillPage-hNhVRNjh.js → NewSkillPage-CzXXY_2H.js} +1 -1
- package/static/assets/{NewTaskPage-Dq75MGuc.js → NewTaskPage-Dnvq8q0H.js} +1 -1
- package/static/assets/{NotFoundPage-CR1-vMeX.js → NotFoundPage-CXNHyu2I.js} +1 -1
- package/static/assets/{NotificationsSettingsPage-5aeTZq8-.js → NotificationsSettingsPage-CMwizTN5.js} +1 -1
- package/static/assets/{PromptsSettingsPage-Brs1vikj.js → PromptsSettingsPage-mzfSW46B.js} +1 -1
- package/static/assets/{ResourceDetailPage-3r3KPdJy.js → ResourceDetailPage-DmVFJJeE.js} +1 -1
- package/static/assets/{ResourcesPage-CFtSgZva.js → ResourcesPage-B-S4WIgq.js} +1 -1
- package/static/assets/{RoleEditPage-DmSqJEHZ.js → RoleEditPage-CLDE56qK.js} +1 -1
- package/static/assets/{RolePage-Dm523gez.js → RolePage-D43fy7y9.js} +1 -1
- package/static/assets/{RulesSettingsPage-DewqNsAk.js → RulesSettingsPage-CZJQIr_7.js} +1 -1
- package/static/assets/{RunDetailPage-BDUVebTX.js → RunDetailPage-DM1a32RR.js} +1 -1
- package/static/assets/{SchedulePage-DFnoNF-X.js → SchedulePage-D2fMyBig.js} +1 -1
- package/static/assets/{SkillDetailPage-DnCPbpIZ.js → SkillDetailPage-BePyNqOX.js} +1 -1
- package/static/assets/{SkillEditPage-Inn-YsZP.js → SkillEditPage-DBc1H0t2.js} +1 -1
- package/static/assets/{SkillsPage-CD-eiUnZ.js → SkillsPage-Be_0YQkP.js} +1 -1
- package/static/assets/{SkillsSettingsPage-C1bs2gVd.js → SkillsSettingsPage-Vr645xmf.js} +1 -1
- package/static/assets/{SourceInput-CIyYOUd-.js → SourceInput-Xd7tPRiQ.js} +1 -1
- package/static/assets/{TagInput-fSSAsdov.js → TagInput-D0zZF7xt.js} +1 -1
- package/static/assets/{TaskDetailPage-B2AeYerz.js → TaskDetailPage-Bpg8n3W0.js} +1 -1
- package/static/assets/{TaskEditPage-B9dA1Nr4.js → TaskEditPage-BNvNMUgF.js} +1 -1
- package/static/assets/{TasksPage-DJBVDNw1.js → TasksPage-BQE58PD0.js} +1 -1
- package/static/assets/{TeamEditPage-BGHM7C8n.js → TeamEditPage-C4UQSONx.js} +1 -1
- package/static/assets/{TeamPage-CGxpXKc4.js → TeamPage-CVtSifUm.js} +1 -1
- package/static/assets/{TerminalPage-z5NbYWjF.js → TerminalPage-SUFGXm4l.js} +1 -1
- package/static/assets/{TerminalSessionPage-eDZDlEeb.js → TerminalSessionPage-BVsNKUkH.js} +1 -1
- package/static/assets/{UserPreferencesPage-uTC5S4Ig.js → UserPreferencesPage-Df-ITRan.js} +1 -1
- package/static/assets/{UserSettingsPage-D6uxgoz5.js → UserSettingsPage-DXVtBXML.js} +1 -1
- package/static/assets/{UtilitiesPage-BwoS0vin.js → UtilitiesPage-D6fqcEaT.js} +1 -1
- package/static/assets/{alert-CKLRmrya.js → alert-DAl4a56c.js} +1 -1
- package/static/assets/{arrow-down-B7v_FmC2.js → arrow-down-CDCYDGUx.js} +1 -1
- package/static/assets/{arrow-left-CrE2UamQ.js → arrow-left-VDfx33Jh.js} +1 -1
- package/static/assets/{arrow-up-DkJyEUv_.js → arrow-up-CDSv61uo.js} +1 -1
- package/static/assets/{arrow-up-down-CyKWLTed.js → arrow-up-down-Ezpoqf2s.js} +1 -1
- package/static/assets/{badge-CEhr50DH.js → badge-D_uqNUSH.js} +1 -1
- package/static/assets/{browser-modal-BaiHyGXz.js → browser-modal-C5jrpzix.js} +1 -1
- package/static/assets/{card-CEBVsJGA.js → card-B0QREUF4.js} +1 -1
- package/static/assets/{chevron-left-Dwnb59xB.js → chevron-left-35sibkLF.js} +1 -1
- package/static/assets/{chevron-up-CLuT-8K8.js → chevron-up-BjM6KODw.js} +1 -1
- package/static/assets/{chevrons-up-DiHFV5Rg.js → chevrons-up-jJ4zW_aE.js} +1 -1
- package/static/assets/{circle-alert-DbwPGG3s.js → circle-alert-gQD7uoQT.js} +1 -1
- package/static/assets/{circle-check-DoS8t4b0.js → circle-check-KTXf2BuN.js} +1 -1
- package/static/assets/{circle-check-big-DW9BPHOx.js → circle-check-big-CJ5S5SSR.js} +1 -1
- package/static/assets/{circle-play-B5pWyVQu.js → circle-play-SYdQRKi1.js} +1 -1
- package/static/assets/{circle-x-D0FfNqWc.js → circle-x-Bcwe-LN_.js} +1 -1
- package/static/assets/{clipboard-DesoxJnQ.js → clipboard-VHK-krjO.js} +1 -1
- package/static/assets/{clock-KMBAqOpw.js → clock-D5ggHAx5.js} +1 -1
- package/static/assets/{code-Jj7V1OI-.js → code-Dg1ZHEGS.js} +1 -1
- package/static/assets/{download-bCNOpuix.js → download-CGb5cJiK.js} +1 -1
- package/static/assets/{external-link-BbvQVJFO.js → external-link-Cf9EKGQO.js} +1 -1
- package/static/assets/{eye-B3bkY8eg.js → eye-oD_Emdr8.js} +1 -1
- package/static/assets/{folder-git-2-DK4rLsn4.js → folder-git-2-DX-nlC0d.js} +1 -1
- package/static/assets/{globe-bTMV8w2D.js → globe-pOzIGyKN.js} +1 -1
- package/static/assets/{index-DUahdX7L.js → index-BIwO8uo-.js} +1 -1
- package/static/assets/{index-C0uIENKu.js → index-BUPxY8PP.js} +3 -3
- package/static/assets/{index-X-V7B-bx.js → index-BXQJo5V4.js} +1 -1
- package/static/assets/{index-BnXRNrU8.js → index-Bfgdm0Cb.js} +1 -1
- package/static/assets/{index-CZiSycvj.js → index-Bxwh96Rz.js} +1 -1
- package/static/assets/{index--BGsGBNQ.js → index-C3FDBd4S.js} +1 -1
- package/static/assets/{index-D5ZLXUjG.js → index-C3MMQmQg.js} +1 -1
- package/static/assets/{index-gnXQirFQ.js → index-C6yQwDNN.js} +1 -1
- package/static/assets/{index-DtuMv8f8.js → index-CC7HjVOa.js} +1 -1
- package/static/assets/{index-BQ6iW0x3.js → index-CCGFI_UP.js} +1 -1
- package/static/assets/{index-BcFOHKDW.js → index-CHyffstY.js} +1 -1
- package/static/assets/{index-4_sGNb1Z.js → index-Cidb9y3R.js} +1 -1
- package/static/assets/{index-fkGtFh-U.js → index-CoFwRL3K.js} +1 -1
- package/static/assets/{index-DVczQIDE.js → index-CusNnDtY.js} +1 -1
- package/static/assets/{index-CpjimEBF.js → index-Cuz8Apx7.js} +1 -1
- package/static/assets/{index-DHFK1JbA.js → index-DchDWBTE.js} +1 -1
- package/static/assets/{index-Bys9M37r.js → index-DjJ6EU0v.js} +1 -1
- package/static/assets/{index-D82OGwJi.js → index-FklRfl66.js} +1 -1
- package/static/assets/{index-BbgmwHwE.js → index-pfpWERL-.js} +1 -1
- package/static/assets/{info-CMb2giNJ.js → info-DlnFCJCq.js} +1 -1
- package/static/assets/{label-DXN216Ba.js → label-CjHH2sSK.js} +1 -1
- package/static/assets/{markdown-editor-MQ7X6BHT.js → markdown-editor-BN8QzPHa.js} +3 -3
- package/static/assets/{message-square-f1hNpr6b.js → message-square-k2mWEt-W.js} +1 -1
- package/static/assets/{paperclip-BiwY4VlV.js → paperclip-pH0rHAfm.js} +1 -1
- package/static/assets/{pause-EbBEDWDr.js → pause-BF-WAXuj.js} +1 -1
- package/static/assets/{play-BHqUO04d.js → play-szwfQctH.js} +1 -1
- package/static/assets/{radio-group-CzhYpC89.js → radio-group-BAAsV2rJ.js} +1 -1
- package/static/assets/{refresh-cw-BPr-EVyC.js → refresh-cw-CxDJQR9R.js} +1 -1
- package/static/assets/{search-BBw4K5iK.js → search-CoqBUnty.js} +1 -1
- package/static/assets/{select-BLUGdloJ.js → select-SvSJ1fXP.js} +1 -1
- package/static/assets/{server-2mf5MwhW.js → server-yLtQ3igN.js} +1 -1
- package/static/assets/{switch-DwGQE3tG.js → switch-DNt53KzF.js} +1 -1
- package/static/assets/{tabs-33myWTAS.js → tabs-DBHspaGs.js} +1 -1
- package/static/assets/{tag-C-PW20qp.js → tag-yDsYYVah.js} +1 -1
- package/static/assets/{terminal-preview-BHb0aOSR.js → terminal-preview-DYd7d-he.js} +1 -1
- package/static/assets/{triangle-alert-CNER-68k.js → triangle-alert-Dy1Oo-ts.js} +1 -1
- package/static/assets/{use-terminal-GvBteSXs.js → use-terminal-DpQ4ZVfs.js} +1 -1
- package/static/assets/{video-3hk0v1CB.js → video-BoEpz24p.js} +1 -1
- package/static/index.html +1 -1
- package/dist/config/m2m.d.ts +0 -26
- package/dist/config/m2m.js +0 -27
- package/dist/lib/auth/clerk-m2m-verifier.d.ts +0 -34
- package/dist/lib/auth/clerk-m2m-verifier.js +0 -47
|
@@ -0,0 +1,245 @@
|
|
|
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 { findGaitDirectory } from '../../../../../lib/gait-path.js';
|
|
6
|
+
import { getLogger, ContextKinds } from '@lovelybunch/core/logging';
|
|
7
|
+
import { requireAuth } from '../../../../../middleware/auth.js';
|
|
8
|
+
// Helper function to generate a simple summary from content
|
|
9
|
+
function generateSummary(content, maxLines = 3, maxChars = 200) {
|
|
10
|
+
// Remove markdown formatting for cleaner summary
|
|
11
|
+
const cleanContent = content
|
|
12
|
+
.replace(/^#+\s+/gm, '') // Remove headings
|
|
13
|
+
.replace(/[*_`]/g, '') // Remove bold, italic, code
|
|
14
|
+
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') // Convert links to text
|
|
15
|
+
.trim();
|
|
16
|
+
// Get first few lines
|
|
17
|
+
const lines = cleanContent.split('\n').filter(line => line.trim().length > 0);
|
|
18
|
+
const summary = lines.slice(0, maxLines).join(' ');
|
|
19
|
+
// Truncate if too long
|
|
20
|
+
return summary.length > maxChars
|
|
21
|
+
? summary.substring(0, maxChars) + '...'
|
|
22
|
+
: summary;
|
|
23
|
+
}
|
|
24
|
+
const app = new Hono();
|
|
25
|
+
async function getArchitecturePath() {
|
|
26
|
+
const gaitDir = await findGaitDirectory();
|
|
27
|
+
if (!gaitDir)
|
|
28
|
+
return null;
|
|
29
|
+
return path.join(gaitDir, 'context');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* GET /api/v1/context/architecture
|
|
33
|
+
* Load architecture document
|
|
34
|
+
*/
|
|
35
|
+
app.get('/', async (c) => {
|
|
36
|
+
try {
|
|
37
|
+
const architecturePath = await getArchitecturePath();
|
|
38
|
+
if (!architecturePath) {
|
|
39
|
+
return c.json({
|
|
40
|
+
success: false,
|
|
41
|
+
error: 'GAIT directory not found'
|
|
42
|
+
}, 404);
|
|
43
|
+
}
|
|
44
|
+
// Ensure directory exists
|
|
45
|
+
await fs.mkdir(architecturePath, { recursive: true });
|
|
46
|
+
// Look for architecture.md file
|
|
47
|
+
const filePath = path.join(architecturePath, 'architecture.md');
|
|
48
|
+
try {
|
|
49
|
+
const fileContent = await fs.readFile(filePath, 'utf-8');
|
|
50
|
+
const { data, content } = matter(fileContent);
|
|
51
|
+
// Extract title from first heading or use default
|
|
52
|
+
const title = content.match(/^#\s+(.+)$/m)?.[1] || 'Architecture Overview';
|
|
53
|
+
const document = {
|
|
54
|
+
filename: 'architecture.md',
|
|
55
|
+
metadata: {
|
|
56
|
+
...data,
|
|
57
|
+
updated: data.updated || new Date().toISOString().split('T')[0],
|
|
58
|
+
type: 'architecture',
|
|
59
|
+
category: 'design',
|
|
60
|
+
tags: data.tags || []
|
|
61
|
+
},
|
|
62
|
+
content,
|
|
63
|
+
title
|
|
64
|
+
};
|
|
65
|
+
return c.json({
|
|
66
|
+
success: true,
|
|
67
|
+
document
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
catch (fileError) {
|
|
71
|
+
// If file doesn't exist, return default content
|
|
72
|
+
const defaultContent = `# Architecture Overview
|
|
73
|
+
|
|
74
|
+
This document describes the overall architecture and design patterns used in this project.
|
|
75
|
+
|
|
76
|
+
## System Architecture
|
|
77
|
+
|
|
78
|
+
Describe the high-level system architecture, including major components and their relationships.
|
|
79
|
+
|
|
80
|
+
## Design Patterns
|
|
81
|
+
|
|
82
|
+
Document the key design patterns and architectural principles followed in this project.
|
|
83
|
+
|
|
84
|
+
### Frontend Architecture
|
|
85
|
+
|
|
86
|
+
- Component structure
|
|
87
|
+
- State management
|
|
88
|
+
- Routing approach
|
|
89
|
+
- UI/UX patterns
|
|
90
|
+
|
|
91
|
+
### Backend Architecture
|
|
92
|
+
|
|
93
|
+
- API design
|
|
94
|
+
- Data layer
|
|
95
|
+
- Service architecture
|
|
96
|
+
- Authentication & authorization
|
|
97
|
+
|
|
98
|
+
## Data Flow
|
|
99
|
+
|
|
100
|
+
Explain how data flows through the system, including:
|
|
101
|
+
|
|
102
|
+
- Request/response cycles
|
|
103
|
+
- Data transformations
|
|
104
|
+
- Caching strategies
|
|
105
|
+
- Error handling
|
|
106
|
+
|
|
107
|
+
## Technology Decisions
|
|
108
|
+
|
|
109
|
+
Document key technology choices and the reasoning behind them:
|
|
110
|
+
|
|
111
|
+
- Framework selections
|
|
112
|
+
- Database choices
|
|
113
|
+
- Third-party integrations
|
|
114
|
+
- Development tools
|
|
115
|
+
|
|
116
|
+
## Deployment Architecture
|
|
117
|
+
|
|
118
|
+
Describe the deployment strategy and infrastructure:
|
|
119
|
+
|
|
120
|
+
- Environment setup
|
|
121
|
+
- CI/CD pipeline
|
|
122
|
+
- Monitoring and logging
|
|
123
|
+
- Scaling considerations
|
|
124
|
+
|
|
125
|
+
## Security Considerations
|
|
126
|
+
|
|
127
|
+
Outline security measures and best practices:
|
|
128
|
+
|
|
129
|
+
- Authentication mechanisms
|
|
130
|
+
- Data protection
|
|
131
|
+
- API security
|
|
132
|
+
- Infrastructure security
|
|
133
|
+
|
|
134
|
+
## Performance Considerations
|
|
135
|
+
|
|
136
|
+
Document performance optimization strategies:
|
|
137
|
+
|
|
138
|
+
- Caching layers
|
|
139
|
+
- Database optimization
|
|
140
|
+
- Frontend performance
|
|
141
|
+
- Monitoring and metrics
|
|
142
|
+
`;
|
|
143
|
+
const document = {
|
|
144
|
+
filename: 'architecture.md',
|
|
145
|
+
metadata: {
|
|
146
|
+
version: '1.0',
|
|
147
|
+
updated: new Date().toISOString().split('T')[0],
|
|
148
|
+
type: 'architecture',
|
|
149
|
+
category: 'design',
|
|
150
|
+
tags: []
|
|
151
|
+
},
|
|
152
|
+
content: defaultContent,
|
|
153
|
+
title: 'Architecture Overview'
|
|
154
|
+
};
|
|
155
|
+
return c.json({
|
|
156
|
+
success: true,
|
|
157
|
+
document
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
console.error('Error loading architecture document:', error);
|
|
163
|
+
return c.json({
|
|
164
|
+
success: false,
|
|
165
|
+
error: 'Failed to load architecture document'
|
|
166
|
+
}, 500);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
/**
|
|
170
|
+
* PUT /api/v1/context/architecture
|
|
171
|
+
* Update architecture document
|
|
172
|
+
*/
|
|
173
|
+
app.put('/', async (c) => {
|
|
174
|
+
try {
|
|
175
|
+
const body = await c.req.json();
|
|
176
|
+
if (!body.content) {
|
|
177
|
+
return c.json({ success: false, error: 'Content is required' }, 400);
|
|
178
|
+
}
|
|
179
|
+
const architecturePath = await getArchitecturePath();
|
|
180
|
+
if (!architecturePath) {
|
|
181
|
+
return c.json({ success: false, error: 'GAIT directory not found' }, 404);
|
|
182
|
+
}
|
|
183
|
+
await fs.mkdir(architecturePath, { recursive: true });
|
|
184
|
+
const filePath = path.join(architecturePath, 'architecture.md');
|
|
185
|
+
// Read current content if it exists
|
|
186
|
+
let currentData = {};
|
|
187
|
+
try {
|
|
188
|
+
const currentContent = await fs.readFile(filePath, 'utf-8');
|
|
189
|
+
const { data } = matter(currentContent);
|
|
190
|
+
currentData = data;
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
// File doesn't exist, use defaults
|
|
194
|
+
}
|
|
195
|
+
// Prepare updated metadata
|
|
196
|
+
const updatedMetadata = {
|
|
197
|
+
...currentData,
|
|
198
|
+
...body.metadata,
|
|
199
|
+
updated: new Date().toISOString().split('T')[0],
|
|
200
|
+
type: 'architecture',
|
|
201
|
+
category: 'design',
|
|
202
|
+
version: currentData.version || '1.0'
|
|
203
|
+
};
|
|
204
|
+
// Create the markdown content with frontmatter
|
|
205
|
+
const fileContent = matter.stringify(body.content, updatedMetadata);
|
|
206
|
+
await fs.writeFile(filePath, fileContent, 'utf-8');
|
|
207
|
+
// Extract updated title
|
|
208
|
+
const title = body.title ||
|
|
209
|
+
body.content.match(/^#\s+(.+)$/m)?.[1] ||
|
|
210
|
+
'Architecture Overview';
|
|
211
|
+
// Log architecture update event
|
|
212
|
+
try {
|
|
213
|
+
const session = await requireAuth(c);
|
|
214
|
+
const actor = session ? `human:${session.email}` : "human:unknown";
|
|
215
|
+
const logger = getLogger();
|
|
216
|
+
logger.log({
|
|
217
|
+
kind: ContextKinds.ARCHITECTURE_UPDATE,
|
|
218
|
+
actor,
|
|
219
|
+
subject: `context:architecture.md`,
|
|
220
|
+
tags: ["context", "architecture"],
|
|
221
|
+
payload: {
|
|
222
|
+
title,
|
|
223
|
+
summary: generateSummary(body.content),
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
catch (logError) {
|
|
228
|
+
console.error('Error logging architecture update:', logError);
|
|
229
|
+
}
|
|
230
|
+
return c.json({
|
|
231
|
+
success: true,
|
|
232
|
+
document: {
|
|
233
|
+
filename: 'architecture.md',
|
|
234
|
+
title,
|
|
235
|
+
metadata: updatedMetadata,
|
|
236
|
+
content: body.content
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
console.error('Error updating architecture document:', error);
|
|
242
|
+
return c.json({ success: false, error: 'Failed to update architecture document' }, 500);
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
export default app;
|
|
@@ -0,0 +1,200 @@
|
|
|
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 { findGaitDirectory } from '../../../../../lib/gait-path.js';
|
|
6
|
+
import { getLogger, ContextKinds } from '@lovelybunch/core/logging';
|
|
7
|
+
import { requireAuth } from '../../../../../middleware/auth.js';
|
|
8
|
+
// Helper function to generate a simple summary from content
|
|
9
|
+
function generateSummary(content, maxLines = 3, maxChars = 200) {
|
|
10
|
+
// Remove markdown formatting for cleaner summary
|
|
11
|
+
const cleanContent = content
|
|
12
|
+
.replace(/^#+\s+/gm, '') // Remove headings
|
|
13
|
+
.replace(/[*_`]/g, '') // Remove bold, italic, code
|
|
14
|
+
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') // Convert links to text
|
|
15
|
+
.trim();
|
|
16
|
+
// Get first few lines
|
|
17
|
+
const lines = cleanContent.split('\n').filter(line => line.trim().length > 0);
|
|
18
|
+
const summary = lines.slice(0, maxLines).join(' ');
|
|
19
|
+
// Truncate if too long
|
|
20
|
+
return summary.length > maxChars
|
|
21
|
+
? summary.substring(0, maxChars) + '...'
|
|
22
|
+
: summary;
|
|
23
|
+
}
|
|
24
|
+
const app = new Hono();
|
|
25
|
+
async function getProjectPath() {
|
|
26
|
+
const gaitDir = await findGaitDirectory();
|
|
27
|
+
if (!gaitDir)
|
|
28
|
+
return null;
|
|
29
|
+
return path.join(gaitDir, 'context');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* GET /api/v1/context/project
|
|
33
|
+
* Load project overview document
|
|
34
|
+
*/
|
|
35
|
+
app.get('/', async (c) => {
|
|
36
|
+
try {
|
|
37
|
+
const projectPath = await getProjectPath();
|
|
38
|
+
if (!projectPath) {
|
|
39
|
+
return c.json({
|
|
40
|
+
success: false,
|
|
41
|
+
error: 'GAIT directory not found'
|
|
42
|
+
}, 404);
|
|
43
|
+
}
|
|
44
|
+
// Ensure directory exists
|
|
45
|
+
await fs.mkdir(projectPath, { recursive: true });
|
|
46
|
+
// Look for project.md file
|
|
47
|
+
const filePath = path.join(projectPath, 'project.md');
|
|
48
|
+
try {
|
|
49
|
+
const fileContent = await fs.readFile(filePath, 'utf-8');
|
|
50
|
+
const { data, content } = matter(fileContent);
|
|
51
|
+
// Extract title from first heading or use default
|
|
52
|
+
const title = content.match(/^#\s+(.+)$/m)?.[1] || 'Project Overview';
|
|
53
|
+
const document = {
|
|
54
|
+
filename: 'project.md',
|
|
55
|
+
metadata: {
|
|
56
|
+
...data,
|
|
57
|
+
updated: data.updated || new Date().toISOString().split('T')[0],
|
|
58
|
+
type: 'project',
|
|
59
|
+
category: 'overview',
|
|
60
|
+
tags: data.tags || []
|
|
61
|
+
},
|
|
62
|
+
content,
|
|
63
|
+
title
|
|
64
|
+
};
|
|
65
|
+
return c.json({
|
|
66
|
+
success: true,
|
|
67
|
+
document
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
catch (fileError) {
|
|
71
|
+
// If file doesn't exist, return default content
|
|
72
|
+
const defaultContent = `# Project Overview
|
|
73
|
+
|
|
74
|
+
This document provides an overview of the project, including its purpose, goals, and key information.
|
|
75
|
+
|
|
76
|
+
## Purpose
|
|
77
|
+
|
|
78
|
+
Describe the main purpose and objectives of this project.
|
|
79
|
+
|
|
80
|
+
## Key Features
|
|
81
|
+
|
|
82
|
+
- Feature 1
|
|
83
|
+
- Feature 2
|
|
84
|
+
- Feature 3
|
|
85
|
+
|
|
86
|
+
## Technology Stack
|
|
87
|
+
|
|
88
|
+
List the main technologies, frameworks, and tools used in this project.
|
|
89
|
+
|
|
90
|
+
## Getting Started
|
|
91
|
+
|
|
92
|
+
Provide instructions for setting up and running the project locally.
|
|
93
|
+
|
|
94
|
+
## Documentation
|
|
95
|
+
|
|
96
|
+
Links to additional documentation, guides, and resources.
|
|
97
|
+
`;
|
|
98
|
+
const document = {
|
|
99
|
+
filename: 'project.md',
|
|
100
|
+
metadata: {
|
|
101
|
+
version: '1.0',
|
|
102
|
+
updated: new Date().toISOString().split('T')[0],
|
|
103
|
+
type: 'project',
|
|
104
|
+
category: 'overview',
|
|
105
|
+
tags: []
|
|
106
|
+
},
|
|
107
|
+
content: defaultContent,
|
|
108
|
+
title: 'Project Overview'
|
|
109
|
+
};
|
|
110
|
+
return c.json({
|
|
111
|
+
success: true,
|
|
112
|
+
document
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
console.error('Error loading project document:', error);
|
|
118
|
+
return c.json({
|
|
119
|
+
success: false,
|
|
120
|
+
error: 'Failed to load project document'
|
|
121
|
+
}, 500);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
/**
|
|
125
|
+
* PUT /api/v1/context/project
|
|
126
|
+
* Update project overview document
|
|
127
|
+
*/
|
|
128
|
+
app.put('/', async (c) => {
|
|
129
|
+
try {
|
|
130
|
+
const body = await c.req.json();
|
|
131
|
+
if (!body.content) {
|
|
132
|
+
return c.json({ success: false, error: 'Content is required' }, 400);
|
|
133
|
+
}
|
|
134
|
+
const projectPath = await getProjectPath();
|
|
135
|
+
if (!projectPath) {
|
|
136
|
+
return c.json({ success: false, error: 'GAIT directory not found' }, 404);
|
|
137
|
+
}
|
|
138
|
+
await fs.mkdir(projectPath, { recursive: true });
|
|
139
|
+
const filePath = path.join(projectPath, 'project.md');
|
|
140
|
+
// Read current content if it exists
|
|
141
|
+
let currentData = {};
|
|
142
|
+
try {
|
|
143
|
+
const currentContent = await fs.readFile(filePath, 'utf-8');
|
|
144
|
+
const { data } = matter(currentContent);
|
|
145
|
+
currentData = data;
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// File doesn't exist, use defaults
|
|
149
|
+
}
|
|
150
|
+
// Prepare updated metadata
|
|
151
|
+
const updatedMetadata = {
|
|
152
|
+
...currentData,
|
|
153
|
+
...body.metadata,
|
|
154
|
+
updated: new Date().toISOString().split('T')[0],
|
|
155
|
+
type: 'project',
|
|
156
|
+
category: 'overview',
|
|
157
|
+
version: currentData.version || '1.0'
|
|
158
|
+
};
|
|
159
|
+
// Create the markdown content with frontmatter
|
|
160
|
+
const fileContent = matter.stringify(body.content, updatedMetadata);
|
|
161
|
+
await fs.writeFile(filePath, fileContent, 'utf-8');
|
|
162
|
+
// Extract updated title
|
|
163
|
+
const title = body.title ||
|
|
164
|
+
body.content.match(/^#\s+(.+)$/m)?.[1] ||
|
|
165
|
+
'Project Overview';
|
|
166
|
+
// Log project update event
|
|
167
|
+
try {
|
|
168
|
+
const session = await requireAuth(c);
|
|
169
|
+
const actor = session ? `human:${session.email}` : "human:unknown";
|
|
170
|
+
const logger = getLogger();
|
|
171
|
+
logger.log({
|
|
172
|
+
kind: ContextKinds.PROJECT_UPDATE,
|
|
173
|
+
actor,
|
|
174
|
+
subject: `context:project.md`,
|
|
175
|
+
tags: ["context", "project"],
|
|
176
|
+
payload: {
|
|
177
|
+
title,
|
|
178
|
+
summary: generateSummary(body.content),
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
catch (logError) {
|
|
183
|
+
console.error('Error logging project update:', logError);
|
|
184
|
+
}
|
|
185
|
+
return c.json({
|
|
186
|
+
success: true,
|
|
187
|
+
document: {
|
|
188
|
+
filename: 'project.md',
|
|
189
|
+
title,
|
|
190
|
+
metadata: updatedMetadata,
|
|
191
|
+
content: body.content
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
console.error('Error updating project document:', error);
|
|
197
|
+
return c.json({ success: false, error: 'Failed to update project document' }, 500);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
export default app;
|
|
@@ -9,6 +9,9 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
|
|
|
9
9
|
}, 404, "json">) | (Response & import("hono").TypedResponse<{
|
|
10
10
|
success: true;
|
|
11
11
|
data: {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
status: ScheduledJobStatus;
|
|
12
15
|
schedule: {
|
|
13
16
|
type: "cron";
|
|
14
17
|
expression: string;
|
|
@@ -22,11 +25,8 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
|
|
|
22
25
|
anchorHour?: number;
|
|
23
26
|
};
|
|
24
27
|
description?: string;
|
|
25
|
-
id: string;
|
|
26
|
-
name: string;
|
|
27
28
|
prompt: string;
|
|
28
29
|
model: string;
|
|
29
|
-
status: ScheduledJobStatus;
|
|
30
30
|
metadata: {
|
|
31
31
|
createdAt: string;
|
|
32
32
|
updatedAt: string;
|
|
@@ -39,13 +39,13 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
|
|
|
39
39
|
agentIds?: string[];
|
|
40
40
|
mcpServers?: string[];
|
|
41
41
|
runs: {
|
|
42
|
+
error?: string;
|
|
42
43
|
id: string;
|
|
43
44
|
status: import("@lovelybunch/types").ScheduledJobRunStatus;
|
|
44
45
|
jobId: string;
|
|
45
46
|
trigger: import("@lovelybunch/types").ScheduledJobTrigger;
|
|
46
47
|
startedAt: string;
|
|
47
48
|
finishedAt?: string;
|
|
48
|
-
error?: string;
|
|
49
49
|
}[];
|
|
50
50
|
};
|
|
51
51
|
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
|
|
@@ -70,6 +70,9 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
|
|
|
70
70
|
}, 400, "json">) | (Response & import("hono").TypedResponse<{
|
|
71
71
|
success: true;
|
|
72
72
|
data: {
|
|
73
|
+
id: string;
|
|
74
|
+
name: string;
|
|
75
|
+
status: ScheduledJobStatus;
|
|
73
76
|
schedule: {
|
|
74
77
|
type: "cron";
|
|
75
78
|
expression: string;
|
|
@@ -83,11 +86,8 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
|
|
|
83
86
|
anchorHour?: number;
|
|
84
87
|
};
|
|
85
88
|
description?: string;
|
|
86
|
-
id: string;
|
|
87
|
-
name: string;
|
|
88
89
|
prompt: string;
|
|
89
90
|
model: string;
|
|
90
|
-
status: ScheduledJobStatus;
|
|
91
91
|
metadata: {
|
|
92
92
|
createdAt: string;
|
|
93
93
|
updatedAt: string;
|
|
@@ -100,13 +100,13 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
|
|
|
100
100
|
agentIds?: string[];
|
|
101
101
|
mcpServers?: string[];
|
|
102
102
|
runs: {
|
|
103
|
+
error?: string;
|
|
103
104
|
id: string;
|
|
104
105
|
status: import("@lovelybunch/types").ScheduledJobRunStatus;
|
|
105
106
|
jobId: string;
|
|
106
107
|
trigger: import("@lovelybunch/types").ScheduledJobTrigger;
|
|
107
108
|
startedAt: string;
|
|
108
109
|
finishedAt?: string;
|
|
109
|
-
error?: string;
|
|
110
110
|
}[];
|
|
111
111
|
};
|
|
112
112
|
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
|
|
@@ -11,6 +11,9 @@ export declare function withLightweightRuns<T extends {
|
|
|
11
11
|
export declare function GET(c: Context): Promise<(Response & import("hono").TypedResponse<{
|
|
12
12
|
success: true;
|
|
13
13
|
data: {
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
status: ScheduledJobStatus;
|
|
14
17
|
schedule: {
|
|
15
18
|
type: "cron";
|
|
16
19
|
expression: string;
|
|
@@ -24,11 +27,8 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
|
|
|
24
27
|
anchorHour?: number;
|
|
25
28
|
};
|
|
26
29
|
description?: string;
|
|
27
|
-
id: string;
|
|
28
|
-
name: string;
|
|
29
30
|
prompt: string;
|
|
30
31
|
model: string;
|
|
31
|
-
status: ScheduledJobStatus;
|
|
32
32
|
metadata: {
|
|
33
33
|
createdAt: string;
|
|
34
34
|
updatedAt: string;
|
|
@@ -41,13 +41,13 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
|
|
|
41
41
|
agentIds?: string[];
|
|
42
42
|
mcpServers?: string[];
|
|
43
43
|
runs: {
|
|
44
|
+
error?: string;
|
|
44
45
|
id: string;
|
|
45
46
|
status: import("@lovelybunch/types").ScheduledJobRunStatus;
|
|
46
47
|
jobId: string;
|
|
47
48
|
trigger: import("@lovelybunch/types").ScheduledJobTrigger;
|
|
48
49
|
startedAt: string;
|
|
49
50
|
finishedAt?: string;
|
|
50
|
-
error?: string;
|
|
51
51
|
}[];
|
|
52
52
|
}[];
|
|
53
53
|
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
|
|
@@ -66,6 +66,9 @@ export declare function POST(c: Context): Promise<(Response & import("hono").Typ
|
|
|
66
66
|
}, 400, "json">) | (Response & import("hono").TypedResponse<{
|
|
67
67
|
success: true;
|
|
68
68
|
data: {
|
|
69
|
+
id: string;
|
|
70
|
+
name: string;
|
|
71
|
+
status: ScheduledJobStatus;
|
|
69
72
|
schedule: {
|
|
70
73
|
type: "cron";
|
|
71
74
|
expression: string;
|
|
@@ -79,11 +82,8 @@ export declare function POST(c: Context): Promise<(Response & import("hono").Typ
|
|
|
79
82
|
anchorHour?: number;
|
|
80
83
|
};
|
|
81
84
|
description?: string;
|
|
82
|
-
id: string;
|
|
83
|
-
name: string;
|
|
84
85
|
prompt: string;
|
|
85
86
|
model: string;
|
|
86
|
-
status: ScheduledJobStatus;
|
|
87
87
|
metadata: {
|
|
88
88
|
createdAt: string;
|
|
89
89
|
updatedAt: string;
|
|
@@ -96,13 +96,13 @@ export declare function POST(c: Context): Promise<(Response & import("hono").Typ
|
|
|
96
96
|
agentIds?: string[];
|
|
97
97
|
mcpServers?: string[];
|
|
98
98
|
runs: {
|
|
99
|
+
error?: string;
|
|
99
100
|
id: string;
|
|
100
101
|
status: import("@lovelybunch/types").ScheduledJobRunStatus;
|
|
101
102
|
jobId: string;
|
|
102
103
|
trigger: import("@lovelybunch/types").ScheduledJobTrigger;
|
|
103
104
|
startedAt: string;
|
|
104
105
|
finishedAt?: string;
|
|
105
|
-
error?: string;
|
|
106
106
|
}[];
|
|
107
107
|
};
|
|
108
108
|
}, 201, "json">) | (Response & import("hono").TypedResponse<{
|
|
@@ -116,7 +116,7 @@ export declare function setMailStatusHandler(c: Context): Promise<(Response & im
|
|
|
116
116
|
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
|
|
117
117
|
success: false;
|
|
118
118
|
error: any;
|
|
119
|
-
},
|
|
119
|
+
}, 404 | 500, "json">)>;
|
|
120
120
|
/**
|
|
121
121
|
* POST /api/v1/mail/:id/reply
|
|
122
122
|
* Reply to an email
|
|
@@ -154,7 +154,7 @@ export declare function replyMailHandler(c: Context): Promise<(Response & import
|
|
|
154
154
|
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
|
|
155
155
|
success: false;
|
|
156
156
|
error: any;
|
|
157
|
-
},
|
|
157
|
+
}, 404 | 500, "json">)>;
|
|
158
158
|
/**
|
|
159
159
|
* POST /api/v1/mail/send
|
|
160
160
|
* Send an email (coming soon)
|
|
@@ -217,7 +217,7 @@ export declare function setMailActionHandler(c: Context): Promise<(Response & im
|
|
|
217
217
|
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
|
|
218
218
|
success: false;
|
|
219
219
|
error: any;
|
|
220
|
-
},
|
|
220
|
+
}, 404 | 500, "json">)>;
|
|
221
221
|
/**
|
|
222
222
|
* GET /api/v1/mail/:id/processing
|
|
223
223
|
* Get processing status and log tail for an email
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lovelybunch/api",
|
|
3
|
-
"version": "1.0.78-alpha.
|
|
3
|
+
"version": "1.0.78-alpha.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/server-with-static.js",
|
|
6
6
|
"exports": {
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
"sharp": "^0.33.5",
|
|
41
41
|
"ws": "^8.18.0",
|
|
42
42
|
"zod": "^3.23.0",
|
|
43
|
-
"@lovelybunch/core": "1.0.78-alpha.
|
|
44
|
-
"@lovelybunch/types": "1.0.78-alpha.
|
|
45
|
-
"@lovelybunch/mcp": "1.0.78-alpha.
|
|
43
|
+
"@lovelybunch/core": "1.0.78-alpha.1",
|
|
44
|
+
"@lovelybunch/types": "1.0.78-alpha.1",
|
|
45
|
+
"@lovelybunch/mcp": "1.0.78-alpha.1"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/adm-zip": "^0.5.7",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as a,A as p,j as e,v,bN as y,B as N,n as w,C as b}from"./index-
|
|
1
|
+
import{r as a,A as p,j as e,v,bN as y,B as N,n as w,C as b}from"./index-BUPxY8PP.js";import{C as c,a as d,b as k,c as C}from"./card-B0QREUF4.js";import{B as m}from"./badge-D_uqNUSH.js";import{R as E}from"./refresh-cw-CxDJQR9R.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};
|