@lovelybunch/api 1.0.78-alpha.2 → 1.0.78-alpha.4
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/auth/auth-manager.d.ts +1 -1
- package/dist/lib/auth/auth-manager.js +2 -1
- package/dist/lib/symlinks/symlink-manager.d.ts +3 -4
- package/dist/lib/symlinks/symlink-manager.js +49 -30
- package/dist/lib/terminal/terminal-manager.d.ts +8 -5
- package/dist/lib/terminal/terminal-manager.js +29 -5
- package/dist/middleware/auth.d.ts +23 -2
- package/dist/middleware/auth.js +44 -4
- package/dist/routes/api/v1/ai/route.js +117 -4
- package/dist/routes/api/v1/api-keys/route.js +7 -1
- package/dist/routes/api/v1/jobs/[id]/route.d.ts +20 -20
- package/dist/routes/api/v1/jobs/route.d.ts +20 -20
- package/dist/routes/api/v1/knowledge/[filename]/route.js +29 -7
- package/dist/routes/api/v1/knowledge/route.js +13 -3
- package/dist/routes/api/v1/terminal/[taskId]/create/route.js +2 -1
- package/dist/routes/api/v1/terminal/[taskId]/destroy/route.js +2 -1
- package/dist/routes/api/v1/terminal/[taskId]/resize/route.js +2 -1
- package/dist/routes/api/v1/terminal/code/route.js +2 -1
- package/dist/routes/api/v1/terminal/sessions/route.js +5 -3
- package/dist/server-with-static.js +3 -3
- package/dist/server.js +3 -3
- package/package.json +4 -4
- package/static/assets/{ActivityPage-B83wvBeD.js → ActivityPage-CtFAFqlg.js} +1 -1
- package/static/assets/{AgentsContextEditPage-CgHVDbMV.js → AgentsContextEditPage-CsRJvzE6.js} +1 -1
- package/static/assets/{AgentsContextPage-DMf6khxC.js → AgentsContextPage-CWCs8CgG.js} +1 -1
- package/static/assets/{ApiKeysSettingsPage-DzwmYsom.js → ApiKeysSettingsPage-B4b_fmJg.js} +1 -1
- package/static/assets/{AuthSettingsPage-B5auAs_s.js → AuthSettingsPage-O3UdLrHC.js} +1 -1
- package/static/assets/{CallbackPage-Cxc5lXE4.js → CallbackPage-WTwVSxdx.js} +1 -1
- package/static/assets/{CoconutCallbackPage-D7Xkrh70.js → CoconutCallbackPage-LEWgUV8J.js} +1 -1
- package/static/assets/{CodePage-D37jAzN1.js → CodePage-DpVmg_UD.js} +1 -1
- package/static/assets/{CollapsibleSection-Bp5C0iRa.js → CollapsibleSection-BHag26Vf.js} +1 -1
- package/static/assets/{DashboardPage-DvWWsMjr.js → DashboardPage-BZnCikpf.js} +1 -1
- package/static/assets/{GitPage-yXgpwI2f.js → GitPage-DD6dgeNu.js} +1 -1
- package/static/assets/{GitSettingsPage-B5bgtLBU.js → GitSettingsPage-CLHCZ6at.js} +1 -1
- package/static/assets/{IdentityPage-Dpr6Z5Id.js → IdentityPage-DtzLSTYd.js} +1 -1
- package/static/assets/{ImplementationStepsEditor-B2e4ML0a.js → ImplementationStepsEditor-Ca1aygKs.js} +1 -1
- package/static/assets/{IntegrationsSettingsPage-CHknhE_l.js → IntegrationsSettingsPage-C2tzpbuI.js} +1 -1
- package/static/assets/{JobDetailPage-BnuDmxZF.js → JobDetailPage-B03z4VgG.js} +1 -1
- package/static/assets/{KnowledgeDetailPage-DFxjt46s.js → KnowledgeDetailPage-XslT5GUv.js} +1 -1
- package/static/assets/{KnowledgeEditPage-Bu1l5VHq.js → KnowledgeEditPage-5NFEnGJh.js} +1 -1
- package/static/assets/{KnowledgePage-CzPB44SA.js → KnowledgePage-Dzh409qU.js} +1 -1
- package/static/assets/{LoginPage-D_ZO_RBy.js → LoginPage-IDVkR1zN.js} +1 -1
- package/static/assets/{MailInboxPage-CXlwKTvH.js → MailInboxPage-CXaBqNl2.js} +1 -1
- package/static/assets/{MailProcessingModal-_C2SsbSm.js → MailProcessingModal-BWyzTMEv.js} +1 -1
- package/static/assets/{MailReadPage-BtgLL4bW.js → MailReadPage-DPGuT0gC.js} +1 -1
- package/static/assets/{MailSentPage-nhZKfZOk.js → MailSentPage-Dtq37Kap.js} +1 -1
- package/static/assets/{McpSettingsPage-C6PdoBPD.js → McpSettingsPage-BiCSPaAJ.js} +1 -1
- package/static/assets/{MemoryEditPage-BpioH6_S.js → MemoryEditPage-Dfa6MsnE.js} +1 -1
- package/static/assets/{MemoryPage-DrPL8CG7.js → MemoryPage-BqUngqIS.js} +1 -1
- package/static/assets/{NewKnowledgePage-rqgKv0VA.js → NewKnowledgePage-BmYwcO98.js} +1 -1
- package/static/assets/{NewSkillPage-0pSUX9z9.js → NewSkillPage-BfNaXH37.js} +1 -1
- package/static/assets/{NewTaskPage-BpCJGis6.js → NewTaskPage-Ctmh2uiJ.js} +1 -1
- package/static/assets/{NotFoundPage-sSYe1QSz.js → NotFoundPage-a2erdq4H.js} +1 -1
- package/static/assets/{NotificationsSettingsPage-CS_ZT6t0.js → NotificationsSettingsPage-BB9QuyUf.js} +1 -1
- package/static/assets/{PromptsSettingsPage-DTq8cZqP.js → PromptsSettingsPage-BZLwTFcd.js} +1 -1
- package/static/assets/{ResourceDetailPage-DYriLbDS.js → ResourceDetailPage-DRWNjykw.js} +1 -1
- package/static/assets/{ResourcesPage-D8QBQrZP.js → ResourcesPage-C3Lx8hz_.js} +1 -1
- package/static/assets/{RoleEditPage-Ci_1L_e_.js → RoleEditPage-W9SV6Mwr.js} +1 -1
- package/static/assets/{RolePage-DMJ7_wD0.js → RolePage-DWWo77tA.js} +1 -1
- package/static/assets/{RulesSettingsPage-CuB55bRV.js → RulesSettingsPage-BKsadZ7r.js} +1 -1
- package/static/assets/{RunDetailPage-CBW-swIi.js → RunDetailPage-C6miynGX.js} +1 -1
- package/static/assets/{SchedulePage-BIklILDy.js → SchedulePage-B6s-CkVg.js} +1 -1
- package/static/assets/{SkillDetailPage-D-1PWQiM.js → SkillDetailPage-DYkLxRjB.js} +1 -1
- package/static/assets/{SkillEditPage-BZB-YL56.js → SkillEditPage-DIB2lUMz.js} +1 -1
- package/static/assets/{SkillsPage-BezXmUjc.js → SkillsPage-BgR2gdCy.js} +1 -1
- package/static/assets/{SkillsSettingsPage-Cqo9_iDG.js → SkillsSettingsPage-CoDOG0YQ.js} +1 -1
- package/static/assets/{SourceInput-TEQpt4P-.js → SourceInput-CS6u1yPi.js} +1 -1
- package/static/assets/{TagInput-DBUiVBgy.js → TagInput-C3WzbX6I.js} +1 -1
- package/static/assets/{TaskDetailPage-Dq0gDy_e.js → TaskDetailPage-DEBBE0D8.js} +1 -1
- package/static/assets/{TaskEditPage-CWGvjTjo.js → TaskEditPage-B26tEsUP.js} +1 -1
- package/static/assets/{TasksPage-BIPx8Qde.js → TasksPage-pqQ7VlC3.js} +1 -1
- package/static/assets/{TeamEditPage-BlNa1eMV.js → TeamEditPage-C6DugOii.js} +1 -1
- package/static/assets/{TeamPage-D1usM-fA.js → TeamPage-BDqQZ6Rr.js} +1 -1
- package/static/assets/{TerminalPage-CLh6hap0.js → TerminalPage-pjss7X1h.js} +1 -1
- package/static/assets/{TerminalSessionPage-DaHcsdNf.js → TerminalSessionPage-C9sJ_13t.js} +1 -1
- package/static/assets/{UserPreferencesPage-CL-nPXv7.js → UserPreferencesPage-BrpKf14p.js} +1 -1
- package/static/assets/{UserSettingsPage-BGIalWgn.js → UserSettingsPage-BbazpvdQ.js} +1 -1
- package/static/assets/{UtilitiesPage-ewlEzigp.js → UtilitiesPage-niclH8kb.js} +1 -1
- package/static/assets/{alert-0GENnoy_.js → alert-DBhIskRX.js} +1 -1
- package/static/assets/{arrow-down-Bfya-JPw.js → arrow-down-TpeNydxP.js} +1 -1
- package/static/assets/{arrow-left-CY9PaWRG.js → arrow-left-_lXkdm9Q.js} +1 -1
- package/static/assets/{arrow-up-BAAEIUsa.js → arrow-up-DaIMsmSO.js} +1 -1
- package/static/assets/{arrow-up-down-0F-DzXlw.js → arrow-up-down-C7wqirJv.js} +1 -1
- package/static/assets/{badge-D1sVaZJG.js → badge-TeAh_Zh0.js} +1 -1
- package/static/assets/{browser-modal-CELhtOVM.js → browser-modal-BpGFpZZj.js} +1 -1
- package/static/assets/{card-D2eA49nP.js → card-CiLixwCG.js} +1 -1
- package/static/assets/{chevron-left-Cbc591ge.js → chevron-left-CuMfw52D.js} +1 -1
- package/static/assets/{chevron-up-DD_GdI6e.js → chevron-up-B4J4D5aE.js} +1 -1
- package/static/assets/{chevrons-up-CQ8ZAERh.js → chevrons-up-Dcs-Dj4B.js} +1 -1
- package/static/assets/{circle-alert-DsESVtwL.js → circle-alert-nI75emvr.js} +1 -1
- package/static/assets/{circle-check-big-HtBmMXFt.js → circle-check-big-CxxxVvOw.js} +1 -1
- package/static/assets/{circle-check-BXiPFdlh.js → circle-check-k6ER9afD.js} +1 -1
- package/static/assets/{circle-play-KOICOGsB.js → circle-play-B4D0d7YW.js} +1 -1
- package/static/assets/{circle-x-B_4fmWCG.js → circle-x-BzPgPb47.js} +1 -1
- package/static/assets/{clipboard-ByOf6HYl.js → clipboard-CLObCrC4.js} +1 -1
- package/static/assets/{clock-CdH0GtRs.js → clock-BK-8XMqv.js} +1 -1
- package/static/assets/{code-7mdwwNlt.js → code-lhIVzb1q.js} +1 -1
- package/static/assets/{download-Bh7rihtL.js → download-ChgFRTfC.js} +1 -1
- package/static/assets/{external-link-DGl8WNOe.js → external-link-D4kianlP.js} +1 -1
- package/static/assets/{eye-C_ckl4MB.js → eye-H1JnZ9E9.js} +1 -1
- package/static/assets/{folder-git-2-C9MVgN94.js → folder-git-2-BZGvXcyj.js} +1 -1
- package/static/assets/{globe-BvwRv4le.js → globe-DAzCOUla.js} +1 -1
- package/static/assets/{index-C611wGVc.js → index-B7UEVagI.js} +1 -1
- package/static/assets/{index-DrTHjwZ8.js → index-Bik-wLXi.js} +1 -1
- package/static/assets/{index-5M1EX2JZ.js → index-BlOxV6pf.js} +1 -1
- package/static/assets/{index-BUOPcczo.js → index-C7dpn8dK.js} +1 -1
- package/static/assets/{index-CnEgD2Gk.js → index-C9wsYS8C.js} +1 -1
- package/static/assets/{index-CzcqLknE.js → index-Ck9sMDuo.js} +1 -1
- package/static/assets/{index-DFPcCMnD.js → index-DMeIDO6W.js} +1 -1
- package/static/assets/{index-BjiLTiAs.js → index-DOpjlxVe.js} +1 -1
- package/static/assets/{index-CjL8t7WM.js → index-DT4K0HgO.js} +1 -1
- package/static/assets/{index-Dx8evZfS.js → index-DeF-CCVg.js} +1 -1
- package/static/assets/{index-ja6BPXln.js → index-DkvhkCo1.js} +1 -1
- package/static/assets/{index-BD57V9U9.js → index-DuDW1LwX.js} +1 -1
- package/static/assets/{index-D1CqgHy0.js → index-Dy_-mpPq.js} +1 -1
- package/static/assets/{index-Bx26Q2JC.js → index-SUQrIHd7.js} +3 -3
- package/static/assets/{index-DH0iEeh5.js → index-c-gr7Bew.js} +1 -1
- package/static/assets/{index-Ci5Lsqgb.js → index-kJaEkklL.js} +1 -1
- package/static/assets/{index-CjU4ihqi.js → index-rslXoTnS.js} +1 -1
- package/static/assets/{index-CLD_gdRP.js → index-rwsZ-IsL.js} +1 -1
- package/static/assets/{index-CCq3bqJI.js → index-sBbL8_xu.js} +1 -1
- package/static/assets/{info-_JNAJSs5.js → info-CVmPHERQ.js} +1 -1
- package/static/assets/{label-fHWG59jZ.js → label-n5pqaObd.js} +1 -1
- package/static/assets/{markdown-editor-Dmq8d9Xs.js → markdown-editor-Cvh5pZzJ.js} +3 -3
- package/static/assets/{message-square-BaejhTPJ.js → message-square-BmnqRsu6.js} +1 -1
- package/static/assets/{paperclip-xnYUFZwQ.js → paperclip-BwcNeQ_C.js} +1 -1
- package/static/assets/{pause-plM13_Um.js → pause-CUswidZW.js} +1 -1
- package/static/assets/{play-DR4AKc9R.js → play-DyZbNGiK.js} +1 -1
- package/static/assets/{radio-group-CE9meIEG.js → radio-group-Bzu_d7xN.js} +1 -1
- package/static/assets/{refresh-cw-CLSROYiq.js → refresh-cw-DvQ0rmk7.js} +1 -1
- package/static/assets/{search-VcMqZsDm.js → search-kc_tG8Rf.js} +1 -1
- package/static/assets/{select-ChtjmmOf.js → select-CIOYQA7a.js} +1 -1
- package/static/assets/{server-DVlnoAGu.js → server-CWIJxRf0.js} +1 -1
- package/static/assets/{switch-BMBFkcUU.js → switch-DczkR77Y.js} +1 -1
- package/static/assets/{tabs-DE4DShnU.js → tabs-DOEakD76.js} +1 -1
- package/static/assets/{tag-czmQSC6D.js → tag-Dc8sXXlM.js} +1 -1
- package/static/assets/{terminal-preview-B8UB7Pz6.js → terminal-preview-D8oASUdZ.js} +1 -1
- package/static/assets/{triangle-alert-RuOrTU7H.js → triangle-alert-C-5ixej6.js} +1 -1
- package/static/assets/{use-terminal-C3O4m83z.js → use-terminal-xdcf4Z2G.js} +1 -1
- package/static/assets/{video-BEV0GqmB.js → video-CBneSE9B.js} +1 -1
- package/static/index.html +1 -1
|
@@ -12,6 +12,16 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
|
|
|
12
12
|
id: string;
|
|
13
13
|
name: string;
|
|
14
14
|
status: ScheduledJobStatus;
|
|
15
|
+
tags?: string[];
|
|
16
|
+
description?: string;
|
|
17
|
+
model: string;
|
|
18
|
+
metadata: {
|
|
19
|
+
createdAt: string;
|
|
20
|
+
updatedAt: string;
|
|
21
|
+
lastRunAt?: string;
|
|
22
|
+
nextRunAt?: string;
|
|
23
|
+
};
|
|
24
|
+
prompt: string;
|
|
15
25
|
schedule: {
|
|
16
26
|
type: "cron";
|
|
17
27
|
expression: string;
|
|
@@ -24,16 +34,6 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
|
|
|
24
34
|
timezone?: string;
|
|
25
35
|
anchorHour?: number;
|
|
26
36
|
};
|
|
27
|
-
description?: string;
|
|
28
|
-
prompt: string;
|
|
29
|
-
model: string;
|
|
30
|
-
metadata: {
|
|
31
|
-
createdAt: string;
|
|
32
|
-
updatedAt: string;
|
|
33
|
-
lastRunAt?: string;
|
|
34
|
-
nextRunAt?: string;
|
|
35
|
-
};
|
|
36
|
-
tags?: string[];
|
|
37
37
|
contextPaths?: string[];
|
|
38
38
|
agentId?: string;
|
|
39
39
|
agentIds?: string[];
|
|
@@ -73,6 +73,16 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
|
|
|
73
73
|
id: string;
|
|
74
74
|
name: string;
|
|
75
75
|
status: ScheduledJobStatus;
|
|
76
|
+
tags?: string[];
|
|
77
|
+
description?: string;
|
|
78
|
+
model: string;
|
|
79
|
+
metadata: {
|
|
80
|
+
createdAt: string;
|
|
81
|
+
updatedAt: string;
|
|
82
|
+
lastRunAt?: string;
|
|
83
|
+
nextRunAt?: string;
|
|
84
|
+
};
|
|
85
|
+
prompt: string;
|
|
76
86
|
schedule: {
|
|
77
87
|
type: "cron";
|
|
78
88
|
expression: string;
|
|
@@ -85,16 +95,6 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
|
|
|
85
95
|
timezone?: string;
|
|
86
96
|
anchorHour?: number;
|
|
87
97
|
};
|
|
88
|
-
description?: string;
|
|
89
|
-
prompt: string;
|
|
90
|
-
model: string;
|
|
91
|
-
metadata: {
|
|
92
|
-
createdAt: string;
|
|
93
|
-
updatedAt: string;
|
|
94
|
-
lastRunAt?: string;
|
|
95
|
-
nextRunAt?: string;
|
|
96
|
-
};
|
|
97
|
-
tags?: string[];
|
|
98
98
|
contextPaths?: string[];
|
|
99
99
|
agentId?: string;
|
|
100
100
|
agentIds?: string[];
|
|
@@ -14,6 +14,16 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
|
|
|
14
14
|
id: string;
|
|
15
15
|
name: string;
|
|
16
16
|
status: ScheduledJobStatus;
|
|
17
|
+
tags?: string[];
|
|
18
|
+
description?: string;
|
|
19
|
+
model: string;
|
|
20
|
+
metadata: {
|
|
21
|
+
createdAt: string;
|
|
22
|
+
updatedAt: string;
|
|
23
|
+
lastRunAt?: string;
|
|
24
|
+
nextRunAt?: string;
|
|
25
|
+
};
|
|
26
|
+
prompt: string;
|
|
17
27
|
schedule: {
|
|
18
28
|
type: "cron";
|
|
19
29
|
expression: string;
|
|
@@ -26,16 +36,6 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
|
|
|
26
36
|
timezone?: string;
|
|
27
37
|
anchorHour?: number;
|
|
28
38
|
};
|
|
29
|
-
description?: string;
|
|
30
|
-
prompt: string;
|
|
31
|
-
model: string;
|
|
32
|
-
metadata: {
|
|
33
|
-
createdAt: string;
|
|
34
|
-
updatedAt: string;
|
|
35
|
-
lastRunAt?: string;
|
|
36
|
-
nextRunAt?: string;
|
|
37
|
-
};
|
|
38
|
-
tags?: string[];
|
|
39
39
|
contextPaths?: string[];
|
|
40
40
|
agentId?: string;
|
|
41
41
|
agentIds?: string[];
|
|
@@ -69,6 +69,16 @@ export declare function POST(c: Context): Promise<(Response & import("hono").Typ
|
|
|
69
69
|
id: string;
|
|
70
70
|
name: string;
|
|
71
71
|
status: ScheduledJobStatus;
|
|
72
|
+
tags?: string[];
|
|
73
|
+
description?: string;
|
|
74
|
+
model: string;
|
|
75
|
+
metadata: {
|
|
76
|
+
createdAt: string;
|
|
77
|
+
updatedAt: string;
|
|
78
|
+
lastRunAt?: string;
|
|
79
|
+
nextRunAt?: string;
|
|
80
|
+
};
|
|
81
|
+
prompt: string;
|
|
72
82
|
schedule: {
|
|
73
83
|
type: "cron";
|
|
74
84
|
expression: string;
|
|
@@ -81,16 +91,6 @@ export declare function POST(c: Context): Promise<(Response & import("hono").Typ
|
|
|
81
91
|
timezone?: string;
|
|
82
92
|
anchorHour?: number;
|
|
83
93
|
};
|
|
84
|
-
description?: string;
|
|
85
|
-
prompt: string;
|
|
86
|
-
model: string;
|
|
87
|
-
metadata: {
|
|
88
|
-
createdAt: string;
|
|
89
|
-
updatedAt: string;
|
|
90
|
-
lastRunAt?: string;
|
|
91
|
-
nextRunAt?: string;
|
|
92
|
-
};
|
|
93
|
-
tags?: string[];
|
|
94
94
|
contextPaths?: string[];
|
|
95
95
|
agentId?: string;
|
|
96
96
|
agentIds?: string[];
|
|
@@ -47,6 +47,22 @@ function generateFilename(title) {
|
|
|
47
47
|
.replace(/^-|-$/g, '') // Remove leading/trailing hyphens
|
|
48
48
|
+ '.md';
|
|
49
49
|
}
|
|
50
|
+
function resolveKnowledgeFile(knowledgePath, filename) {
|
|
51
|
+
const actualFilename = filename.endsWith('.md') ? filename : `${filename}.md`;
|
|
52
|
+
if (!actualFilename ||
|
|
53
|
+
actualFilename.includes('/') ||
|
|
54
|
+
actualFilename.includes('\\') ||
|
|
55
|
+
actualFilename.split(/[\\/]/).some(part => part === '..')) {
|
|
56
|
+
throw new Error('Invalid knowledge filename');
|
|
57
|
+
}
|
|
58
|
+
const resolvedBase = path.resolve(knowledgePath);
|
|
59
|
+
const filePath = path.resolve(resolvedBase, actualFilename);
|
|
60
|
+
const relative = path.relative(resolvedBase, filePath);
|
|
61
|
+
if (relative === '' || relative.startsWith('..') || path.isAbsolute(relative)) {
|
|
62
|
+
throw new Error('Invalid knowledge filename');
|
|
63
|
+
}
|
|
64
|
+
return { actualFilename, filePath };
|
|
65
|
+
}
|
|
50
66
|
/**
|
|
51
67
|
* GET /api/v1/knowledge/:filename
|
|
52
68
|
* Load a specific knowledge document
|
|
@@ -55,8 +71,7 @@ app.get('/:filename', async (c) => {
|
|
|
55
71
|
try {
|
|
56
72
|
const filename = c.req.param('filename');
|
|
57
73
|
const knowledgePath = getKnowledgePath();
|
|
58
|
-
const actualFilename =
|
|
59
|
-
const filePath = path.join(knowledgePath, actualFilename);
|
|
74
|
+
const { actualFilename, filePath } = resolveKnowledgeFile(knowledgePath, filename);
|
|
60
75
|
const [fileContent, stats] = await Promise.all([
|
|
61
76
|
fs.readFile(filePath, 'utf-8'),
|
|
62
77
|
fs.stat(filePath)
|
|
@@ -84,6 +99,9 @@ app.get('/:filename', async (c) => {
|
|
|
84
99
|
});
|
|
85
100
|
}
|
|
86
101
|
catch (error) {
|
|
102
|
+
if (error.message === 'Invalid knowledge filename') {
|
|
103
|
+
return c.json({ success: false, error: 'Invalid knowledge filename' }, 400);
|
|
104
|
+
}
|
|
87
105
|
if (error.code === 'ENOENT') {
|
|
88
106
|
return c.json({ success: false, error: 'Knowledge document not found' }, 404);
|
|
89
107
|
}
|
|
@@ -100,8 +118,7 @@ app.put('/:filename', async (c) => {
|
|
|
100
118
|
const filename = c.req.param('filename');
|
|
101
119
|
const body = await c.req.json();
|
|
102
120
|
const knowledgePath = getKnowledgePath();
|
|
103
|
-
const actualFilename =
|
|
104
|
-
const filePath = path.join(knowledgePath, actualFilename);
|
|
121
|
+
const { actualFilename, filePath } = resolveKnowledgeFile(knowledgePath, filename);
|
|
105
122
|
// Check if file exists
|
|
106
123
|
try {
|
|
107
124
|
await fs.access(filePath);
|
|
@@ -136,7 +153,7 @@ app.put('/:filename', async (c) => {
|
|
|
136
153
|
// Only rename file if title explicitly changed
|
|
137
154
|
if (titleChanged) {
|
|
138
155
|
newFilename = generateFilename(newTitle);
|
|
139
|
-
newFilePath =
|
|
156
|
+
newFilePath = resolveKnowledgeFile(knowledgePath, newFilename).filePath;
|
|
140
157
|
// Check if new filename conflicts with existing file (unless it's the same file)
|
|
141
158
|
if (newFilename !== actualFilename) {
|
|
142
159
|
try {
|
|
@@ -189,6 +206,9 @@ app.put('/:filename', async (c) => {
|
|
|
189
206
|
});
|
|
190
207
|
}
|
|
191
208
|
catch (error) {
|
|
209
|
+
if (error.message === 'Invalid knowledge filename') {
|
|
210
|
+
return c.json({ success: false, error: 'Invalid knowledge filename' }, 400);
|
|
211
|
+
}
|
|
192
212
|
console.error('Error updating knowledge document:', error);
|
|
193
213
|
return c.json({ success: false, error: 'Failed to update knowledge document' }, 500);
|
|
194
214
|
}
|
|
@@ -201,8 +221,7 @@ app.delete('/:filename', async (c) => {
|
|
|
201
221
|
try {
|
|
202
222
|
const filename = c.req.param('filename');
|
|
203
223
|
const knowledgePath = getKnowledgePath();
|
|
204
|
-
const actualFilename =
|
|
205
|
-
const filePath = path.join(knowledgePath, actualFilename);
|
|
224
|
+
const { actualFilename, filePath } = resolveKnowledgeFile(knowledgePath, filename);
|
|
206
225
|
// Check if file exists
|
|
207
226
|
try {
|
|
208
227
|
await fs.access(filePath);
|
|
@@ -247,6 +266,9 @@ app.delete('/:filename', async (c) => {
|
|
|
247
266
|
});
|
|
248
267
|
}
|
|
249
268
|
catch (error) {
|
|
269
|
+
if (error.message === 'Invalid knowledge filename') {
|
|
270
|
+
return c.json({ success: false, error: 'Invalid knowledge filename' }, 400);
|
|
271
|
+
}
|
|
250
272
|
console.error('Error deleting knowledge document:', error);
|
|
251
273
|
return c.json({ success: false, error: 'Failed to delete knowledge document' }, 500);
|
|
252
274
|
}
|
|
@@ -3,7 +3,7 @@ import { promises as fs } from 'fs';
|
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import matter from 'gray-matter';
|
|
5
5
|
import filenameRoute from './[filename]/index.js';
|
|
6
|
-
import { listKnowledge } from '@lovelybunch/core';
|
|
6
|
+
import { listKnowledge, sanitizeProvidedFilename } from '@lovelybunch/core';
|
|
7
7
|
import { getLogger, KnowledgeKinds } from '@lovelybunch/core/logging';
|
|
8
8
|
import { requireAuth } from '../../../../middleware/auth.js';
|
|
9
9
|
// Helper function to generate a simple summary from content
|
|
@@ -104,12 +104,22 @@ app.post('/', async (c) => {
|
|
|
104
104
|
}
|
|
105
105
|
const knowledgePath = getKnowledgePath();
|
|
106
106
|
await fs.mkdir(knowledgePath, { recursive: true });
|
|
107
|
-
|
|
107
|
+
let filename;
|
|
108
|
+
if (typeof body.filename === 'string' && body.filename.trim().length > 0) {
|
|
109
|
+
const sanitized = sanitizeProvidedFilename(body.filename);
|
|
110
|
+
if (!sanitized) {
|
|
111
|
+
return c.json({ success: false, error: 'Invalid filename' }, 400);
|
|
112
|
+
}
|
|
113
|
+
filename = sanitized;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
filename = generateFilename(body.title);
|
|
117
|
+
}
|
|
108
118
|
const filePath = path.join(knowledgePath, filename);
|
|
109
119
|
// Check if file already exists
|
|
110
120
|
try {
|
|
111
121
|
await fs.access(filePath);
|
|
112
|
-
return c.json({ success: false, error: 'A document with this
|
|
122
|
+
return c.json({ success: false, error: 'A document with this filename already exists' }, 409);
|
|
113
123
|
}
|
|
114
124
|
catch {
|
|
115
125
|
// File doesn't exist, which is what we want
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getGlobalTerminalManager } from '../../../../../../lib/terminal/global-manager.js';
|
|
2
2
|
import { loadUserSettings } from '../../../../../../lib/user-preferences.js';
|
|
3
|
+
import { getAuthPrincipalKey } from '../../../../../../middleware/auth.js';
|
|
3
4
|
export async function POST(c) {
|
|
4
5
|
try {
|
|
5
6
|
const taskId = c.req.param('taskId');
|
|
@@ -13,7 +14,7 @@ export async function POST(c) {
|
|
|
13
14
|
const shellPreference = (userSettings.preferences.terminalShell || 'bash');
|
|
14
15
|
// Create a new terminal session for this task
|
|
15
16
|
const terminalManager = getGlobalTerminalManager();
|
|
16
|
-
const session = await terminalManager.createSession(taskId, shellPreference, startupCommand);
|
|
17
|
+
const session = await terminalManager.createSession(taskId, shellPreference, startupCommand, getAuthPrincipalKey(c));
|
|
17
18
|
return c.json({
|
|
18
19
|
sessionId: session.id,
|
|
19
20
|
taskId: session.taskId,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getGlobalTerminalManager } from '../../../../../../lib/terminal/global-manager.js';
|
|
2
|
+
import { getAuthPrincipalKey } from '../../../../../../middleware/auth.js';
|
|
2
3
|
export async function POST(c) {
|
|
3
4
|
try {
|
|
4
5
|
const taskId = c.req.param('taskId');
|
|
@@ -8,7 +9,7 @@ export async function POST(c) {
|
|
|
8
9
|
return c.json({ error: 'Session ID is required' }, 400);
|
|
9
10
|
}
|
|
10
11
|
const terminalManager = getGlobalTerminalManager();
|
|
11
|
-
const success = terminalManager.destroySession(sessionId);
|
|
12
|
+
const success = terminalManager.destroySession(sessionId, getAuthPrincipalKey(c));
|
|
12
13
|
if (!success) {
|
|
13
14
|
return c.json({ error: 'Session not found' }, 404);
|
|
14
15
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getGlobalTerminalManager } from '../../../../../../lib/terminal/global-manager.js';
|
|
2
|
+
import { getAuthPrincipalKey } from '../../../../../../middleware/auth.js';
|
|
2
3
|
export async function POST(c) {
|
|
3
4
|
try {
|
|
4
5
|
const taskId = c.req.param('taskId');
|
|
@@ -8,7 +9,7 @@ export async function POST(c) {
|
|
|
8
9
|
return c.json({ error: 'Session ID, cols, and rows are required' }, 400);
|
|
9
10
|
}
|
|
10
11
|
const terminalManager = getGlobalTerminalManager();
|
|
11
|
-
const success = terminalManager.resizeSession(sessionId, cols, rows);
|
|
12
|
+
const success = terminalManager.resizeSession(sessionId, cols, rows, getAuthPrincipalKey(c));
|
|
12
13
|
if (!success) {
|
|
13
14
|
return c.json({ error: 'Session not found or resize failed' }, 404);
|
|
14
15
|
}
|
|
@@ -5,6 +5,7 @@ import matter from 'gray-matter';
|
|
|
5
5
|
import { getGlobalTerminalManager } from '../../../../../lib/terminal/global-manager.js';
|
|
6
6
|
import { loadUserSettings } from '../../../../../lib/user-preferences.js';
|
|
7
7
|
import { FileStorageAdapter } from '../../../../../lib/storage/file-storage.js';
|
|
8
|
+
import { getAuthPrincipalKey } from '../../../../../middleware/auth.js';
|
|
8
9
|
import { buildPipelineScript, buildPipelineBanner } from '@lovelybunch/core';
|
|
9
10
|
const storage = new FileStorageAdapter();
|
|
10
11
|
const VALID_AGENTS = ['claude', 'gemini', 'codex', 'droid', 'kiro'];
|
|
@@ -143,7 +144,7 @@ export async function POST(c) {
|
|
|
143
144
|
? `cd '${worktreePath.replace(/'/g, "'\\''")}' && ${command}`
|
|
144
145
|
: command;
|
|
145
146
|
const terminalManager = getGlobalTerminalManager();
|
|
146
|
-
const session = await terminalManager.createSession(taskId, shellPreference, startupCommand);
|
|
147
|
+
const session = await terminalManager.createSession(taskId, shellPreference, startupCommand, getAuthPrincipalKey(c));
|
|
147
148
|
return c.json({
|
|
148
149
|
sessionId: session.id,
|
|
149
150
|
taskId: session.taskId,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getGlobalTerminalManager } from '../../../../../lib/terminal/global-manager.js';
|
|
2
|
+
import { getAuthPrincipalKey } from '../../../../../middleware/auth.js';
|
|
2
3
|
// Lightweight ANSI escape sequence stripper to keep preview readable
|
|
3
4
|
// This avoids adding a dependency just for previews
|
|
4
5
|
const ANSI_REGEX = /[\u001B\u009B][[\]()#;?]*(?:\d{1,4}(?:;\d{0,4})*)?[0-9A-ORZcf-nqry=><]/g;
|
|
@@ -40,16 +41,17 @@ export async function GET(c) {
|
|
|
40
41
|
const previewBytes = Number.isFinite(maxBytesParam) && maxBytesParam > 0 ? Math.min(maxBytesParam, 8192) : 4096; // cap at 8KB
|
|
41
42
|
const colorize = ['1', 'true', 'yes'].includes((searchParams.get('colorize') || '').toLowerCase());
|
|
42
43
|
const terminalManager = getGlobalTerminalManager();
|
|
44
|
+
const ownerId = getAuthPrincipalKey(c);
|
|
43
45
|
let sessions;
|
|
44
46
|
if (sessionId) {
|
|
45
47
|
const s = terminalManager.getSession(sessionId);
|
|
46
|
-
sessions = s ? [s] : [];
|
|
48
|
+
sessions = terminalManager.canAccessSession(s, ownerId) && s ? [s] : [];
|
|
47
49
|
}
|
|
48
50
|
else if (taskId) {
|
|
49
|
-
sessions = terminalManager.getSessionsByTask(taskId);
|
|
51
|
+
sessions = terminalManager.getSessionsByTask(taskId).filter(session => terminalManager.canAccessSession(session, ownerId));
|
|
50
52
|
}
|
|
51
53
|
else {
|
|
52
|
-
sessions = terminalManager.
|
|
54
|
+
sessions = terminalManager.getSessionsForOwner(ownerId);
|
|
53
55
|
}
|
|
54
56
|
// Return session info without the PTY instance
|
|
55
57
|
const sessionInfo = sessions.map(session => ({
|
|
@@ -105,7 +105,7 @@ app.use('/api/*', cors({
|
|
|
105
105
|
// Handle trailing slashes consistently for API routes
|
|
106
106
|
app.use('/api/*', trimTrailingSlash());
|
|
107
107
|
// Import and apply authentication middleware
|
|
108
|
-
import { authMiddleware } from './middleware/auth.js';
|
|
108
|
+
import { authMiddleware, getAuthPrincipalKey } from './middleware/auth.js';
|
|
109
109
|
app.use('/api/*', authMiddleware);
|
|
110
110
|
app.use('/ws/*', authMiddleware);
|
|
111
111
|
// Create WebSocket support
|
|
@@ -123,7 +123,7 @@ app.get('/ws/terminal/:sessionId', upgradeWebSocket((c) => ({
|
|
|
123
123
|
ws.close(1000, 'WebSocket error');
|
|
124
124
|
return;
|
|
125
125
|
}
|
|
126
|
-
const success = terminalManager.attachWebSocket(sessionId, rawWs);
|
|
126
|
+
const success = terminalManager.attachWebSocket(sessionId, rawWs, getAuthPrincipalKey(c));
|
|
127
127
|
if (!success) {
|
|
128
128
|
console.error(`Failed to attach WebSocket to session: ${sessionId}`);
|
|
129
129
|
ws.close(1000, 'Session not found');
|
|
@@ -152,7 +152,7 @@ app.get('/ws/terminal-preview/:sessionId', upgradeWebSocket((c) => ({
|
|
|
152
152
|
catch { }
|
|
153
153
|
return;
|
|
154
154
|
}
|
|
155
|
-
const success = terminalManager.attachPreviewWebSocket(sessionId, rawWs);
|
|
155
|
+
const success = terminalManager.attachPreviewWebSocket(sessionId, rawWs, getAuthPrincipalKey(c));
|
|
156
156
|
if (!success) {
|
|
157
157
|
try {
|
|
158
158
|
ws.close(1000, 'Session not found');
|
package/dist/server.js
CHANGED
|
@@ -99,7 +99,7 @@ app.use('*', cors({
|
|
|
99
99
|
// Handle trailing slashes consistently for API routes
|
|
100
100
|
app.use('/api/*', trimTrailingSlash());
|
|
101
101
|
// Import and apply authentication middleware
|
|
102
|
-
import { authMiddleware } from './middleware/auth.js';
|
|
102
|
+
import { authMiddleware, getAuthPrincipalKey } from './middleware/auth.js';
|
|
103
103
|
app.use('/api/*', authMiddleware);
|
|
104
104
|
app.use('/ws/*', authMiddleware);
|
|
105
105
|
// Create WebSocket support
|
|
@@ -117,7 +117,7 @@ app.get('/ws/terminal/:sessionId', upgradeWebSocket((c) => ({
|
|
|
117
117
|
ws.close(1000, 'WebSocket error');
|
|
118
118
|
return;
|
|
119
119
|
}
|
|
120
|
-
const success = terminalManager.attachWebSocket(sessionId, rawWs);
|
|
120
|
+
const success = terminalManager.attachWebSocket(sessionId, rawWs, getAuthPrincipalKey(c));
|
|
121
121
|
if (!success) {
|
|
122
122
|
console.error(`Failed to attach WebSocket to session: ${sessionId}`);
|
|
123
123
|
ws.close(1000, 'Session not found');
|
|
@@ -146,7 +146,7 @@ app.get('/ws/terminal-preview/:sessionId', upgradeWebSocket((c) => ({
|
|
|
146
146
|
catch { }
|
|
147
147
|
return;
|
|
148
148
|
}
|
|
149
|
-
const success = terminalManager.attachPreviewWebSocket(sessionId, rawWs);
|
|
149
|
+
const success = terminalManager.attachPreviewWebSocket(sessionId, rawWs, getAuthPrincipalKey(c));
|
|
150
150
|
if (!success) {
|
|
151
151
|
try {
|
|
152
152
|
ws.close(1000, 'Session not found');
|
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.4",
|
|
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/
|
|
44
|
-
"@lovelybunch/
|
|
45
|
-
"@lovelybunch/mcp": "1.0.78-alpha.
|
|
43
|
+
"@lovelybunch/types": "1.0.78-alpha.4",
|
|
44
|
+
"@lovelybunch/core": "1.0.78-alpha.4",
|
|
45
|
+
"@lovelybunch/mcp": "1.0.78-alpha.4"
|
|
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-SUQrIHd7.js";import{C as c,a as d,b as k,c as C}from"./card-CiLixwCG.js";import{B as m}from"./badge-TeAh_Zh0.js";import{R as E}from"./refresh-cw-DvQ0rmk7.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};
|
package/static/assets/{AgentsContextEditPage-CgHVDbMV.js → AgentsContextEditPage-CsRJvzE6.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{u as p,a as j,r as n,A as l,j as e,B as h,L as v,a5 as N}from"./index-
|
|
1
|
+
import{u as p,a as j,r as n,A as l,j as e,B as h,L as v,a5 as N}from"./index-SUQrIHd7.js";import{C as m,a as x,b as C,c as S}from"./card-CiLixwCG.js";import{M as w}from"./markdown-editor-Cvh5pZzJ.js";import{A as y}from"./arrow-left-_lXkdm9Q.js";import{C as A}from"./circle-check-big-CxxxVvOw.js";import"./index-BlOxV6pf.js";function F(){const f=p(),{toast:t}=j(),[a,i]=n.useState(""),[g,r]=n.useState(!0),[o,c]=n.useState(!1);n.useEffect(()=>{fetch(`${l}/api/v1/context/agents`).then(s=>s.json()).then(s=>{s.success&&i(s.document.content.trim()),r(!1)}).catch(s=>{console.error("Failed to load context:",s),t({title:"Error",description:"Failed to load agents definition",variant:"destructive"}),r(!1)})},[t]);const u=async()=>{c(!0);try{const d=await(await fetch(`${l}/api/v1/context/agents`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:a,metadata:{}})})).json();if(d.success)t({title:"Success",description:"Agents definition saved successfully",action:e.jsx(A,{className:"h-4 w-4"})}),f("/context/agents");else throw new Error(d.error||"Failed to save")}catch(s){console.error("Save error:",s),t({title:"Error",description:"Failed to save agents definition",variant:"destructive"})}finally{c(!1)}};return g?e.jsx("div",{className:"space-y-6",children:e.jsx(m,{children:e.jsx(x,{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 Agents Definition"}),e.jsx("p",{className:"text-muted-foreground text-sm hidden sm:block",children:"Define agents, their capabilities, and configurations"})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-shrink-0",children:[e.jsx(h,{variant:"ghost",size:"sm",asChild:!0,children:e.jsx(v,{to:"/context/agents",className:"text-muted-foreground hover:text-foreground transition-colors",children:e.jsx(y,{className:"w-4 h-4"})})}),e.jsxs(h,{onClick:u,disabled:o,size:"sm",children:[e.jsx(N,{className:"w-4 h-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:o?"Saving...":"Save"})]})]})]}),e.jsxs(m,{children:[e.jsx(C,{children:e.jsx(S,{children:"Agents Documentation"})}),e.jsx(x,{children:e.jsx(w,{value:a,onChange:s=>i(s||""),placeholder:`Write your agents definition in markdown...
|
|
2
2
|
|
|
3
3
|
## Agent Definitions
|
|
4
4
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as g,r as t,A as N,j as e,v,az as C,B as a,L as d,a2 as l,M as w,ay as y,au as E}from"./index-
|
|
1
|
+
import{a as g,r as t,A as N,j as e,v,az as C,B as a,L as d,a2 as l,M as w,ay as y,au as E}from"./index-SUQrIHd7.js";import{C as i,a as c,b}from"./card-CiLixwCG.js";import{c as A}from"./clipboard-B9ndUJKl.js";function D(){const{toast:r}=g(),[o,m]=t.useState(null),[x,h]=t.useState(!0),[u,n]=t.useState(!1);t.useEffect(()=>{fetch(`${N}/api/v1/context/agents`).then(s=>{if(s.ok)return s.json();throw new Error("Not found")}).then(s=>{s.success?(m(s.document),n(!0)):n(!1)}).catch(()=>{n(!1)}).finally(()=>{h(!1)})},[]);const p=async()=>{const s=".nut/context/agents.md";try{await A(s),r({title:"Copied!",description:`Path ${s} copied to clipboard`})}catch(f){console.error("Failed to copy path:",f),r({title:"Error",description:"Failed to copy path to clipboard",variant:"destructive"})}},j=()=>{const s=new CustomEvent("discuss-in-chat",{detail:{type:"context",id:"agents-md",filename:"agents.md",name:"agents.md",path:".nut/context/agents.md"}});window.dispatchEvent(s)};return x?e.jsx("div",{className:"space-y-6",children:e.jsx(i,{children:e.jsx(c,{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 agents definition..."})]})})})}):!u||!o?e.jsx("div",{className:"space-y-6",children:e.jsx(i,{children:e.jsx(c,{className:"pt-6",children:e.jsxs("div",{className:"text-center",children:[e.jsx(C,{className:"mx-auto h-12 w-12 text-muted-foreground"}),e.jsx("h3",{className:"mt-4 text-lg font-semibold",children:"No Agents Definition Found"}),e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:"Agents definition will appear here once created."}),e.jsx(a,{className:"mt-4",asChild:!0,children:e.jsxs(d,{to:"/context/agents/edit",children:[e.jsx(l,{className:"h-4 w-4 mr-2"}),"Create Agents Definition"]})})]})})})}):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:"Agents"}),e.jsx("p",{className:"text-muted-foreground",children:"Agent definitions and configurations"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(a,{variant:"outline",size:"sm",onClick:j,children:[e.jsx(w,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Discuss"})]}),e.jsxs(a,{variant:"outline",size:"sm",onClick:p,children:[e.jsx(y,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Copy Path"})]}),e.jsx(a,{size:"sm",asChild:!0,children:e.jsxs(d,{to:"/context/agents/edit",children:[e.jsx(l,{className:"h-4 w-4 sm:mr-2"}),e.jsx("span",{className:"hidden sm:inline",children:"Edit"})]})})]})]}),e.jsxs(i,{children:[e.jsx(b,{className:"pb-0"}),e.jsx(c,{children:e.jsx("div",{className:"prose prose-sm max-w-none dark:prose-invert",children:e.jsx(E,{children:o.content||"No content available"})})})]})]})}export{D as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as R,r as t,E as y,j as e,B as a,P as X,bH as Y,Q as J,D as j,b as g,d as v,f,g as A,I as F,a1 as N,ai as Q,w as i}from"./index-
|
|
1
|
+
import{t as R,r as t,E as y,j as e,B as a,P as X,bH as Y,Q as J,D as j,b as g,d as v,f,g as A,I as F,a1 as N,ai as Q,w as i}from"./index-SUQrIHd7.js";import{C as W,b as G,c as V,d as Z,a as _}from"./card-CiLixwCG.js";import{L as w}from"./label-n5pqaObd.js";import{B as ee}from"./badge-TeAh_Zh0.js";import{A as I,a as C}from"./alert-DBhIskRX.js";import{I as L}from"./info-CVmPHERQ.js";import{C as se}from"./circle-alert-nI75emvr.js";function oe(){const{authEnabled:n}=R(),[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/tasks`:"",T=n?null:e.jsxs(I,{children:[e.jsx(L,{className:"h-4 w-4"}),e.jsxs(C,{children:["Authentication is currently disabled. API keys will only be required once you enable authentication in the ",e.jsx("a",{href:"/settings/authentication",className:"underline",children:"Authentication settings"}),"."]})]});return!n&&b?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"API Keys"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage API keys for programmatic access"})]}),T]}):b?e.jsx("div",{className:"space-y-6",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"API Keys"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading..."})]})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"API Keys"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage API keys for programmatic access to your Coconut instance"})]}),T,n&&e.jsxs(I,{children:[e.jsx(L,{className:"h-4 w-4"}),e.jsxs(C,{children:["API keys provide programmatic access to your Coconut instance. Use them in CI/CD pipelines or automation scripts by including the key in the ",e.jsx("code",{className:"bg-muted px-1 py-0.5 rounded",children:"X-API-Key"})," header."]})]}),e.jsxs(W,{children:[e.jsx(G,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(V,{children:"Active API Keys"}),e.jsx(Z,{children:"API keys you've created for programmatic access"})]}),e.jsxs(a,{onClick:()=>l(!0),disabled:!n,children:[e.jsx(X,{className:"mr-2 h-4 w-4"}),"Create API Key"]})]})}),e.jsx(_,{children:P.length===0?e.jsxs("div",{className:"text-center py-8 text-muted-foreground",children:[e.jsx(Y,{className:"h-12 w-12 mx-auto mb-4 opacity-20"}),e.jsx("p",{children:"No API keys yet"}),e.jsx("p",{className:"text-sm",children:"Create an API key to get started with programmatic access"})]}):e.jsx("div",{className:"space-y-4",children: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(ee,{variant:"destructive",children:"Expired"})]}),e.jsx("p",{className:"text-sm text-muted-foreground font-mono",children:s.keyPreview}),e.jsxs("div",{className:"flex items-center gap-4 mt-2 text-xs text-muted-foreground",children:[e.jsxs("span",{children:["Created: ",u(s.createdAt)]}),s.expiresAt&&e.jsxs("span",{children:["Expires: ",u(s.expiresAt)]}),s.lastUsedAt&&e.jsxs("span",{children:["Last used: ",u(s.lastUsedAt)]})]})]}),e.jsx(a,{variant:"ghost",size:"icon",onClick:()=>o(s.id),children:e.jsx(J,{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(Q,{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{oe as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as te,t as me,r as n,E as l,j as e,bB as _,i as H,D as q,a0 as z,B as d,b as B,d as Y,f as K,g as Q,I as x,a1 as G,J as ge,N as je,Q as pe,R as ve,U as fe,V as we,W as ye,Y as Ce,_ as Ne,$ as Se,w as r}from"./index-
|
|
1
|
+
import{c as te,t as me,r as n,E as l,j as e,bB as _,i as H,D as q,a0 as z,B as d,b as B,d as Y,f as K,g as Q,I as x,a1 as G,J as ge,N as je,Q as pe,R as ve,U as fe,V as we,W as ye,Y as Ce,_ as Ne,$ as Se,w as r}from"./index-SUQrIHd7.js";import{C as m,b as g,c as j,d as p,a as v}from"./card-CiLixwCG.js";import{L as c}from"./label-n5pqaObd.js";import{S as X,a as Z,b as ee,c as se,d as a}from"./select-CIOYQA7a.js";import{S as N}from"./switch-DczkR77Y.js";import{B as F}from"./badge-TeAh_Zh0.js";import{C as be}from"./circle-alert-nI75emvr.js";import"./index-BlOxV6pf.js";import"./chevron-up-B4J4D5aE.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,v as x,A as f}from"./index-
|
|
1
|
+
import{r as m,j as e,v as x,A as f}from"./index-SUQrIHd7.js";import{C as w}from"./circle-check-k6ER9afD.js";import{C as b}from"./circle-x-BzPgPb47.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 y=()=>{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{y as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as E,x as S,t as j,r as i,j as e,v,y as p,z as y,E as C,O as k,w as N}from"./index-
|
|
1
|
+
import{u as E,x as S,t as j,r as i,j as e,v,y as p,z as y,E as C,O as k,w as N}from"./index-SUQrIHd7.js";function I(){const c=E(),[a]=S(),{oauth:t,refreshUser:u,isLoading:l}=j(),[w,r]=i.useState("working"),[b,s]=i.useState(null),d=i.useRef(!1);return i.useEffect(()=>{if(d.current||l)return;d.current=!0,(async()=>{const g=a.get("code"),h=a.get("error");if(h){r("error"),s(a.get("error_description")||h);return}if(!g){r("error"),s("Missing authorization code in callback URL");return}if(!t.enabled||!t.clientId||!t.issuer){r("error"),s("OAuth is not enabled on this coconut");return}let o=null;try{o=sessionStorage.getItem(p)}catch{o=null}if(!o){r("error"),s("Missing PKCE verifier - please start sign-in again");return}try{const n=await y({issuer:t.issuer,clientId:t.clientId,code:g,verifier:o});if(!n.id_token)throw new Error('Clerk did not return an id_token (is the "openid" scope registered for this client?)');const m=await C("/api/v1/auth/oauth/exchange",{method:"POST",body:JSON.stringify({idToken:n.id_token})});if(!m.success)throw new Error(m.error||"Server rejected OAuth token");try{sessionStorage.removeItem(p)}catch{}await u();let f="/";try{const x=sessionStorage.getItem(k);x&&(sessionStorage.removeItem(k),f=x)}catch{}N({title:"Welcome back",description:"Signed in with Coconut"}),c(f,{replace:!0})}catch(n){console.error("OAuth callback failed:",n),r("error"),s(n?.message||"OAuth callback failed")}})()},[l,c,t,u,a]),e.jsx("div",{className:"min-h-screen flex items-center justify-center bg-gradient-to-br from-background to-muted p-4",children:e.jsx("div",{className:"max-w-sm text-center space-y-4",children:w==="working"?e.jsxs(e.Fragment,{children:[e.jsx(v,{className:"h-8 w-8 animate-spin text-muted-foreground mx-auto"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Finishing sign-in with Coconut..."})]}):e.jsxs(e.Fragment,{children:[e.jsx("h1",{className:"text-lg font-semibold",children:"Sign-in failed"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:b||"Something went wrong completing OAuth sign-in."}),e.jsx("button",{type:"button",className:"text-sm underline",onClick:()=>c("/login",{replace:!0}),children:"Back to login"})]})})})}export{I as default};
|