@lovelybunch/api 1.0.76-alpha.8 → 1.0.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/git.d.ts +3 -0
- package/dist/lib/git.js +35 -0
- package/dist/routes/api/v1/ai/route.js +214 -152
- package/dist/routes/api/v1/config/route.js +13 -9
- package/dist/routes/api/v1/context/agents/route.js +159 -0
- package/dist/routes/api/v1/context/index.js +6 -4
- package/dist/routes/api/v1/context/memory/route.js +163 -0
- package/dist/routes/api/v1/context/team/route.js +159 -0
- package/dist/routes/api/v1/git/index.js +27 -1
- package/dist/routes/api/v1/jobs/[id]/route.d.ts +26 -32
- package/dist/routes/api/v1/jobs/[id]/route.js +3 -3
- package/dist/routes/api/v1/jobs/route.d.ts +33 -33
- package/dist/routes/api/v1/jobs/route.js +17 -2
- package/dist/routes/api/v1/mcp/index.js +194 -21
- package/dist/routes/api/v1/resources/generate/route.js +10 -3
- package/package.json +4 -4
- package/static/assets/ActivityPage-sJEQn6DK.js +1 -0
- package/static/assets/AgentsContextEditPage-DU3qIXk9.js +9 -0
- package/static/assets/AgentsContextPage-tJ-LhFYb.js +1 -0
- package/static/assets/{ApiKeysSettingsPage-BhaH6ZYP.js → ApiKeysSettingsPage-Bg84BQHV.js} +2 -2
- package/static/assets/{AuthSettingsPage-D0MQlHyh.js → AuthSettingsPage-Bwr7uP3z.js} +1 -1
- package/static/assets/{CallbackPage-Bz4m3_W8.js → CallbackPage-BFn0Np2S.js} +1 -1
- package/static/assets/CodePage-kp4s3wCJ.js +2 -0
- package/static/assets/{CollapsibleSection-CxX11hr-.js → CollapsibleSection-CNs1mvsZ.js} +1 -1
- package/static/assets/{DashboardPage-B3HR1UM7.js → DashboardPage-DMJSzzgD.js} +9 -19
- package/static/assets/{GitPage-Dm36PRw_.js → GitPage-uqene8zj.js} +3 -3
- package/static/assets/{GitSettingsPage-CRWcjgVI.js → GitSettingsPage-CLswbZsT.js} +2 -2
- package/static/assets/{IdentityPage-YCkmdyzR.js → IdentityPage-BDTPXEo7.js} +2 -2
- package/static/assets/{ImplementationStepsEditor-u3dPxmKW.js → ImplementationStepsEditor-D4cvhPhz.js} +2 -2
- package/static/assets/IntegrationsSettingsPage-o7NXZGt9.js +1 -0
- package/static/assets/JobDetailPage-DuEiPz6X.js +1 -0
- package/static/assets/KnowledgeDetailPage-DFVud_VC.js +1 -0
- package/static/assets/{KnowledgeEditPage-DhrF6UPg.js → KnowledgeEditPage-XG6HKK7E.js} +1 -1
- package/static/assets/{KnowledgePage-_gZhpTe3.js → KnowledgePage-B2zI3xwW.js} +2 -2
- package/static/assets/{LoginPage-Cc1Ac2j4.js → LoginPage-CUJRxwXy.js} +1 -1
- package/static/assets/MailInboxPage-BlCG-tba.js +1 -0
- package/static/assets/MailProcessingModal-BJIdHOqK.js +1 -0
- package/static/assets/MailReadPage-MoNo_gmW.js +1 -0
- package/static/assets/{MailSentPage-Dj63oQ5D.js → MailSentPage-QzpuIJmT.js} +1 -1
- package/static/assets/{McpSettingsPage-DYZ0QNbp.js → McpSettingsPage-BZcCGkGM.js} +1 -1
- package/static/assets/MemoryEditPage-DXSQoCT4.js +13 -0
- package/static/assets/MemoryPage-oBnyuvSf.js +1 -0
- package/static/assets/NewKnowledgePage-deMsezK8.js +1 -0
- package/static/assets/{NewSkillPage-BEn18f2A.js → NewSkillPage-DRYWdrlV.js} +1 -1
- package/static/assets/{NewTaskPage-CSlncpI5.js → NewTaskPage-B6xdic5_.js} +2 -2
- package/static/assets/{NotFoundPage-C4x0lGai.js → NotFoundPage-Bxu9uKFO.js} +1 -1
- package/static/assets/{NotificationsSettingsPage-C9YnfRlj.js → NotificationsSettingsPage-CLgtsCVM.js} +1 -1
- package/static/assets/{PromptsSettingsPage-Chc4da1S.js → PromptsSettingsPage-BWaELCjG.js} +1 -1
- package/static/assets/{ResourceDetailPage-DDYKQxpM.js → ResourceDetailPage-CMPDRdVM.js} +1 -1
- package/static/assets/ResourcesPage-DspYILfG.js +41 -0
- package/static/assets/{RoleEditPage-Ccfu1tn1.js → RoleEditPage-DXtzicVZ.js} +1 -1
- package/static/assets/{RolePage-CcdEUjSm.js → RolePage-DafGURGp.js} +1 -1
- package/static/assets/{RulesSettingsPage-Cz1g_eAj.js → RulesSettingsPage-E8V9cexV.js} +1 -1
- package/static/assets/RunDetailPage-DsxkqFst.js +1 -0
- package/static/assets/SchedulePage-B2YvNDHr.js +4 -0
- package/static/assets/{SkillDetailPage-sJg-L8A8.js → SkillDetailPage-CWkqSfuT.js} +1 -1
- package/static/assets/{SkillEditPage-BksV7GmD.js → SkillEditPage-DwyebzFV.js} +1 -1
- package/static/assets/{SkillsPage-CwarkJmZ.js → SkillsPage-CauK65X_.js} +2 -2
- package/static/assets/{SkillsSettingsPage-DTnBlBdE.js → SkillsSettingsPage-DXMRv3jR.js} +1 -1
- package/static/assets/{SourceInput-CWazIr6v.js → SourceInput-C0iKqbQ1.js} +1 -1
- package/static/assets/{TagInput-Bgyxb_JU.js → TagInput-Ct-WRvTs.js} +1 -1
- package/static/assets/{TaskDetailPage-DlmG1kZR.js → TaskDetailPage-CApk2iBh.js} +1 -1
- package/static/assets/{TaskEditPage-BnpNeed_.js → TaskEditPage-NgOVShfK.js} +1 -1
- package/static/assets/{TasksPage-CXeTMpgy.js → TasksPage-BoPrP_Rl.js} +3 -3
- package/static/assets/TeamEditPage-ChY6mYm8.js +9 -0
- package/static/assets/TeamPage-DH-dJhFG.js +1 -0
- package/static/assets/{TerminalPage-BLcPt381.js → TerminalPage-CRhcscF2.js} +1 -1
- package/static/assets/TerminalSessionPage-CSCQg2sn.js +3 -0
- package/static/assets/{UserPreferencesPage-BNwEqlRW.js → UserPreferencesPage-DxCSWJnS.js} +1 -1
- package/static/assets/{UserSettingsPage-BRafqkiD.js → UserSettingsPage-DKkOLNPV.js} +1 -1
- package/static/assets/UtilitiesPage-CBNSvixW.js +1 -0
- package/static/assets/{alert-Ci2-OWZ_.js → alert-Dw_RSroN.js} +1 -1
- package/static/assets/{arrow-down-C6Flf0DF.js → arrow-down-UClxXzT-.js} +1 -1
- package/static/assets/{arrow-left-7TCkaJlN.js → arrow-left-DWmf9YJp.js} +1 -1
- package/static/assets/{arrow-up-down-tqbfiBy6.js → arrow-up-down-Btc3okb3.js} +1 -1
- package/static/assets/{arrow-up-DeQAxOPq.js → arrow-up-fLCh7Hvh.js} +1 -1
- package/static/assets/{badge-D4vHU_w_.js → badge-vIqE5SOP.js} +1 -1
- package/static/assets/{browser-modal-BiaqhKHm.js → browser-modal-DgMJTsMd.js} +2 -2
- package/static/assets/{card-xkODbJy-.js → card-DPLdBoa5.js} +1 -1
- package/static/assets/{chevron-left-CvpfJBPQ.js → chevron-left-CiNaLX-v.js} +1 -1
- package/static/assets/{chevron-up-BB-6OS4z.js → chevron-up-DFd-7wxW.js} +1 -1
- package/static/assets/{chevrons-up-CLKrQHMU.js → chevrons-up-BfU70OcQ.js} +1 -1
- package/static/assets/{circle-alert-lnP0-w3N.js → circle-alert-Mv00T-P2.js} +1 -1
- package/static/assets/{circle-check-big-Dbo-OmWQ.js → circle-check-big-BEY1IoIP.js} +1 -1
- package/static/assets/{circle-check-BPkEav83.js → circle-check-xMiP6SLO.js} +1 -1
- package/static/assets/{circle-play-BbtBIeo3.js → circle-play-iZZwaGbV.js} +1 -1
- package/static/assets/{circle-x-BBwi8e5G.js → circle-x-z3iynaE7.js} +1 -1
- package/static/assets/{clipboard-Ce816tAO.js → clipboard-C8wZRPDH.js} +1 -1
- package/static/assets/{clock-BIeoO5Mt.js → clock-C_9shc08.js} +1 -1
- package/static/assets/{code-DTW3giBe.js → code-DH-sRhus.js} +1 -1
- package/static/assets/{download-BgKxfry9.js → download-CE8b59ER.js} +1 -1
- package/static/assets/{external-link--RjKXREe.js → external-link-DPyKt8NE.js} +1 -1
- package/static/assets/{eye--K-OgK7L.js → eye-BpGD-yoS.js} +1 -1
- package/static/assets/{folder-git-2-Bgv7r0zC.js → folder-git-2-BIw4zbmy.js} +1 -1
- package/static/assets/globe-CUo7eHKN.js +6 -0
- package/static/assets/{index-Di7xMYoG.js → index-B07hel4U.js} +1 -1
- package/static/assets/{index-DF_KNbKf.js → index-BCwmQxLC.js} +1 -1
- package/static/assets/{index-D9xZafJb.js → index-BOKaM9K-.js} +1 -1
- package/static/assets/{index-Cd5hBt4x.js → index-BaR4iUzg.js} +1 -1
- package/static/assets/index-BcCuKdbf.css +1 -0
- package/static/assets/{index-Db5-BoCU.js → index-Bfb3OTwj.js} +1 -1
- package/static/assets/{index-Do92mBFr.js → index-Bkt1rQVV.js} +1 -1
- package/static/assets/{index-BD9UBXsr.js → index-C65b3D5_.js} +1 -1
- package/static/assets/{index-BbrX1XcC.js → index-CGbmjmEy.js} +1 -1
- package/static/assets/{index-4RuWYO4M.js → index-CTouvf2d.js} +1 -1
- package/static/assets/{index-Dt_WtbUU.js → index-Cdwx6Zps.js} +1 -1
- package/static/assets/{index-iIFwHD3L.js → index-ClO9-JVh.js} +1 -1
- package/static/assets/{index-BteQHbZ1.js → index-CpJ0uBf3.js} +1 -1
- package/static/assets/{index-LMsLdXw_.js → index-CsBxEWw5.js} +1 -1
- package/static/assets/{index-CW9pK_cZ.js → index-DZAYfTI2.js} +1 -1
- package/static/assets/{index-BkEdELOI.js → index-Dkr9CBL7.js} +1 -1
- package/static/assets/{index-BQYB8kWb.js → index-DnZKG-_7.js} +1 -1
- package/static/assets/index-UXL5-kaP.js +497 -0
- package/static/assets/{index-Ch4GVR8L.js → index-iB8oed57.js} +1 -1
- package/static/assets/{index-R44k73Ca.js → index-jaRIZ6SY.js} +1 -1
- package/static/assets/{info-DgZN3xWF.js → info-D-UNBNx2.js} +1 -1
- package/static/assets/{label-DvPENm3h.js → label-8VKluf9w.js} +1 -1
- package/static/assets/{markdown-editor-DpZxV-fa.js → markdown-editor-DBdRsbP2.js} +3 -3
- package/static/assets/{message-square-CoaQYehb.js → message-square-CO8kDUed.js} +1 -1
- package/static/assets/{paperclip-ChugoOAp.js → paperclip-DlLXZbru.js} +1 -1
- package/static/assets/{pause-m9YcgxdE.js → pause-zSiaxJBu.js} +1 -1
- package/static/assets/{play-DtFz_MLh.js → play-DVBhRokt.js} +1 -1
- package/static/assets/{radio-group-C5Te9bVb.js → radio-group-CThYUcA4.js} +1 -1
- package/static/assets/{refresh-cw-B1bWW9Rg.js → refresh-cw-tXYl1ePu.js} +1 -1
- package/static/assets/{search-CPOHeeUa.js → search-BxF7Wwex.js} +1 -1
- package/static/assets/{select-B1v2u6hQ.js → select-CyHFRA1Y.js} +1 -1
- package/static/assets/server-lRxThHjr.js +6 -0
- package/static/assets/{switch-Bf1Cq3P6.js → switch-BUpDbrux.js} +1 -1
- package/static/assets/tabs-DkvCmQEX.js +1 -0
- package/static/assets/{tag-Cz4z82t0.js → tag-CkcZNLnh.js} +1 -1
- package/static/assets/{terminal-preview-DTUohQ5b.js → terminal-preview-CLWDhoOZ.js} +1 -1
- package/static/assets/triangle-alert-CmjG_mbF.js +6 -0
- package/static/assets/{use-terminal-CFbQv1ie.js → use-terminal-D3iV7-iC.js} +1 -1
- package/static/assets/{video-B6ZJ-Epb.js → video-CY_dOujm.js} +1 -1
- package/static/index.html +2 -2
- package/dist/lib/mcp-client.d.ts +0 -39
- package/dist/lib/mcp-client.js +0 -131
- package/dist/routes/api/v1/ai/tools.d.ts +0 -17
- package/dist/routes/api/v1/ai/tools.js +0 -931
- package/dist/routes/api/v1/context/knowledge/[filename]/index.d.ts +0 -1
- package/dist/routes/api/v1/context/knowledge/[filename]/index.js +0 -1
- package/dist/routes/api/v1/context/knowledge/[filename]/route.js +0 -254
- package/dist/routes/api/v1/context/knowledge/index.d.ts +0 -1
- package/dist/routes/api/v1/context/knowledge/index.js +0 -1
- package/dist/routes/api/v1/context/knowledge/route.js +0 -176
- package/dist/routes/api/v1/proposals/[id]/route.d.ts +0 -337
- package/dist/routes/api/v1/proposals/[id]/route.js +0 -165
- package/dist/routes/api/v1/proposals/index.d.ts +0 -3
- package/dist/routes/api/v1/proposals/index.js +0 -10
- package/dist/routes/api/v1/proposals/route.d.ts +0 -315
- package/dist/routes/api/v1/proposals/route.js +0 -129
- package/dist/routes/api/v1/terminal/[proposalId]/create/index.d.ts +0 -3
- package/dist/routes/api/v1/terminal/[proposalId]/create/index.js +0 -5
- package/dist/routes/api/v1/terminal/[proposalId]/create/route.d.ts +0 -10
- package/dist/routes/api/v1/terminal/[proposalId]/create/route.js +0 -27
- package/dist/routes/api/v1/terminal/[proposalId]/destroy/index.js +0 -5
- package/dist/routes/api/v1/terminal/[proposalId]/destroy/route.d.ts +0 -10
- package/dist/routes/api/v1/terminal/[proposalId]/destroy/route.js +0 -21
- package/dist/routes/api/v1/terminal/[proposalId]/resize/index.d.ts +0 -3
- package/dist/routes/api/v1/terminal/[proposalId]/resize/index.js +0 -5
- package/dist/routes/api/v1/terminal/[proposalId]/resize/route.d.ts +0 -10
- package/dist/routes/api/v1/terminal/[proposalId]/resize/route.js +0 -21
- package/static/assets/ActivityPage-uL-Qknui.js +0 -1
- package/static/assets/ArchitectureEditPage-BWKyKi3T.js +0 -21
- package/static/assets/ArchitecturePage-Dtm0OAac.js +0 -1
- package/static/assets/CodePage-BuO2K_xx.js +0 -2
- package/static/assets/IntegrationsSettingsPage-Z8xCUmX9.js +0 -1
- package/static/assets/JobDetailPage-B8Za82RA.js +0 -1
- package/static/assets/KnowledgeDetailPage-CR9c4_WD.js +0 -1
- package/static/assets/MailInboxPage-B_h1Kz4D.js +0 -1
- package/static/assets/MailProcessingModal-D_qEwqmL.js +0 -6
- package/static/assets/MailReadPage-_q-xk_cX.js +0 -1
- package/static/assets/NewKnowledgePage-BEVMYnKG.js +0 -9
- package/static/assets/ProjectEditPage-X0-4mEAS.js +0 -11
- package/static/assets/ProjectPage-D8OX1GKt.js +0 -1
- package/static/assets/ResourcesPage-BmOpgt3L.js +0 -41
- package/static/assets/SchedulePage-CGxZHEL-.js +0 -4
- package/static/assets/TerminalSessionPage-CeAd8IAy.js +0 -8
- package/static/assets/UtilitiesPage-BPX_Unxu.js +0 -1
- package/static/assets/index-DH_vXhd4.css +0 -1
- package/static/assets/index-PyVlsLW8.js +0 -487
- package/static/assets/tabs-DAbCZiFC.js +0 -1
- /package/dist/routes/api/v1/context/{knowledge/[filename] → agents}/route.d.ts +0 -0
- /package/dist/routes/api/v1/context/{knowledge → memory}/route.d.ts +0 -0
- /package/dist/routes/api/v1/{terminal/[proposalId]/destroy/index.d.ts → context/team/route.d.ts} +0 -0
|
@@ -0,0 +1,159 @@
|
|
|
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
|
+
function generateSummary(content, maxLines = 3, maxChars = 200) {
|
|
9
|
+
const cleanContent = content
|
|
10
|
+
.replace(/^#+\s+/gm, '')
|
|
11
|
+
.replace(/[*_`]/g, '')
|
|
12
|
+
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
|
|
13
|
+
.trim();
|
|
14
|
+
const lines = cleanContent.split('\n').filter(line => line.trim().length > 0);
|
|
15
|
+
const summary = lines.slice(0, maxLines).join(' ');
|
|
16
|
+
return summary.length > maxChars
|
|
17
|
+
? summary.substring(0, maxChars) + '...'
|
|
18
|
+
: summary;
|
|
19
|
+
}
|
|
20
|
+
const app = new Hono();
|
|
21
|
+
async function getAgentsPath() {
|
|
22
|
+
const gaitDir = await findGaitDirectory();
|
|
23
|
+
if (!gaitDir)
|
|
24
|
+
return null;
|
|
25
|
+
return path.join(gaitDir, 'context');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* GET /api/v1/context/agents
|
|
29
|
+
*/
|
|
30
|
+
app.get('/', async (c) => {
|
|
31
|
+
try {
|
|
32
|
+
const agentsPath = await getAgentsPath();
|
|
33
|
+
if (!agentsPath) {
|
|
34
|
+
return c.json({ success: false, error: 'GAIT directory not found' }, 404);
|
|
35
|
+
}
|
|
36
|
+
await fs.mkdir(agentsPath, { recursive: true });
|
|
37
|
+
const filePath = path.join(agentsPath, 'agents.md');
|
|
38
|
+
try {
|
|
39
|
+
const fileContent = await fs.readFile(filePath, 'utf-8');
|
|
40
|
+
const { data, content } = matter(fileContent);
|
|
41
|
+
const title = content.match(/^#\s+(.+)$/m)?.[1] || 'Agents';
|
|
42
|
+
const document = {
|
|
43
|
+
filename: 'agents.md',
|
|
44
|
+
metadata: {
|
|
45
|
+
...data,
|
|
46
|
+
updated: data.updated || new Date().toISOString().split('T')[0],
|
|
47
|
+
type: 'agents',
|
|
48
|
+
category: 'context',
|
|
49
|
+
tags: data.tags || []
|
|
50
|
+
},
|
|
51
|
+
content,
|
|
52
|
+
title
|
|
53
|
+
};
|
|
54
|
+
return c.json({ success: true, document });
|
|
55
|
+
}
|
|
56
|
+
catch (fileError) {
|
|
57
|
+
const defaultContent = `# Agents
|
|
58
|
+
|
|
59
|
+
This document defines the agents available in this project.
|
|
60
|
+
|
|
61
|
+
## Agent Definitions
|
|
62
|
+
|
|
63
|
+
Describe agents, their capabilities, and configurations.
|
|
64
|
+
|
|
65
|
+
## Agent Guidelines
|
|
66
|
+
|
|
67
|
+
Key guidelines for agent behavior and interaction patterns.
|
|
68
|
+
`;
|
|
69
|
+
const document = {
|
|
70
|
+
filename: 'agents.md',
|
|
71
|
+
metadata: {
|
|
72
|
+
version: '1.0',
|
|
73
|
+
updated: new Date().toISOString().split('T')[0],
|
|
74
|
+
type: 'agents',
|
|
75
|
+
category: 'context',
|
|
76
|
+
tags: []
|
|
77
|
+
},
|
|
78
|
+
content: defaultContent,
|
|
79
|
+
title: 'Agents'
|
|
80
|
+
};
|
|
81
|
+
return c.json({ success: true, document });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.error('Error loading agents document:', error);
|
|
86
|
+
return c.json({ success: false, error: 'Failed to load agents document' }, 500);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
/**
|
|
90
|
+
* PUT /api/v1/context/agents
|
|
91
|
+
*/
|
|
92
|
+
app.put('/', async (c) => {
|
|
93
|
+
try {
|
|
94
|
+
const body = await c.req.json();
|
|
95
|
+
if (!body.content) {
|
|
96
|
+
return c.json({ success: false, error: 'Content is required' }, 400);
|
|
97
|
+
}
|
|
98
|
+
const agentsPath = await getAgentsPath();
|
|
99
|
+
if (!agentsPath) {
|
|
100
|
+
return c.json({ success: false, error: 'GAIT directory not found' }, 404);
|
|
101
|
+
}
|
|
102
|
+
await fs.mkdir(agentsPath, { recursive: true });
|
|
103
|
+
const filePath = path.join(agentsPath, 'agents.md');
|
|
104
|
+
let currentData = {};
|
|
105
|
+
try {
|
|
106
|
+
const currentContent = await fs.readFile(filePath, 'utf-8');
|
|
107
|
+
const { data } = matter(currentContent);
|
|
108
|
+
currentData = data;
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// File doesn't exist, use defaults
|
|
112
|
+
}
|
|
113
|
+
const updatedMetadata = {
|
|
114
|
+
...currentData,
|
|
115
|
+
...body.metadata,
|
|
116
|
+
updated: new Date().toISOString().split('T')[0],
|
|
117
|
+
type: 'agents',
|
|
118
|
+
category: 'context',
|
|
119
|
+
version: currentData.version || '1.0'
|
|
120
|
+
};
|
|
121
|
+
const fileContent = matter.stringify(body.content, updatedMetadata);
|
|
122
|
+
await fs.writeFile(filePath, fileContent, 'utf-8');
|
|
123
|
+
const title = body.title ||
|
|
124
|
+
body.content.match(/^#\s+(.+)$/m)?.[1] ||
|
|
125
|
+
'Agents';
|
|
126
|
+
try {
|
|
127
|
+
const session = await requireAuth(c);
|
|
128
|
+
const actor = session ? `human:${session.email}` : "human:unknown";
|
|
129
|
+
const logger = getLogger();
|
|
130
|
+
logger.log({
|
|
131
|
+
kind: ContextKinds.AGENTS_UPDATE,
|
|
132
|
+
actor,
|
|
133
|
+
subject: `context:agents.md`,
|
|
134
|
+
tags: ["context", "agents"],
|
|
135
|
+
payload: {
|
|
136
|
+
title,
|
|
137
|
+
summary: generateSummary(body.content),
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
catch (logError) {
|
|
142
|
+
console.error('Error logging agents update:', logError);
|
|
143
|
+
}
|
|
144
|
+
return c.json({
|
|
145
|
+
success: true,
|
|
146
|
+
document: {
|
|
147
|
+
filename: 'agents.md',
|
|
148
|
+
title,
|
|
149
|
+
metadata: updatedMetadata,
|
|
150
|
+
content: body.content
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
console.error('Error updating agents document:', error);
|
|
156
|
+
return c.json({ success: false, error: 'Failed to update agents document' }, 500);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
export default app;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
|
-
import project from './project/route.js';
|
|
3
|
-
import architecture from './architecture/route.js';
|
|
4
2
|
import role from './role/route.js';
|
|
3
|
+
import agents from './agents/route.js';
|
|
4
|
+
import team from './team/route.js';
|
|
5
|
+
import memory from './memory/route.js';
|
|
5
6
|
import images from './images/index.js';
|
|
6
7
|
const context = new Hono();
|
|
7
|
-
context.route('/project', project);
|
|
8
|
-
context.route('/architecture', architecture);
|
|
9
8
|
context.route('/role', role);
|
|
9
|
+
context.route('/agents', agents);
|
|
10
|
+
context.route('/team', team);
|
|
11
|
+
context.route('/memory', memory);
|
|
10
12
|
context.route('/images', images);
|
|
11
13
|
export default context;
|
|
@@ -0,0 +1,163 @@
|
|
|
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
|
+
function generateSummary(content, maxLines = 3, maxChars = 200) {
|
|
9
|
+
const cleanContent = content
|
|
10
|
+
.replace(/^#+\s+/gm, '')
|
|
11
|
+
.replace(/[*_`]/g, '')
|
|
12
|
+
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
|
|
13
|
+
.trim();
|
|
14
|
+
const lines = cleanContent.split('\n').filter(line => line.trim().length > 0);
|
|
15
|
+
const summary = lines.slice(0, maxLines).join(' ');
|
|
16
|
+
return summary.length > maxChars
|
|
17
|
+
? summary.substring(0, maxChars) + '...'
|
|
18
|
+
: summary;
|
|
19
|
+
}
|
|
20
|
+
const app = new Hono();
|
|
21
|
+
async function getMemoryPath() {
|
|
22
|
+
const gaitDir = await findGaitDirectory();
|
|
23
|
+
if (!gaitDir)
|
|
24
|
+
return null;
|
|
25
|
+
return path.join(gaitDir, 'context');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* GET /api/v1/context/memory
|
|
29
|
+
*/
|
|
30
|
+
app.get('/', async (c) => {
|
|
31
|
+
try {
|
|
32
|
+
const memoryPath = await getMemoryPath();
|
|
33
|
+
if (!memoryPath) {
|
|
34
|
+
return c.json({ success: false, error: 'GAIT directory not found' }, 404);
|
|
35
|
+
}
|
|
36
|
+
await fs.mkdir(memoryPath, { recursive: true });
|
|
37
|
+
const filePath = path.join(memoryPath, 'memory.md');
|
|
38
|
+
try {
|
|
39
|
+
const fileContent = await fs.readFile(filePath, 'utf-8');
|
|
40
|
+
const { data, content } = matter(fileContent);
|
|
41
|
+
const title = content.match(/^#\s+(.+)$/m)?.[1] || 'Memory';
|
|
42
|
+
const document = {
|
|
43
|
+
filename: 'memory.md',
|
|
44
|
+
metadata: {
|
|
45
|
+
...data,
|
|
46
|
+
updated: data.updated || new Date().toISOString().split('T')[0],
|
|
47
|
+
type: 'memory',
|
|
48
|
+
category: 'context',
|
|
49
|
+
tags: data.tags || []
|
|
50
|
+
},
|
|
51
|
+
content,
|
|
52
|
+
title
|
|
53
|
+
};
|
|
54
|
+
return c.json({ success: true, document });
|
|
55
|
+
}
|
|
56
|
+
catch (fileError) {
|
|
57
|
+
const defaultContent = `# Memory
|
|
58
|
+
|
|
59
|
+
This document stores persistent memory and learned context.
|
|
60
|
+
|
|
61
|
+
## Key Decisions
|
|
62
|
+
|
|
63
|
+
Important decisions made during the project.
|
|
64
|
+
|
|
65
|
+
## Lessons Learned
|
|
66
|
+
|
|
67
|
+
Insights and patterns discovered over time.
|
|
68
|
+
|
|
69
|
+
## Preferences
|
|
70
|
+
|
|
71
|
+
Remembered preferences and conventions.
|
|
72
|
+
`;
|
|
73
|
+
const document = {
|
|
74
|
+
filename: 'memory.md',
|
|
75
|
+
metadata: {
|
|
76
|
+
version: '1.0',
|
|
77
|
+
updated: new Date().toISOString().split('T')[0],
|
|
78
|
+
type: 'memory',
|
|
79
|
+
category: 'context',
|
|
80
|
+
tags: []
|
|
81
|
+
},
|
|
82
|
+
content: defaultContent,
|
|
83
|
+
title: 'Memory'
|
|
84
|
+
};
|
|
85
|
+
return c.json({ success: true, document });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
console.error('Error loading memory document:', error);
|
|
90
|
+
return c.json({ success: false, error: 'Failed to load memory document' }, 500);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
/**
|
|
94
|
+
* PUT /api/v1/context/memory
|
|
95
|
+
*/
|
|
96
|
+
app.put('/', async (c) => {
|
|
97
|
+
try {
|
|
98
|
+
const body = await c.req.json();
|
|
99
|
+
if (!body.content) {
|
|
100
|
+
return c.json({ success: false, error: 'Content is required' }, 400);
|
|
101
|
+
}
|
|
102
|
+
const memoryPath = await getMemoryPath();
|
|
103
|
+
if (!memoryPath) {
|
|
104
|
+
return c.json({ success: false, error: 'GAIT directory not found' }, 404);
|
|
105
|
+
}
|
|
106
|
+
await fs.mkdir(memoryPath, { recursive: true });
|
|
107
|
+
const filePath = path.join(memoryPath, 'memory.md');
|
|
108
|
+
let currentData = {};
|
|
109
|
+
try {
|
|
110
|
+
const currentContent = await fs.readFile(filePath, 'utf-8');
|
|
111
|
+
const { data } = matter(currentContent);
|
|
112
|
+
currentData = data;
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// File doesn't exist, use defaults
|
|
116
|
+
}
|
|
117
|
+
const updatedMetadata = {
|
|
118
|
+
...currentData,
|
|
119
|
+
...body.metadata,
|
|
120
|
+
updated: new Date().toISOString().split('T')[0],
|
|
121
|
+
type: 'memory',
|
|
122
|
+
category: 'context',
|
|
123
|
+
version: currentData.version || '1.0'
|
|
124
|
+
};
|
|
125
|
+
const fileContent = matter.stringify(body.content, updatedMetadata);
|
|
126
|
+
await fs.writeFile(filePath, fileContent, 'utf-8');
|
|
127
|
+
const title = body.title ||
|
|
128
|
+
body.content.match(/^#\s+(.+)$/m)?.[1] ||
|
|
129
|
+
'Memory';
|
|
130
|
+
try {
|
|
131
|
+
const session = await requireAuth(c);
|
|
132
|
+
const actor = session ? `human:${session.email}` : "human:unknown";
|
|
133
|
+
const logger = getLogger();
|
|
134
|
+
logger.log({
|
|
135
|
+
kind: ContextKinds.MEMORY_UPDATE,
|
|
136
|
+
actor,
|
|
137
|
+
subject: `context:memory.md`,
|
|
138
|
+
tags: ["context", "memory"],
|
|
139
|
+
payload: {
|
|
140
|
+
title,
|
|
141
|
+
summary: generateSummary(body.content),
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
catch (logError) {
|
|
146
|
+
console.error('Error logging memory update:', logError);
|
|
147
|
+
}
|
|
148
|
+
return c.json({
|
|
149
|
+
success: true,
|
|
150
|
+
document: {
|
|
151
|
+
filename: 'memory.md',
|
|
152
|
+
title,
|
|
153
|
+
metadata: updatedMetadata,
|
|
154
|
+
content: body.content
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
console.error('Error updating memory document:', error);
|
|
160
|
+
return c.json({ success: false, error: 'Failed to update memory document' }, 500);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
export default app;
|
|
@@ -0,0 +1,159 @@
|
|
|
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
|
+
function generateSummary(content, maxLines = 3, maxChars = 200) {
|
|
9
|
+
const cleanContent = content
|
|
10
|
+
.replace(/^#+\s+/gm, '')
|
|
11
|
+
.replace(/[*_`]/g, '')
|
|
12
|
+
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
|
|
13
|
+
.trim();
|
|
14
|
+
const lines = cleanContent.split('\n').filter(line => line.trim().length > 0);
|
|
15
|
+
const summary = lines.slice(0, maxLines).join(' ');
|
|
16
|
+
return summary.length > maxChars
|
|
17
|
+
? summary.substring(0, maxChars) + '...'
|
|
18
|
+
: summary;
|
|
19
|
+
}
|
|
20
|
+
const app = new Hono();
|
|
21
|
+
async function getTeamPath() {
|
|
22
|
+
const gaitDir = await findGaitDirectory();
|
|
23
|
+
if (!gaitDir)
|
|
24
|
+
return null;
|
|
25
|
+
return path.join(gaitDir, 'context');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* GET /api/v1/context/team
|
|
29
|
+
*/
|
|
30
|
+
app.get('/', async (c) => {
|
|
31
|
+
try {
|
|
32
|
+
const teamPath = await getTeamPath();
|
|
33
|
+
if (!teamPath) {
|
|
34
|
+
return c.json({ success: false, error: 'GAIT directory not found' }, 404);
|
|
35
|
+
}
|
|
36
|
+
await fs.mkdir(teamPath, { recursive: true });
|
|
37
|
+
const filePath = path.join(teamPath, 'team.md');
|
|
38
|
+
try {
|
|
39
|
+
const fileContent = await fs.readFile(filePath, 'utf-8');
|
|
40
|
+
const { data, content } = matter(fileContent);
|
|
41
|
+
const title = content.match(/^#\s+(.+)$/m)?.[1] || 'Team';
|
|
42
|
+
const document = {
|
|
43
|
+
filename: 'team.md',
|
|
44
|
+
metadata: {
|
|
45
|
+
...data,
|
|
46
|
+
updated: data.updated || new Date().toISOString().split('T')[0],
|
|
47
|
+
type: 'team',
|
|
48
|
+
category: 'context',
|
|
49
|
+
tags: data.tags || []
|
|
50
|
+
},
|
|
51
|
+
content,
|
|
52
|
+
title
|
|
53
|
+
};
|
|
54
|
+
return c.json({ success: true, document });
|
|
55
|
+
}
|
|
56
|
+
catch (fileError) {
|
|
57
|
+
const defaultContent = `# Team
|
|
58
|
+
|
|
59
|
+
This document describes the team structure and members.
|
|
60
|
+
|
|
61
|
+
## Team Members
|
|
62
|
+
|
|
63
|
+
List team members, their roles, and responsibilities.
|
|
64
|
+
|
|
65
|
+
## Communication
|
|
66
|
+
|
|
67
|
+
Team communication channels and conventions.
|
|
68
|
+
`;
|
|
69
|
+
const document = {
|
|
70
|
+
filename: 'team.md',
|
|
71
|
+
metadata: {
|
|
72
|
+
version: '1.0',
|
|
73
|
+
updated: new Date().toISOString().split('T')[0],
|
|
74
|
+
type: 'team',
|
|
75
|
+
category: 'context',
|
|
76
|
+
tags: []
|
|
77
|
+
},
|
|
78
|
+
content: defaultContent,
|
|
79
|
+
title: 'Team'
|
|
80
|
+
};
|
|
81
|
+
return c.json({ success: true, document });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.error('Error loading team document:', error);
|
|
86
|
+
return c.json({ success: false, error: 'Failed to load team document' }, 500);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
/**
|
|
90
|
+
* PUT /api/v1/context/team
|
|
91
|
+
*/
|
|
92
|
+
app.put('/', async (c) => {
|
|
93
|
+
try {
|
|
94
|
+
const body = await c.req.json();
|
|
95
|
+
if (!body.content) {
|
|
96
|
+
return c.json({ success: false, error: 'Content is required' }, 400);
|
|
97
|
+
}
|
|
98
|
+
const teamPath = await getTeamPath();
|
|
99
|
+
if (!teamPath) {
|
|
100
|
+
return c.json({ success: false, error: 'GAIT directory not found' }, 404);
|
|
101
|
+
}
|
|
102
|
+
await fs.mkdir(teamPath, { recursive: true });
|
|
103
|
+
const filePath = path.join(teamPath, 'team.md');
|
|
104
|
+
let currentData = {};
|
|
105
|
+
try {
|
|
106
|
+
const currentContent = await fs.readFile(filePath, 'utf-8');
|
|
107
|
+
const { data } = matter(currentContent);
|
|
108
|
+
currentData = data;
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// File doesn't exist, use defaults
|
|
112
|
+
}
|
|
113
|
+
const updatedMetadata = {
|
|
114
|
+
...currentData,
|
|
115
|
+
...body.metadata,
|
|
116
|
+
updated: new Date().toISOString().split('T')[0],
|
|
117
|
+
type: 'team',
|
|
118
|
+
category: 'context',
|
|
119
|
+
version: currentData.version || '1.0'
|
|
120
|
+
};
|
|
121
|
+
const fileContent = matter.stringify(body.content, updatedMetadata);
|
|
122
|
+
await fs.writeFile(filePath, fileContent, 'utf-8');
|
|
123
|
+
const title = body.title ||
|
|
124
|
+
body.content.match(/^#\s+(.+)$/m)?.[1] ||
|
|
125
|
+
'Team';
|
|
126
|
+
try {
|
|
127
|
+
const session = await requireAuth(c);
|
|
128
|
+
const actor = session ? `human:${session.email}` : "human:unknown";
|
|
129
|
+
const logger = getLogger();
|
|
130
|
+
logger.log({
|
|
131
|
+
kind: ContextKinds.TEAM_UPDATE,
|
|
132
|
+
actor,
|
|
133
|
+
subject: `context:team.md`,
|
|
134
|
+
tags: ["context", "team"],
|
|
135
|
+
payload: {
|
|
136
|
+
title,
|
|
137
|
+
summary: generateSummary(body.content),
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
catch (logError) {
|
|
142
|
+
console.error('Error logging team update:', logError);
|
|
143
|
+
}
|
|
144
|
+
return c.json({
|
|
145
|
+
success: true,
|
|
146
|
+
document: {
|
|
147
|
+
filename: 'team.md',
|
|
148
|
+
title,
|
|
149
|
+
metadata: updatedMetadata,
|
|
150
|
+
content: body.content
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
console.error('Error updating team document:', error);
|
|
156
|
+
return c.json({ success: false, error: 'Failed to update team document' }, 500);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
export default app;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
2
|
import crypto from 'crypto';
|
|
3
|
-
import { getRepoStatus, listBranches, createBranch, deleteBranch, switchBranch, mergeBranch, pushCurrent, pullCurrent, listWorktrees, addWorktree, removeWorktree, commitInWorktree, pushWorktree, pullWorktree, checkRemoteAuth, getCredentialConfig, storeCredentials, getCommitDetails, getFileDiff, setRemoteUrl, } from '../../../../lib/git.js';
|
|
3
|
+
import { getRepoStatus, listBranches, createBranch, deleteBranch, switchBranch, mergeBranch, pushCurrent, pullCurrent, listWorktrees, addWorktree, removeWorktree, commitInWorktree, pushWorktree, pullWorktree, checkRemoteAuth, getCredentialConfig, storeCredentials, getCommitDetails, getFileDiff, setRemoteUrl, lsTree, getInstructionFiles, } from '../../../../lib/git.js';
|
|
4
|
+
import { INSTRUCTION_FILE_KINDS } from '@lovelybunch/types';
|
|
4
5
|
import { saveGithubToken, clearGithubToken, readGithubToken, isGithubTokenValid } from '../../../../lib/github-token.js';
|
|
5
6
|
import { createGithubAuthState, consumeGithubAuthState } from '../../../../lib/github-auth-state.js';
|
|
6
7
|
import { resolveCoconutId, resolveControlPlaneUrl } from '../../../../lib/coconut-context.js';
|
|
@@ -674,4 +675,29 @@ app.get('/commits/:sha/files/:filepath{.+}', async (c) => {
|
|
|
674
675
|
return c.json({ success: false, error: { message: e.message || 'Failed to get file diff' } }, 500);
|
|
675
676
|
}
|
|
676
677
|
});
|
|
678
|
+
// ls-tree
|
|
679
|
+
app.get('/ls-tree', async (c) => {
|
|
680
|
+
try {
|
|
681
|
+
const files = await lsTree();
|
|
682
|
+
return c.json({ success: true, data: files });
|
|
683
|
+
}
|
|
684
|
+
catch (e) {
|
|
685
|
+
return c.json({ success: false, error: { message: e.message || 'Failed to list tree' } }, 500);
|
|
686
|
+
}
|
|
687
|
+
});
|
|
688
|
+
// instruction-files
|
|
689
|
+
const VALID_FILTERS = new Set([...INSTRUCTION_FILE_KINDS, 'all']);
|
|
690
|
+
app.get('/instruction-files', async (c) => {
|
|
691
|
+
try {
|
|
692
|
+
const kind = (c.req.query('kind') || 'all');
|
|
693
|
+
if (!VALID_FILTERS.has(kind)) {
|
|
694
|
+
return c.json({ success: false, error: { message: `Invalid kind. Must be one of: ${[...VALID_FILTERS].join(', ')}` } }, 400);
|
|
695
|
+
}
|
|
696
|
+
const data = await getInstructionFiles(kind);
|
|
697
|
+
return c.json({ success: true, data });
|
|
698
|
+
}
|
|
699
|
+
catch (e) {
|
|
700
|
+
return c.json({ success: false, error: { message: e.message || 'Failed to retrieve instruction files' } }, 500);
|
|
701
|
+
}
|
|
702
|
+
});
|
|
677
703
|
export default app;
|
|
@@ -9,12 +9,6 @@ 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
|
-
description?: string;
|
|
15
|
-
prompt: string;
|
|
16
|
-
model: string;
|
|
17
|
-
status: ScheduledJobStatus;
|
|
18
12
|
schedule: {
|
|
19
13
|
type: "cron";
|
|
20
14
|
expression: string;
|
|
@@ -27,29 +21,32 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
|
|
|
27
21
|
timezone?: string;
|
|
28
22
|
anchorHour?: number;
|
|
29
23
|
};
|
|
24
|
+
description?: string;
|
|
25
|
+
id: string;
|
|
26
|
+
name: string;
|
|
27
|
+
prompt: string;
|
|
28
|
+
model: string;
|
|
29
|
+
status: ScheduledJobStatus;
|
|
30
30
|
metadata: {
|
|
31
31
|
createdAt: string;
|
|
32
32
|
updatedAt: string;
|
|
33
33
|
lastRunAt?: string;
|
|
34
34
|
nextRunAt?: string;
|
|
35
35
|
};
|
|
36
|
+
tags?: string[];
|
|
37
|
+
contextPaths?: string[];
|
|
38
|
+
agentId?: string;
|
|
39
|
+
agentIds?: string[];
|
|
40
|
+
mcpServers?: string[];
|
|
36
41
|
runs: {
|
|
42
|
+
error?: string;
|
|
37
43
|
id: string;
|
|
44
|
+
status: import("@lovelybunch/types").ScheduledJobRunStatus;
|
|
38
45
|
jobId: string;
|
|
39
46
|
trigger: import("@lovelybunch/types").ScheduledJobTrigger;
|
|
40
|
-
status: import("@lovelybunch/types").ScheduledJobRunStatus;
|
|
41
47
|
startedAt: string;
|
|
42
48
|
finishedAt?: string;
|
|
43
|
-
outputPath?: string;
|
|
44
|
-
summary?: string;
|
|
45
|
-
error?: string;
|
|
46
|
-
cliCommand?: string;
|
|
47
49
|
}[];
|
|
48
|
-
tags?: string[];
|
|
49
|
-
contextPaths?: string[];
|
|
50
|
-
agentId?: string;
|
|
51
|
-
agentIds?: string[];
|
|
52
|
-
mcpServers?: string[];
|
|
53
50
|
};
|
|
54
51
|
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
|
|
55
52
|
success: false;
|
|
@@ -73,12 +70,6 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
|
|
|
73
70
|
}, 400, "json">) | (Response & import("hono").TypedResponse<{
|
|
74
71
|
success: true;
|
|
75
72
|
data: {
|
|
76
|
-
id: string;
|
|
77
|
-
name: string;
|
|
78
|
-
description?: string;
|
|
79
|
-
prompt: string;
|
|
80
|
-
model: string;
|
|
81
|
-
status: ScheduledJobStatus;
|
|
82
73
|
schedule: {
|
|
83
74
|
type: "cron";
|
|
84
75
|
expression: string;
|
|
@@ -91,29 +82,32 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
|
|
|
91
82
|
timezone?: string;
|
|
92
83
|
anchorHour?: number;
|
|
93
84
|
};
|
|
85
|
+
description?: string;
|
|
86
|
+
id: string;
|
|
87
|
+
name: string;
|
|
88
|
+
prompt: string;
|
|
89
|
+
model: string;
|
|
90
|
+
status: ScheduledJobStatus;
|
|
94
91
|
metadata: {
|
|
95
92
|
createdAt: string;
|
|
96
93
|
updatedAt: string;
|
|
97
94
|
lastRunAt?: string;
|
|
98
95
|
nextRunAt?: string;
|
|
99
96
|
};
|
|
97
|
+
tags?: string[];
|
|
98
|
+
contextPaths?: string[];
|
|
99
|
+
agentId?: string;
|
|
100
|
+
agentIds?: string[];
|
|
101
|
+
mcpServers?: string[];
|
|
100
102
|
runs: {
|
|
103
|
+
error?: string;
|
|
101
104
|
id: string;
|
|
105
|
+
status: import("@lovelybunch/types").ScheduledJobRunStatus;
|
|
102
106
|
jobId: string;
|
|
103
107
|
trigger: import("@lovelybunch/types").ScheduledJobTrigger;
|
|
104
|
-
status: import("@lovelybunch/types").ScheduledJobRunStatus;
|
|
105
108
|
startedAt: string;
|
|
106
109
|
finishedAt?: string;
|
|
107
|
-
outputPath?: string;
|
|
108
|
-
summary?: string;
|
|
109
|
-
error?: string;
|
|
110
|
-
cliCommand?: string;
|
|
111
110
|
}[];
|
|
112
|
-
tags?: string[];
|
|
113
|
-
contextPaths?: string[];
|
|
114
|
-
agentId?: string;
|
|
115
|
-
agentIds?: string[];
|
|
116
|
-
mcpServers?: string[];
|
|
117
111
|
};
|
|
118
112
|
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
|
|
119
113
|
success: false;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { JobStore } from '../../../../../lib/jobs/job-store.js';
|
|
2
2
|
import { getGlobalJobScheduler } from '../../../../../lib/jobs/global-job-scheduler.js';
|
|
3
|
-
import { normalizeSchedule, normalizeStatus, } from '../route.js';
|
|
3
|
+
import { normalizeSchedule, normalizeStatus, withLightweightRuns, } from '../route.js';
|
|
4
4
|
const store = new JobStore();
|
|
5
5
|
const scheduler = getGlobalJobScheduler();
|
|
6
6
|
function normalizeScheduleUpdate(current, incoming) {
|
|
@@ -32,7 +32,7 @@ export async function GET(c) {
|
|
|
32
32
|
}
|
|
33
33
|
}, 404);
|
|
34
34
|
}
|
|
35
|
-
return c.json({ success: true, data: job });
|
|
35
|
+
return c.json({ success: true, data: withLightweightRuns(job) });
|
|
36
36
|
}
|
|
37
37
|
catch (error) {
|
|
38
38
|
console.error('Failed to fetch job:', error);
|
|
@@ -101,7 +101,7 @@ export async function PATCH(c) {
|
|
|
101
101
|
const reloaded = await store.getJob(updated.id);
|
|
102
102
|
return c.json({
|
|
103
103
|
success: true,
|
|
104
|
-
data: reloaded ?? updated
|
|
104
|
+
data: withLightweightRuns(reloaded ?? updated)
|
|
105
105
|
});
|
|
106
106
|
}
|
|
107
107
|
catch (error) {
|