@lovelybunch/api 1.0.78-alpha.3 → 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.
Files changed (141) hide show
  1. package/dist/lib/auth/auth-manager.d.ts +1 -1
  2. package/dist/lib/auth/auth-manager.js +2 -1
  3. package/dist/lib/symlinks/symlink-manager.d.ts +3 -4
  4. package/dist/lib/symlinks/symlink-manager.js +49 -30
  5. package/dist/lib/terminal/terminal-manager.d.ts +8 -5
  6. package/dist/lib/terminal/terminal-manager.js +29 -5
  7. package/dist/middleware/auth.d.ts +23 -2
  8. package/dist/middleware/auth.js +44 -4
  9. package/dist/routes/api/v1/ai/route.js +117 -4
  10. package/dist/routes/api/v1/api-keys/route.js +7 -1
  11. package/dist/routes/api/v1/jobs/[id]/route.d.ts +28 -28
  12. package/dist/routes/api/v1/jobs/route.d.ts +28 -28
  13. package/dist/routes/api/v1/knowledge/[filename]/route.js +29 -7
  14. package/dist/routes/api/v1/slack/route.d.ts +6 -6
  15. package/dist/routes/api/v1/terminal/[taskId]/create/route.js +2 -1
  16. package/dist/routes/api/v1/terminal/[taskId]/destroy/route.js +2 -1
  17. package/dist/routes/api/v1/terminal/[taskId]/resize/route.js +2 -1
  18. package/dist/routes/api/v1/terminal/code/route.js +2 -1
  19. package/dist/routes/api/v1/terminal/sessions/route.js +5 -3
  20. package/dist/server-with-static.js +3 -3
  21. package/dist/server.js +3 -3
  22. package/package.json +4 -4
  23. package/static/assets/{ActivityPage-CO2m97Hz.js → ActivityPage-CtFAFqlg.js} +1 -1
  24. package/static/assets/{AgentsContextEditPage-B9pcC3Y4.js → AgentsContextEditPage-CsRJvzE6.js} +1 -1
  25. package/static/assets/{AgentsContextPage-CWsGDD4F.js → AgentsContextPage-CWCs8CgG.js} +1 -1
  26. package/static/assets/{ApiKeysSettingsPage-CPckUylF.js → ApiKeysSettingsPage-B4b_fmJg.js} +1 -1
  27. package/static/assets/{AuthSettingsPage-CaiYl7fx.js → AuthSettingsPage-O3UdLrHC.js} +1 -1
  28. package/static/assets/{CallbackPage-C73ggs1e.js → CallbackPage-WTwVSxdx.js} +1 -1
  29. package/static/assets/{CoconutCallbackPage-Bhc_sIuJ.js → CoconutCallbackPage-LEWgUV8J.js} +1 -1
  30. package/static/assets/{CodePage-7zrLYTBq.js → CodePage-DpVmg_UD.js} +1 -1
  31. package/static/assets/{CollapsibleSection-DD6cnVaM.js → CollapsibleSection-BHag26Vf.js} +1 -1
  32. package/static/assets/{DashboardPage-BiVDSLAm.js → DashboardPage-BZnCikpf.js} +1 -1
  33. package/static/assets/{GitPage-C7n82d8O.js → GitPage-DD6dgeNu.js} +1 -1
  34. package/static/assets/{GitSettingsPage-D2R-zg9d.js → GitSettingsPage-CLHCZ6at.js} +1 -1
  35. package/static/assets/{IdentityPage-B3gUyFXr.js → IdentityPage-DtzLSTYd.js} +1 -1
  36. package/static/assets/{ImplementationStepsEditor-DmrYGdZB.js → ImplementationStepsEditor-Ca1aygKs.js} +1 -1
  37. package/static/assets/{IntegrationsSettingsPage-V6t85OD_.js → IntegrationsSettingsPage-C2tzpbuI.js} +1 -1
  38. package/static/assets/{JobDetailPage-BUmQGshi.js → JobDetailPage-B03z4VgG.js} +1 -1
  39. package/static/assets/{KnowledgeDetailPage-DzpoOs9C.js → KnowledgeDetailPage-XslT5GUv.js} +1 -1
  40. package/static/assets/{KnowledgeEditPage-C9zyCfr6.js → KnowledgeEditPage-5NFEnGJh.js} +1 -1
  41. package/static/assets/{KnowledgePage-C56_NMA9.js → KnowledgePage-Dzh409qU.js} +1 -1
  42. package/static/assets/{LoginPage-DZpAjZmK.js → LoginPage-IDVkR1zN.js} +1 -1
  43. package/static/assets/{MailInboxPage-BvOBQvF3.js → MailInboxPage-CXaBqNl2.js} +1 -1
  44. package/static/assets/{MailProcessingModal-CCGrVGDs.js → MailProcessingModal-BWyzTMEv.js} +1 -1
  45. package/static/assets/{MailReadPage-CycqG4oj.js → MailReadPage-DPGuT0gC.js} +1 -1
  46. package/static/assets/{MailSentPage-DpwRNrju.js → MailSentPage-Dtq37Kap.js} +1 -1
  47. package/static/assets/{McpSettingsPage-pJ41THOO.js → McpSettingsPage-BiCSPaAJ.js} +1 -1
  48. package/static/assets/{MemoryEditPage-DobGCRrl.js → MemoryEditPage-Dfa6MsnE.js} +1 -1
  49. package/static/assets/{MemoryPage-BrFnh8rC.js → MemoryPage-BqUngqIS.js} +1 -1
  50. package/static/assets/{NewKnowledgePage-CTFx_YTk.js → NewKnowledgePage-BmYwcO98.js} +1 -1
  51. package/static/assets/{NewSkillPage-D_FfkSKi.js → NewSkillPage-BfNaXH37.js} +1 -1
  52. package/static/assets/{NewTaskPage-CehAYsyJ.js → NewTaskPage-Ctmh2uiJ.js} +1 -1
  53. package/static/assets/{NotFoundPage-wcJQI6_Y.js → NotFoundPage-a2erdq4H.js} +1 -1
  54. package/static/assets/{NotificationsSettingsPage-_9Dum2JJ.js → NotificationsSettingsPage-BB9QuyUf.js} +1 -1
  55. package/static/assets/{PromptsSettingsPage-BBIP8PWS.js → PromptsSettingsPage-BZLwTFcd.js} +1 -1
  56. package/static/assets/{ResourceDetailPage-C7goHk6o.js → ResourceDetailPage-DRWNjykw.js} +1 -1
  57. package/static/assets/{ResourcesPage-ZH5lSPaG.js → ResourcesPage-C3Lx8hz_.js} +1 -1
  58. package/static/assets/{RoleEditPage-JJnQ7UXW.js → RoleEditPage-W9SV6Mwr.js} +1 -1
  59. package/static/assets/{RolePage-C-gQnpzL.js → RolePage-DWWo77tA.js} +1 -1
  60. package/static/assets/{RulesSettingsPage-Bc05Q6j8.js → RulesSettingsPage-BKsadZ7r.js} +1 -1
  61. package/static/assets/{RunDetailPage-BhWthPVR.js → RunDetailPage-C6miynGX.js} +1 -1
  62. package/static/assets/{SchedulePage-zvr5ce8N.js → SchedulePage-B6s-CkVg.js} +1 -1
  63. package/static/assets/{SkillDetailPage-5DhKM3NY.js → SkillDetailPage-DYkLxRjB.js} +1 -1
  64. package/static/assets/{SkillEditPage-1V1ADtPe.js → SkillEditPage-DIB2lUMz.js} +1 -1
  65. package/static/assets/{SkillsPage-6VQCj1hf.js → SkillsPage-BgR2gdCy.js} +1 -1
  66. package/static/assets/{SkillsSettingsPage-C7lqSbBf.js → SkillsSettingsPage-CoDOG0YQ.js} +1 -1
  67. package/static/assets/{SourceInput-CeltF2kQ.js → SourceInput-CS6u1yPi.js} +1 -1
  68. package/static/assets/{TagInput-DUR8EcF5.js → TagInput-C3WzbX6I.js} +1 -1
  69. package/static/assets/{TaskDetailPage-HqNWYvGE.js → TaskDetailPage-DEBBE0D8.js} +1 -1
  70. package/static/assets/{TaskEditPage-Cy6_oKRU.js → TaskEditPage-B26tEsUP.js} +1 -1
  71. package/static/assets/{TasksPage-DHdwWucP.js → TasksPage-pqQ7VlC3.js} +1 -1
  72. package/static/assets/{TeamEditPage-DZHs9LwL.js → TeamEditPage-C6DugOii.js} +1 -1
  73. package/static/assets/{TeamPage-C10th6Xi.js → TeamPage-BDqQZ6Rr.js} +1 -1
  74. package/static/assets/{TerminalPage-BajLCwBP.js → TerminalPage-pjss7X1h.js} +1 -1
  75. package/static/assets/{TerminalSessionPage-dJGlApIY.js → TerminalSessionPage-C9sJ_13t.js} +1 -1
  76. package/static/assets/{UserPreferencesPage-crzoMvn3.js → UserPreferencesPage-BrpKf14p.js} +1 -1
  77. package/static/assets/{UserSettingsPage-B4eeW2b9.js → UserSettingsPage-BbazpvdQ.js} +1 -1
  78. package/static/assets/{UtilitiesPage-ZnNRIlEg.js → UtilitiesPage-niclH8kb.js} +1 -1
  79. package/static/assets/{alert-a0XoDY__.js → alert-DBhIskRX.js} +1 -1
  80. package/static/assets/{arrow-down-DwCDIVHH.js → arrow-down-TpeNydxP.js} +1 -1
  81. package/static/assets/{arrow-left-D4GyWema.js → arrow-left-_lXkdm9Q.js} +1 -1
  82. package/static/assets/{arrow-up-ClZJeJXS.js → arrow-up-DaIMsmSO.js} +1 -1
  83. package/static/assets/{arrow-up-down-ozcTje6W.js → arrow-up-down-C7wqirJv.js} +1 -1
  84. package/static/assets/{badge-CgbZdX-R.js → badge-TeAh_Zh0.js} +1 -1
  85. package/static/assets/{browser-modal-CV9x_ILy.js → browser-modal-BpGFpZZj.js} +1 -1
  86. package/static/assets/{card-bSzcwVEz.js → card-CiLixwCG.js} +1 -1
  87. package/static/assets/{chevron-left-Dnm2Bv2g.js → chevron-left-CuMfw52D.js} +1 -1
  88. package/static/assets/{chevron-up-znuSUWjo.js → chevron-up-B4J4D5aE.js} +1 -1
  89. package/static/assets/{chevrons-up-DyHcV7KP.js → chevrons-up-Dcs-Dj4B.js} +1 -1
  90. package/static/assets/{circle-alert-Dn8B5NPI.js → circle-alert-nI75emvr.js} +1 -1
  91. package/static/assets/{circle-check-big-HUp82Tz-.js → circle-check-big-CxxxVvOw.js} +1 -1
  92. package/static/assets/{circle-check-2Hh5KJn8.js → circle-check-k6ER9afD.js} +1 -1
  93. package/static/assets/{circle-play-BG4sTHV2.js → circle-play-B4D0d7YW.js} +1 -1
  94. package/static/assets/{circle-x-DBrbnMPA.js → circle-x-BzPgPb47.js} +1 -1
  95. package/static/assets/{clipboard-B6OwO-az.js → clipboard-CLObCrC4.js} +1 -1
  96. package/static/assets/{clock-B36ytcOX.js → clock-BK-8XMqv.js} +1 -1
  97. package/static/assets/{code-CK8i3Xlg.js → code-lhIVzb1q.js} +1 -1
  98. package/static/assets/{download-C_C3f7cE.js → download-ChgFRTfC.js} +1 -1
  99. package/static/assets/{external-link-kQIXuJh_.js → external-link-D4kianlP.js} +1 -1
  100. package/static/assets/{eye-DTyfbeQg.js → eye-H1JnZ9E9.js} +1 -1
  101. package/static/assets/{folder-git-2-CKR2HcNZ.js → folder-git-2-BZGvXcyj.js} +1 -1
  102. package/static/assets/{globe--bHEtjre.js → globe-DAzCOUla.js} +1 -1
  103. package/static/assets/{index-CJBq79WW.js → index-B7UEVagI.js} +1 -1
  104. package/static/assets/{index-CRSpx2tQ.js → index-Bik-wLXi.js} +1 -1
  105. package/static/assets/{index-ObZJu-Zv.js → index-BlOxV6pf.js} +1 -1
  106. package/static/assets/{index-QgKSm0gN.js → index-C7dpn8dK.js} +1 -1
  107. package/static/assets/{index-ffbhzKxY.js → index-C9wsYS8C.js} +1 -1
  108. package/static/assets/{index-9Y0fmmy7.js → index-Ck9sMDuo.js} +1 -1
  109. package/static/assets/{index-CvrVx0kf.js → index-DMeIDO6W.js} +1 -1
  110. package/static/assets/{index-Bg80D0Z0.js → index-DOpjlxVe.js} +1 -1
  111. package/static/assets/{index-nRow2q03.js → index-DT4K0HgO.js} +1 -1
  112. package/static/assets/{index-DMKQFm-M.js → index-DeF-CCVg.js} +1 -1
  113. package/static/assets/{index-CTZ51lNe.js → index-DkvhkCo1.js} +1 -1
  114. package/static/assets/{index-DXkvtMiO.js → index-DuDW1LwX.js} +1 -1
  115. package/static/assets/{index-DOgqHj1l.js → index-Dy_-mpPq.js} +1 -1
  116. package/static/assets/{index-B81KYk3Z.js → index-SUQrIHd7.js} +6 -6
  117. package/static/assets/{index-UKy_jk8q.js → index-c-gr7Bew.js} +1 -1
  118. package/static/assets/{index-C_zW1Hi0.js → index-kJaEkklL.js} +1 -1
  119. package/static/assets/{index-XJ0Ck2RG.js → index-rslXoTnS.js} +1 -1
  120. package/static/assets/{index-CD6zflLk.js → index-rwsZ-IsL.js} +1 -1
  121. package/static/assets/{index-B52hVXHu.js → index-sBbL8_xu.js} +1 -1
  122. package/static/assets/{info-wSiZMXgL.js → info-CVmPHERQ.js} +1 -1
  123. package/static/assets/{label-CHP4q6u3.js → label-n5pqaObd.js} +1 -1
  124. package/static/assets/{markdown-editor-DSI9T1tt.js → markdown-editor-Cvh5pZzJ.js} +3 -3
  125. package/static/assets/{message-square-D1sMYX2G.js → message-square-BmnqRsu6.js} +1 -1
  126. package/static/assets/{paperclip-plxfUm0D.js → paperclip-BwcNeQ_C.js} +1 -1
  127. package/static/assets/{pause-B2JeikEI.js → pause-CUswidZW.js} +1 -1
  128. package/static/assets/{play-l7Mu5YPO.js → play-DyZbNGiK.js} +1 -1
  129. package/static/assets/{radio-group-DxYoqBDN.js → radio-group-Bzu_d7xN.js} +1 -1
  130. package/static/assets/{refresh-cw-BTHxZiES.js → refresh-cw-DvQ0rmk7.js} +1 -1
  131. package/static/assets/{search-Cpy49h7H.js → search-kc_tG8Rf.js} +1 -1
  132. package/static/assets/{select-CG6kgyUu.js → select-CIOYQA7a.js} +1 -1
  133. package/static/assets/{server-DzOL5RbP.js → server-CWIJxRf0.js} +1 -1
  134. package/static/assets/{switch-7YpWWyAq.js → switch-DczkR77Y.js} +1 -1
  135. package/static/assets/{tabs-DJk1ZrWh.js → tabs-DOEakD76.js} +1 -1
  136. package/static/assets/{tag-BvoXF-sG.js → tag-Dc8sXXlM.js} +1 -1
  137. package/static/assets/{terminal-preview-d_BZ8s8s.js → terminal-preview-D8oASUdZ.js} +1 -1
  138. package/static/assets/{triangle-alert-P6aKUDal.js → triangle-alert-C-5ixej6.js} +1 -1
  139. package/static/assets/{use-terminal-BXYq-vfY.js → use-terminal-xdcf4Z2G.js} +1 -1
  140. package/static/assets/{video-PACu7StA.js → video-CBneSE9B.js} +1 -1
  141. package/static/index.html +1 -1
@@ -9,8 +9,19 @@ 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
- tags?: string[];
12
+ id: string;
13
+ name: string;
13
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;
14
25
  schedule: {
15
26
  type: "cron";
16
27
  expression: string;
@@ -23,27 +34,16 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
23
34
  timezone?: string;
24
35
  anchorHour?: number;
25
36
  };
26
- id: string;
27
- name: string;
28
- metadata: {
29
- createdAt: string;
30
- updatedAt: string;
31
- lastRunAt?: string;
32
- nextRunAt?: string;
33
- };
34
- description?: string;
35
- model: string;
36
- prompt: string;
37
- mcpServers?: string[];
38
37
  contextPaths?: string[];
39
38
  agentId?: string;
40
39
  agentIds?: string[];
40
+ mcpServers?: string[];
41
41
  runs: {
42
42
  error?: string;
43
+ id: string;
43
44
  status: import("@lovelybunch/types").ScheduledJobRunStatus;
44
45
  jobId: string;
45
46
  trigger: import("@lovelybunch/types").ScheduledJobTrigger;
46
- id: string;
47
47
  startedAt: string;
48
48
  finishedAt?: string;
49
49
  }[];
@@ -70,8 +70,19 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
70
70
  }, 400, "json">) | (Response & import("hono").TypedResponse<{
71
71
  success: true;
72
72
  data: {
73
- tags?: string[];
73
+ id: string;
74
+ name: string;
74
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;
75
86
  schedule: {
76
87
  type: "cron";
77
88
  expression: string;
@@ -84,27 +95,16 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
84
95
  timezone?: string;
85
96
  anchorHour?: number;
86
97
  };
87
- id: string;
88
- name: string;
89
- metadata: {
90
- createdAt: string;
91
- updatedAt: string;
92
- lastRunAt?: string;
93
- nextRunAt?: string;
94
- };
95
- description?: string;
96
- model: string;
97
- prompt: string;
98
- mcpServers?: string[];
99
98
  contextPaths?: string[];
100
99
  agentId?: string;
101
100
  agentIds?: string[];
101
+ mcpServers?: string[];
102
102
  runs: {
103
103
  error?: string;
104
+ id: string;
104
105
  status: import("@lovelybunch/types").ScheduledJobRunStatus;
105
106
  jobId: string;
106
107
  trigger: import("@lovelybunch/types").ScheduledJobTrigger;
107
- id: string;
108
108
  startedAt: string;
109
109
  finishedAt?: string;
110
110
  }[];
@@ -11,8 +11,19 @@ export declare function withLightweightRuns<T extends {
11
11
  export declare function GET(c: Context): Promise<(Response & import("hono").TypedResponse<{
12
12
  success: true;
13
13
  data: {
14
- tags?: string[];
14
+ id: string;
15
+ name: string;
15
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;
16
27
  schedule: {
17
28
  type: "cron";
18
29
  expression: string;
@@ -25,27 +36,16 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
25
36
  timezone?: string;
26
37
  anchorHour?: number;
27
38
  };
28
- id: string;
29
- name: string;
30
- metadata: {
31
- createdAt: string;
32
- updatedAt: string;
33
- lastRunAt?: string;
34
- nextRunAt?: string;
35
- };
36
- description?: string;
37
- model: string;
38
- prompt: string;
39
- mcpServers?: string[];
40
39
  contextPaths?: string[];
41
40
  agentId?: string;
42
41
  agentIds?: string[];
42
+ mcpServers?: string[];
43
43
  runs: {
44
44
  error?: string;
45
+ id: string;
45
46
  status: import("@lovelybunch/types").ScheduledJobRunStatus;
46
47
  jobId: string;
47
48
  trigger: import("@lovelybunch/types").ScheduledJobTrigger;
48
- id: string;
49
49
  startedAt: string;
50
50
  finishedAt?: string;
51
51
  }[];
@@ -66,8 +66,19 @@ export declare function POST(c: Context): Promise<(Response & import("hono").Typ
66
66
  }, 400, "json">) | (Response & import("hono").TypedResponse<{
67
67
  success: true;
68
68
  data: {
69
- tags?: string[];
69
+ id: string;
70
+ name: string;
70
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;
71
82
  schedule: {
72
83
  type: "cron";
73
84
  expression: string;
@@ -80,27 +91,16 @@ export declare function POST(c: Context): Promise<(Response & import("hono").Typ
80
91
  timezone?: string;
81
92
  anchorHour?: number;
82
93
  };
83
- id: string;
84
- name: string;
85
- metadata: {
86
- createdAt: string;
87
- updatedAt: string;
88
- lastRunAt?: string;
89
- nextRunAt?: string;
90
- };
91
- description?: string;
92
- model: string;
93
- prompt: string;
94
- mcpServers?: string[];
95
94
  contextPaths?: string[];
96
95
  agentId?: string;
97
96
  agentIds?: string[];
97
+ mcpServers?: string[];
98
98
  runs: {
99
99
  error?: string;
100
+ id: string;
100
101
  status: import("@lovelybunch/types").ScheduledJobRunStatus;
101
102
  jobId: string;
102
103
  trigger: import("@lovelybunch/types").ScheduledJobTrigger;
103
- id: string;
104
104
  startedAt: string;
105
105
  finishedAt?: string;
106
106
  }[];
@@ -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 = filename.endsWith('.md') ? filename : `${filename}.md`;
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 = filename.endsWith('.md') ? filename : `${filename}.md`;
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 = path.join(knowledgePath, newFilename);
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 = filename.endsWith('.md') ? filename : `${filename}.md`;
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
  }
@@ -7,9 +7,6 @@ export declare function getConfig(c: Context): Promise<(Response & import("hono"
7
7
  success: true;
8
8
  data: {
9
9
  enabled: boolean;
10
- channelId: string;
11
- channelName: string;
12
- siteUrl: string;
13
10
  notifications: {
14
11
  proposals: {
15
12
  created: boolean;
@@ -24,6 +21,9 @@ export declare function getConfig(c: Context): Promise<(Response & import("hono"
24
21
  merge: boolean;
25
22
  };
26
23
  };
24
+ channelId: string;
25
+ channelName: string;
26
+ siteUrl: string;
27
27
  hasBotToken: boolean;
28
28
  hasSigningSecret: boolean;
29
29
  };
@@ -39,9 +39,6 @@ export declare function updateConfig(c: Context): Promise<(Response & import("ho
39
39
  success: true;
40
40
  data: {
41
41
  enabled: boolean;
42
- channelId: string;
43
- channelName: string;
44
- siteUrl: string;
45
42
  notifications: {
46
43
  proposals: {
47
44
  created: boolean;
@@ -56,6 +53,9 @@ export declare function updateConfig(c: Context): Promise<(Response & import("ho
56
53
  merge: boolean;
57
54
  };
58
55
  };
56
+ channelId: string;
57
+ channelName: string;
58
+ siteUrl: string;
59
59
  hasBotToken: boolean;
60
60
  hasSigningSecret: boolean;
61
61
  };
@@ -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.getAllSessions();
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",
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/core": "1.0.78-alpha.3",
44
- "@lovelybunch/types": "1.0.78-alpha.3",
45
- "@lovelybunch/mcp": "1.0.78-alpha.3"
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-B81KYk3Z.js";import{C as c,a as d,b as k,c as C}from"./card-bSzcwVEz.js";import{B as m}from"./badge-CgbZdX-R.js";import{R as E}from"./refresh-cw-BTHxZiES.js";const A=5e3;function $(){const[n,o]=a.useState([]),[i,x]=a.useState(!0),[h,u]=a.useState(new Set),l=a.useCallback(async()=>{x(!0);try{const s=await fetch(`${p}/api/v1/events?limit=${A}`);if(!s.ok)throw new Error("Failed to load events");const t=await s.json();o(Array.isArray(t.items)?[...t.items].reverse():[])}catch(s){console.error("Failed to load events:",s),o([])}finally{x(!1)}},[]),g=a.useCallback(s=>{u(t=>{const r=new Set(t);return r.has(s)?r.delete(s):r.add(s),r})},[]);a.useEffect(()=>{l()},[l]);const f=s=>{if(!s)return"Unknown time";try{return new Date(s).toLocaleString()}catch{return s}},j=s=>{switch(s?.toLowerCase()){case"error":return"bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200";case"warn":case"warning":return"bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200";case"info":return"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200";case"debug":return"bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-200";default:return"bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-200"}};return i?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold tracking-tight",children:"Activity"}),e.jsx("p",{className:"text-muted-foreground",children:"View system activity and events"})]}),e.jsx(c,{children:e.jsx(d,{className:"pt-6",children:e.jsxs("div",{className:"flex items-center justify-center",children:[e.jsx(v,{className:"h-8 w-8 animate-spin text-muted-foreground"}),e.jsx("span",{className:"ml-2 text-muted-foreground",children:"Loading events..."})]})})})]}):n.length===0?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold tracking-tight",children:"Activity"}),e.jsx("p",{className:"text-muted-foreground",children:"View system activity and events"})]}),e.jsx(c,{children:e.jsx(d,{className:"pt-6",children:e.jsxs("div",{className:"text-center",children:[e.jsx(y,{className:"mx-auto h-12 w-12 text-muted-foreground"}),e.jsx("h3",{className:"mt-4 text-lg font-semibold",children:"No Events Found"}),e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:"Activity events will appear here as they occur."})]})})})]}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold tracking-tight",children:"Activity"}),e.jsxs("p",{className:"text-muted-foreground",children:["View system activity and events (",n.length," events)"]})]}),e.jsxs(N,{variant:"outline",size:"sm",onClick:()=>void l(),disabled:i,children:[e.jsx(E,{className:`h-4 w-4 mr-2 ${i?"animate-spin":""}`}),"Refresh"]})]}),e.jsx("div",{className:"space-y-3",children:n.map(s=>{const t=h.has(s.seq);return e.jsxs(c,{className:"transition-colors",children:[e.jsx(k,{className:"py-3 cursor-pointer hover:bg-muted/30",onClick:()=>g(s.seq),children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex items-start gap-2 flex-1 min-w-0",children:[t?e.jsx(w,{className:"h-4 w-4 mt-0.5 text-muted-foreground shrink-0"}):e.jsx(b,{className:"h-4 w-4 mt-0.5 text-muted-foreground shrink-0"}),e.jsxs("div",{className:"space-y-1 flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsxs(C,{className:"text-sm font-medium",children:["#",s.seq]}),s.kind&&e.jsx(m,{variant:"outline",className:"text-xs",children:s.kind}),s.level&&e.jsx(m,{className:`text-xs ${j(s.level)}`,children:s.level})]}),s.message&&e.jsx("p",{className:`text-sm text-muted-foreground ${t?"":"truncate"}`,children:s.message})]})]}),e.jsx("span",{className:"text-xs text-muted-foreground whitespace-nowrap",children:f(s.ts)})]})}),t&&e.jsx(d,{className:"pt-0 pb-4",children:e.jsx("pre",{className:"text-xs bg-muted p-3 rounded-md overflow-x-auto",children:JSON.stringify(s,null,2)})})]},s.seq)})})]})}export{$ as default};
1
+ import{r as a,A as p,j as e,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};
@@ -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-B81KYk3Z.js";import{C as m,a as x,b as C,c as S}from"./card-bSzcwVEz.js";import{M as w}from"./markdown-editor-DSI9T1tt.js";import{A as y}from"./arrow-left-D4GyWema.js";import{C as A}from"./circle-check-big-HUp82Tz-.js";import"./index-ObZJu-Zv.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...
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-B81KYk3Z.js";import{C as i,a as c,b}from"./card-bSzcwVEz.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
+ 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-B81KYk3Z.js";import{C as W,b as G,c as V,d as Z,a as _}from"./card-bSzcwVEz.js";import{L as w}from"./label-CHP4q6u3.js";import{B as ee}from"./badge-CgbZdX-R.js";import{A as I,a as C}from"./alert-a0XoDY__.js";import{I as L}from"./info-wSiZMXgL.js";import{C as se}from"./circle-alert-Dn8B5NPI.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}" \\
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-B81KYk3Z.js";import{C as m,b as g,c as j,d as p,a as v}from"./card-bSzcwVEz.js";import{L as c}from"./label-CHP4q6u3.js";import{S as X,a as Z,b as ee,c as se,d as a}from"./select-CG6kgyUu.js";import{S as N}from"./switch-7YpWWyAq.js";import{B as F}from"./badge-CgbZdX-R.js";import{C as be}from"./circle-alert-Dn8B5NPI.js";import"./index-ObZJu-Zv.js";import"./chevron-up-znuSUWjo.js";/**
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-B81KYk3Z.js";import{C as w}from"./circle-check-2Hh5KJn8.js";import{C as b}from"./circle-x-DBrbnMPA.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
+ 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};