@lovelybunch/api 1.0.76 → 1.0.77-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/dist/config/oauth.d.ts +33 -0
  2. package/dist/config/oauth.js +43 -0
  3. package/dist/lib/auth/auth-manager.d.ts +21 -1
  4. package/dist/lib/auth/auth-manager.js +57 -3
  5. package/dist/lib/auth/clerk-verifier.d.ts +22 -0
  6. package/dist/lib/auth/clerk-verifier.js +30 -0
  7. package/dist/lib/terminal/terminal-manager.js +2 -1
  8. package/dist/middleware/auth.js +40 -3
  9. package/dist/routes/api/v1/auth/route.js +90 -0
  10. package/dist/routes/api/v1/auth-settings/route.js +83 -2
  11. package/dist/routes/api/v1/events/status/route.d.ts +1 -1
  12. package/dist/routes/api/v1/jobs/[id]/route.d.ts +8 -8
  13. package/dist/routes/api/v1/jobs/[id]/run/route.d.ts +2 -2
  14. package/dist/routes/api/v1/jobs/[id]/runs/[runId]/route.d.ts +2 -2
  15. package/dist/routes/api/v1/jobs/route.d.ts +8 -8
  16. package/dist/routes/api/v1/jobs/status/route.d.ts +1 -1
  17. package/dist/routes/api/v1/mail/route.d.ts +3 -3
  18. package/dist/routes/api/v1/tasks/[id]/route.d.ts +4 -4
  19. package/dist/routes/api/v1/tasks/[id]/steps/[stepId]/route.d.ts +2 -2
  20. package/dist/routes/api/v1/tasks/route.d.ts +1 -1
  21. package/dist/server-with-static.js +36 -17
  22. package/dist/server.js +12 -0
  23. package/package.json +25 -23
  24. package/static/assets/{ActivityPage-sJEQn6DK.js → ActivityPage-DqSj7XDx.js} +1 -1
  25. package/static/assets/{AgentsContextEditPage-DU3qIXk9.js → AgentsContextEditPage-C5afMo09.js} +1 -1
  26. package/static/assets/AgentsContextPage-IrZGdiYt.js +1 -0
  27. package/static/assets/{ApiKeysSettingsPage-Bg84BQHV.js → ApiKeysSettingsPage-CFBTIYNp.js} +2 -2
  28. package/static/assets/AuthSettingsPage-LU7DFMG6.js +11 -0
  29. package/static/assets/{CallbackPage-BFn0Np2S.js → CallbackPage-Beg0ZLv4.js} +1 -1
  30. package/static/assets/CoconutCallbackPage-BuBYbeY-.js +1 -0
  31. package/static/assets/CodePage-C9auBWu3.js +2 -0
  32. package/static/assets/{CollapsibleSection-CNs1mvsZ.js → CollapsibleSection-C3uaXDrK.js} +1 -1
  33. package/static/assets/{DashboardPage-DMJSzzgD.js → DashboardPage-DK2uEtcQ.js} +2 -2
  34. package/static/assets/{GitPage-uqene8zj.js → GitPage-BgfZ5rXn.js} +2 -2
  35. package/static/assets/{GitSettingsPage-CLswbZsT.js → GitSettingsPage-DIhaZgDD.js} +2 -2
  36. package/static/assets/{IdentityPage-BDTPXEo7.js → IdentityPage-6_IEyGmH.js} +2 -2
  37. package/static/assets/{ImplementationStepsEditor-D4cvhPhz.js → ImplementationStepsEditor-BXjs77nI.js} +1 -1
  38. package/static/assets/IntegrationsSettingsPage-Cu-C86-i.js +1 -0
  39. package/static/assets/JobDetailPage-BWd0sz7w.js +1 -0
  40. package/static/assets/KnowledgeDetailPage-Cx0NiVN5.js +1 -0
  41. package/static/assets/KnowledgeEditPage-Dtp9Ceyp.js +1 -0
  42. package/static/assets/{KnowledgePage-B2zI3xwW.js → KnowledgePage-DRavibOT.js} +2 -2
  43. package/static/assets/LoginPage-Bn-55dqi.js +1 -0
  44. package/static/assets/MailInboxPage-B-mzoocZ.js +1 -0
  45. package/static/assets/MailProcessingModal-B5HFIwxh.js +1 -0
  46. package/static/assets/MailReadPage-DVVICNmn.js +1 -0
  47. package/static/assets/MailSentPage-BmqXLEIF.js +1 -0
  48. package/static/assets/McpSettingsPage-D6hW-2uy.js +1 -0
  49. package/static/assets/{MemoryEditPage-DXSQoCT4.js → MemoryEditPage-Cw2oWAW2.js} +1 -1
  50. package/static/assets/MemoryPage-BKNQlp0x.js +1 -0
  51. package/static/assets/{NewKnowledgePage-deMsezK8.js → NewKnowledgePage-zWnjfGF1.js} +1 -1
  52. package/static/assets/{NewSkillPage-DRYWdrlV.js → NewSkillPage-eqK5nwnk.js} +1 -1
  53. package/static/assets/{NewTaskPage-B6xdic5_.js → NewTaskPage-BcOmFrza.js} +2 -2
  54. package/static/assets/{NotFoundPage-Bxu9uKFO.js → NotFoundPage-CKcBMXOQ.js} +1 -1
  55. package/static/assets/{NotificationsSettingsPage-CLgtsCVM.js → NotificationsSettingsPage-DETz35D7.js} +1 -1
  56. package/static/assets/PromptsSettingsPage-8--L7lw4.js +1 -0
  57. package/static/assets/{ResourceDetailPage-CMPDRdVM.js → ResourceDetailPage-BH-A0yn7.js} +1 -1
  58. package/static/assets/{ResourcesPage-DspYILfG.js → ResourcesPage-CfdKptfd.js} +1 -1
  59. package/static/assets/{RoleEditPage-DXtzicVZ.js → RoleEditPage-DfqF4tLW.js} +1 -1
  60. package/static/assets/RolePage-CCwufp_f.js +1 -0
  61. package/static/assets/{RulesSettingsPage-E8V9cexV.js → RulesSettingsPage-dzUPGors.js} +4 -4
  62. package/static/assets/{RunDetailPage-DsxkqFst.js → RunDetailPage-B9I5nrOb.js} +1 -1
  63. package/static/assets/SchedulePage-7Ufvzd34.js +4 -0
  64. package/static/assets/SkillDetailPage-DCjWVhUE.js +1 -0
  65. package/static/assets/{SkillEditPage-DwyebzFV.js → SkillEditPage-BA-ebFGI.js} +1 -1
  66. package/static/assets/{SkillsPage-CauK65X_.js → SkillsPage-QqNzKzhn.js} +2 -2
  67. package/static/assets/{SkillsSettingsPage-DXMRv3jR.js → SkillsSettingsPage-DPXiPnWO.js} +1 -1
  68. package/static/assets/SourceInput-0S84iX2C.js +1 -0
  69. package/static/assets/{TagInput-Ct-WRvTs.js → TagInput-C_2MLj_1.js} +1 -1
  70. package/static/assets/{TaskDetailPage-CApk2iBh.js → TaskDetailPage-6E7isObV.js} +2 -2
  71. package/static/assets/{TaskEditPage-NgOVShfK.js → TaskEditPage-Bd1DFoK3.js} +1 -1
  72. package/static/assets/{TasksPage-BoPrP_Rl.js → TasksPage-CeWPVVwj.js} +1 -1
  73. package/static/assets/{TeamEditPage-ChY6mYm8.js → TeamEditPage-CgYsqeq9.js} +1 -1
  74. package/static/assets/TeamPage-CEojyLvc.js +1 -0
  75. package/static/assets/{TerminalPage-CRhcscF2.js → TerminalPage-D-LJMND7.js} +1 -1
  76. package/static/assets/{TerminalSessionPage-CSCQg2sn.js → TerminalSessionPage-BGHgOQhV.js} +2 -2
  77. package/static/assets/{UserPreferencesPage-DxCSWJnS.js → UserPreferencesPage-D5nGgztl.js} +1 -1
  78. package/static/assets/{UserSettingsPage-DKkOLNPV.js → UserSettingsPage-Dv6fSWWx.js} +1 -1
  79. package/static/assets/UtilitiesPage-hCM0KDs8.js +1 -0
  80. package/static/assets/{alert-Dw_RSroN.js → alert-DxBTp_In.js} +1 -1
  81. package/static/assets/{arrow-down-UClxXzT-.js → arrow-down-Be4lZFzF.js} +1 -1
  82. package/static/assets/{arrow-left-DWmf9YJp.js → arrow-left-DzGSl0dC.js} +1 -1
  83. package/static/assets/{arrow-up-fLCh7Hvh.js → arrow-up-6HVzdiIw.js} +1 -1
  84. package/static/assets/{arrow-up-down-Btc3okb3.js → arrow-up-down-C9lUuyDO.js} +1 -1
  85. package/static/assets/{badge-vIqE5SOP.js → badge-DyF_7_dv.js} +1 -1
  86. package/static/assets/{browser-modal-DgMJTsMd.js → browser-modal-DKHn0FAC.js} +2 -2
  87. package/static/assets/{card-DPLdBoa5.js → card-DW9yx9FC.js} +1 -1
  88. package/static/assets/{chevron-left-CiNaLX-v.js → chevron-left-CJjrbO2y.js} +1 -1
  89. package/static/assets/{chevron-up-DFd-7wxW.js → chevron-up-BrSqNhfU.js} +1 -1
  90. package/static/assets/{chevrons-up-BfU70OcQ.js → chevrons-up-wQrNHZqU.js} +1 -1
  91. package/static/assets/{circle-alert-Mv00T-P2.js → circle-alert-ByPjREVD.js} +1 -1
  92. package/static/assets/{circle-check-xMiP6SLO.js → circle-check-D7peX4CI.js} +1 -1
  93. package/static/assets/{circle-check-big-BEY1IoIP.js → circle-check-big--yqXPZzU.js} +1 -1
  94. package/static/assets/{circle-play-iZZwaGbV.js → circle-play-C2th8mzN.js} +1 -1
  95. package/static/assets/{circle-x-z3iynaE7.js → circle-x-Oj6Gai3s.js} +1 -1
  96. package/static/assets/{clipboard-C8wZRPDH.js → clipboard-qigxJPlJ.js} +1 -1
  97. package/static/assets/{clock-C_9shc08.js → clock-JhtahL2B.js} +1 -1
  98. package/static/assets/{code-DH-sRhus.js → code-DcBDG3ah.js} +1 -1
  99. package/static/assets/{download-CE8b59ER.js → download-BBjLPrfj.js} +1 -1
  100. package/static/assets/{external-link-DPyKt8NE.js → external-link-DDneC3kx.js} +1 -1
  101. package/static/assets/{eye-BpGD-yoS.js → eye-Bl23BbY6.js} +1 -1
  102. package/static/assets/{folder-git-2-BIw4zbmy.js → folder-git-2-BBe22u2y.js} +1 -1
  103. package/static/assets/{globe-CUo7eHKN.js → globe-C3j3aWiD.js} +1 -1
  104. package/static/assets/{index-UXL5-kaP.js → index-0zkOcODK.js} +105 -105
  105. package/static/assets/{index-ClO9-JVh.js → index-B-9XKFgb.js} +1 -1
  106. package/static/assets/{index-Cdwx6Zps.js → index-CWt3zgDI.js} +1 -1
  107. package/static/assets/{index-Bkt1rQVV.js → index-Cbo5QxHl.js} +1 -1
  108. package/static/assets/{index-iB8oed57.js → index-D2rSjJPF.js} +1 -1
  109. package/static/assets/{index-Bfb3OTwj.js → index-DFfxOZw8.js} +1 -1
  110. package/static/assets/{index-B07hel4U.js → index-DUwRskPW.js} +1 -1
  111. package/static/assets/index-DVMcu9sQ.css +1 -0
  112. package/static/assets/{index-CpJ0uBf3.js → index-DaAZbWZV.js} +1 -1
  113. package/static/assets/{index-BCwmQxLC.js → index-DdDCTC_d.js} +1 -1
  114. package/static/assets/{index-jaRIZ6SY.js → index-DdSybLsG.js} +1 -1
  115. package/static/assets/{index-BaR4iUzg.js → index-DgFdrtDt.js} +1 -1
  116. package/static/assets/{index-CTouvf2d.js → index-DkobSVA-.js} +1 -1
  117. package/static/assets/{index-CsBxEWw5.js → index-DuWsaYa4.js} +1 -1
  118. package/static/assets/{index-CGbmjmEy.js → index-DukcrMyC.js} +1 -1
  119. package/static/assets/{index-BOKaM9K-.js → index-I6ZfnFaA.js} +1 -1
  120. package/static/assets/{index-Dkr9CBL7.js → index-QZn_aaqg.js} +1 -1
  121. package/static/assets/{index-C65b3D5_.js → index-UM1qitEs.js} +1 -1
  122. package/static/assets/{index-DZAYfTI2.js → index-r07pPAcM.js} +1 -1
  123. package/static/assets/{index-DnZKG-_7.js → index-xBQb0rMo.js} +1 -1
  124. package/static/assets/{info-D-UNBNx2.js → info-DWORrO-s.js} +1 -1
  125. package/static/assets/{label-8VKluf9w.js → label-DyhnItJm.js} +1 -1
  126. package/static/assets/{markdown-editor-DBdRsbP2.js → markdown-editor-C8LFQE7K.js} +38 -38
  127. package/static/assets/{message-square-CO8kDUed.js → message-square-CiISW36v.js} +1 -1
  128. package/static/assets/{paperclip-DlLXZbru.js → paperclip-DRufaOtA.js} +1 -1
  129. package/static/assets/{pause-zSiaxJBu.js → pause-GqIUdKFa.js} +1 -1
  130. package/static/assets/{pipeline-builders-Bkf0wt_O.js → pipeline-builders-DrEjlsbH.js} +1 -1
  131. package/static/assets/{play-DVBhRokt.js → play-CkuTY54l.js} +1 -1
  132. package/static/assets/{radio-group-CThYUcA4.js → radio-group-ClpV676y.js} +1 -1
  133. package/static/assets/{refresh-cw-tXYl1ePu.js → refresh-cw-CYBx0C_n.js} +1 -1
  134. package/static/assets/{search-BxF7Wwex.js → search-DxiQuWo1.js} +1 -1
  135. package/static/assets/{select-CyHFRA1Y.js → select-D_L7OXwN.js} +1 -1
  136. package/static/assets/{server-lRxThHjr.js → server-CgjJESGe.js} +1 -1
  137. package/static/assets/{switch-BUpDbrux.js → switch-DXojpqQ8.js} +1 -1
  138. package/static/assets/{tabs-DkvCmQEX.js → tabs-zdz4RlY5.js} +1 -1
  139. package/static/assets/{tag-CkcZNLnh.js → tag-CeaYtqPJ.js} +1 -1
  140. package/static/assets/terminal-preview-CspSfoko.js +1 -0
  141. package/static/assets/{triangle-alert-CmjG_mbF.js → triangle-alert-DTdlIh6V.js} +1 -1
  142. package/static/assets/{use-terminal-D3iV7-iC.js → use-terminal-DkVoTttR.js} +1 -1
  143. package/static/assets/{video-CY_dOujm.js → video-5zJ0jcFw.js} +1 -1
  144. package/static/index.html +2 -2
  145. package/dist/routes/api/v1/context/architecture/route.d.ts +0 -3
  146. package/dist/routes/api/v1/context/architecture/route.js +0 -245
  147. package/dist/routes/api/v1/context/project/route.d.ts +0 -3
  148. package/dist/routes/api/v1/context/project/route.js +0 -200
  149. package/static/assets/AgentsContextPage-tJ-LhFYb.js +0 -1
  150. package/static/assets/AuthSettingsPage-Bwr7uP3z.js +0 -11
  151. package/static/assets/CodePage-kp4s3wCJ.js +0 -2
  152. package/static/assets/IntegrationsSettingsPage-o7NXZGt9.js +0 -1
  153. package/static/assets/JobDetailPage-DuEiPz6X.js +0 -1
  154. package/static/assets/KnowledgeDetailPage-DFVud_VC.js +0 -1
  155. package/static/assets/KnowledgeEditPage-XG6HKK7E.js +0 -1
  156. package/static/assets/LoginPage-CUJRxwXy.js +0 -1
  157. package/static/assets/MailInboxPage-BlCG-tba.js +0 -1
  158. package/static/assets/MailProcessingModal-BJIdHOqK.js +0 -1
  159. package/static/assets/MailReadPage-MoNo_gmW.js +0 -1
  160. package/static/assets/MailSentPage-QzpuIJmT.js +0 -1
  161. package/static/assets/McpSettingsPage-BZcCGkGM.js +0 -1
  162. package/static/assets/MemoryPage-oBnyuvSf.js +0 -1
  163. package/static/assets/PromptsSettingsPage-BWaELCjG.js +0 -1
  164. package/static/assets/RolePage-DafGURGp.js +0 -1
  165. package/static/assets/SchedulePage-B2YvNDHr.js +0 -4
  166. package/static/assets/SkillDetailPage-CWkqSfuT.js +0 -1
  167. package/static/assets/SourceInput-C0iKqbQ1.js +0 -1
  168. package/static/assets/TeamPage-DH-dJhFG.js +0 -1
  169. package/static/assets/UtilitiesPage-CBNSvixW.js +0 -1
  170. package/static/assets/index-BcCuKdbf.css +0 -1
  171. package/static/assets/terminal-preview-CLWDhoOZ.js +0 -1
@@ -11,6 +11,9 @@ export declare function withLightweightRuns<T extends {
11
11
  export declare function GET(c: Context): Promise<(Response & import("hono").TypedResponse<{
12
12
  success: true;
13
13
  data: {
14
+ id: string;
15
+ name: string;
16
+ status: ScheduledJobStatus;
14
17
  schedule: {
15
18
  type: "cron";
16
19
  expression: string;
@@ -24,11 +27,8 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
24
27
  anchorHour?: number;
25
28
  };
26
29
  description?: string;
27
- id: string;
28
- name: string;
29
30
  prompt: string;
30
31
  model: string;
31
- status: ScheduledJobStatus;
32
32
  metadata: {
33
33
  createdAt: string;
34
34
  updatedAt: string;
@@ -41,8 +41,8 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
41
41
  agentIds?: string[];
42
42
  mcpServers?: string[];
43
43
  runs: {
44
- error?: string;
45
44
  id: string;
45
+ error?: string;
46
46
  status: import("@lovelybunch/types").ScheduledJobRunStatus;
47
47
  jobId: string;
48
48
  trigger: import("@lovelybunch/types").ScheduledJobTrigger;
@@ -66,6 +66,9 @@ export declare function POST(c: Context): Promise<(Response & import("hono").Typ
66
66
  }, 400, "json">) | (Response & import("hono").TypedResponse<{
67
67
  success: true;
68
68
  data: {
69
+ id: string;
70
+ name: string;
71
+ status: ScheduledJobStatus;
69
72
  schedule: {
70
73
  type: "cron";
71
74
  expression: string;
@@ -79,11 +82,8 @@ export declare function POST(c: Context): Promise<(Response & import("hono").Typ
79
82
  anchorHour?: number;
80
83
  };
81
84
  description?: string;
82
- id: string;
83
- name: string;
84
85
  prompt: string;
85
86
  model: string;
86
- status: ScheduledJobStatus;
87
87
  metadata: {
88
88
  createdAt: string;
89
89
  updatedAt: string;
@@ -96,8 +96,8 @@ export declare function POST(c: Context): Promise<(Response & import("hono").Typ
96
96
  agentIds?: string[];
97
97
  mcpServers?: string[];
98
98
  runs: {
99
- error?: string;
100
99
  id: string;
100
+ error?: string;
101
101
  status: import("@lovelybunch/types").ScheduledJobRunStatus;
102
102
  jobId: string;
103
103
  trigger: import("@lovelybunch/types").ScheduledJobTrigger;
@@ -7,7 +7,7 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
7
7
  runningCount: number;
8
8
  jobs: {
9
9
  id: string;
10
- status: import("@lovelybunch/types").ScheduledJobStatus;
10
+ status: import("node_modules/@lovelybunch/types/src/index.js").ScheduledJobStatus;
11
11
  nextRunAt?: string;
12
12
  lastRunAt?: string;
13
13
  timerActive: boolean;
@@ -116,7 +116,7 @@ export declare function setMailStatusHandler(c: Context): Promise<(Response & im
116
116
  }, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
117
117
  success: false;
118
118
  error: any;
119
- }, 500 | 404, "json">)>;
119
+ }, 404 | 500, "json">)>;
120
120
  /**
121
121
  * POST /api/v1/mail/:id/reply
122
122
  * Reply to an email
@@ -154,7 +154,7 @@ export declare function replyMailHandler(c: Context): Promise<(Response & import
154
154
  }, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
155
155
  success: false;
156
156
  error: any;
157
- }, 500 | 404, "json">)>;
157
+ }, 404 | 500, "json">)>;
158
158
  /**
159
159
  * POST /api/v1/mail/send
160
160
  * Send an email (coming soon)
@@ -217,7 +217,7 @@ export declare function setMailActionHandler(c: Context): Promise<(Response & im
217
217
  }, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
218
218
  success: false;
219
219
  error: any;
220
- }, 500 | 404, "json">)>;
220
+ }, 404 | 500, "json">)>;
221
221
  /**
222
222
  * GET /api/v1/mail/:id/processing
223
223
  * Get processing status and log tail for an email
@@ -13,7 +13,7 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
13
13
  intent?: string;
14
14
  content?: string;
15
15
  author: {
16
- type: import("@lovelybunch/types").AuthorType;
16
+ type: import("node_modules/@lovelybunch/types/src/index.js").AuthorType;
17
17
  id: string;
18
18
  name: string;
19
19
  email?: string;
@@ -29,7 +29,7 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
29
29
  error?: string;
30
30
  executedAt?: string;
31
31
  }[];
32
- status: import("@lovelybunch/types").TaskStatus;
32
+ status: import("node_modules/@lovelybunch/types/src/index.js").TaskStatus;
33
33
  comments?: {
34
34
  id: string;
35
35
  author: string;
@@ -60,7 +60,7 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
60
60
  intent?: string;
61
61
  content?: string;
62
62
  author: {
63
- type: import("@lovelybunch/types").AuthorType;
63
+ type: import("node_modules/@lovelybunch/types/src/index.js").AuthorType;
64
64
  id: string;
65
65
  name: string;
66
66
  email?: string;
@@ -76,7 +76,7 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
76
76
  error?: string;
77
77
  executedAt?: string;
78
78
  }[];
79
- status: import("@lovelybunch/types").TaskStatus;
79
+ status: import("node_modules/@lovelybunch/types/src/index.js").TaskStatus;
80
80
  comments?: {
81
81
  id: string;
82
82
  author: string;
@@ -19,7 +19,7 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
19
19
  intent?: string;
20
20
  content?: string;
21
21
  author: {
22
- type: import("@lovelybunch/types").AuthorType;
22
+ type: import("node_modules/@lovelybunch/types/src/index.js").AuthorType;
23
23
  id: string;
24
24
  name: string;
25
25
  email?: string;
@@ -35,7 +35,7 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
35
35
  error?: string;
36
36
  executedAt?: string;
37
37
  }[];
38
- status: import("@lovelybunch/types").TaskStatus;
38
+ status: import("node_modules/@lovelybunch/types/src/index.js").TaskStatus;
39
39
  comments?: {
40
40
  id: string;
41
41
  author: string;
@@ -14,7 +14,7 @@ import { Context } from 'hono';
14
14
  */
15
15
  export declare function GET(c: Context): Promise<(Response & import("hono").TypedResponse<{
16
16
  offset: number;
17
- data: never[];
17
+ data: import("hono/utils/types").JSONValue[];
18
18
  limit: number;
19
19
  totalCount: number;
20
20
  count: number;
@@ -12,10 +12,17 @@ import { getGlobalJobScheduler } from './lib/jobs/global-job-scheduler.js';
12
12
  import { fileURLToPath } from 'url';
13
13
  import { getLogger } from '@lovelybunch/core/logging';
14
14
  import { getLogsDir } from '@lovelybunch/core';
15
+ import { oauthRuntimeFromAuthConfig, setOAuthRuntimeConfig } from './config/oauth.js';
16
+ import { getAuthManager } from './lib/auth/auth-manager.js';
15
17
  const __filename = fileURLToPath(import.meta.url);
16
18
  const __dirname = path.dirname(__filename);
17
19
  // Load environment variables from .env file in project root
18
20
  dotenvConfig({ path: path.resolve(__dirname, '../../../.env') });
21
+ const verbose = process.env.COCONUT_VERBOSE === '1' || process.env.COCONUT_VERBOSE === 'true';
22
+ function vlog(...args) {
23
+ if (verbose)
24
+ console.log(...args);
25
+ }
19
26
  // Helper: Find .nut directory by traversing up from cwd
20
27
  // Only returns a .nut directory if it contains config.json
21
28
  function findNutDirectorySync() {
@@ -33,7 +40,7 @@ function findNutDirectorySync() {
33
40
  }
34
41
  // Initialize logger with config from .nut/config.json or use OS app data directory
35
42
  // This must happen BEFORE importing route handlers (they call getLogger at module level)
36
- console.log('🔍 Initializing activity logging...');
43
+ vlog('🔍 Initializing activity logging...');
37
44
  try {
38
45
  const nutDir = findNutDirectorySync();
39
46
  let logsDir = getLogsDir(); // Default to OS app data directory
@@ -43,8 +50,8 @@ try {
43
50
  if (nutDir) {
44
51
  const projectRoot = path.dirname(nutDir);
45
52
  const configPath = path.join(nutDir, 'config.json');
46
- console.log(' Project root:', projectRoot);
47
- console.log(' Config path:', configPath);
53
+ vlog(' Project root:', projectRoot);
54
+ vlog(' Config path:', configPath);
48
55
  const configData = fs.readFileSync(configPath, 'utf-8');
49
56
  const config = JSON.parse(configData);
50
57
  // Check if logging is explicitly disabled in config
@@ -68,9 +75,9 @@ try {
68
75
  logsDir,
69
76
  rotateBytes
70
77
  });
71
- console.log('📝 Activity logging ENABLED');
72
- console.log(' Logs directory:', logsDir);
73
- console.log(' Coconut ID:', coconutId);
78
+ vlog('📝 Activity logging ENABLED');
79
+ vlog(' Logs directory:', logsDir);
80
+ vlog(' Coconut ID:', coconutId);
74
81
  // Test log immediately
75
82
  logger.log({
76
83
  kind: 'system.startup',
@@ -79,10 +86,10 @@ try {
79
86
  tags: ['system', 'startup'],
80
87
  payload: { message: 'Server starting with logging enabled' }
81
88
  });
82
- console.log(' ✓ Test event logged');
89
+ vlog(' ✓ Test event logged');
83
90
  }
84
91
  else {
85
- console.log('📝 Activity logging disabled in config');
92
+ vlog('📝 Activity logging disabled in config');
86
93
  }
87
94
  }
88
95
  catch (error) {
@@ -100,13 +107,14 @@ app.use('/api/*', trimTrailingSlash());
100
107
  // Import and apply authentication middleware
101
108
  import { authMiddleware } from './middleware/auth.js';
102
109
  app.use('/api/*', authMiddleware);
110
+ app.use('/ws/*', authMiddleware);
103
111
  // Create WebSocket support
104
112
  const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app });
105
113
  // WebSocket route for terminal sessions
106
114
  app.get('/ws/terminal/:sessionId', upgradeWebSocket((c) => ({
107
115
  onOpen: (_evt, ws) => {
108
116
  const sessionId = c.req.param('sessionId');
109
- console.log(`WebSocket connected for terminal session: ${sessionId}`);
117
+ vlog(`WebSocket connected for terminal session: ${sessionId}`);
110
118
  const terminalManager = getGlobalTerminalManager();
111
119
  // Extract the raw WebSocket from the WSContext
112
120
  const rawWs = ws.raw;
@@ -125,7 +133,7 @@ app.get('/ws/terminal/:sessionId', upgradeWebSocket((c) => ({
125
133
  // Message handling is done in the terminal manager
126
134
  },
127
135
  onClose: (_evt, _ws) => {
128
- console.log('WebSocket connection closed');
136
+ vlog('WebSocket connection closed');
129
137
  },
130
138
  onError: (evt, _ws) => {
131
139
  console.error('WebSocket error:', evt);
@@ -185,7 +193,7 @@ import version from './routes/api/v1/version/index.js';
185
193
  import { slackRoutes } from './routes/api/v1/slack/index.js';
186
194
  import { mailRoutes } from './routes/api/v1/mail/index.js';
187
195
  // Register API routes FIRST
188
- console.log('🔗 Registering API routes...');
196
+ vlog('🔗 Registering API routes...');
189
197
  app.route('/api/v1/auth', auth);
190
198
  app.route('/api/v1/auth-settings', authSettings);
191
199
  app.route('/api/v1/api-keys', apiKeys);
@@ -216,7 +224,7 @@ app.route('/api/v1/events', events);
216
224
  app.route('/api/v1/version', version);
217
225
  app.route('/api/v1/slack', slackRoutes);
218
226
  app.route('/api/v1/mail', mailRoutes);
219
- console.log('✅ API routes registered');
227
+ vlog('✅ API routes registered');
220
228
  app.get(PUBLIC_AGENT_CARD_PATH, authMiddleware, async (c) => {
221
229
  try {
222
230
  const document = await readAgentCard();
@@ -259,7 +267,7 @@ for (const possiblePath of possibleStaticPaths) {
259
267
  try {
260
268
  if (fs.existsSync(possiblePath)) {
261
269
  staticPath = possiblePath;
262
- console.log(`📁 Serving static files from: ${staticPath}`);
270
+ vlog(`📁 Serving static files from: ${staticPath}`);
263
271
  break;
264
272
  }
265
273
  }
@@ -304,7 +312,18 @@ else {
304
312
  export async function startServer(options = {}) {
305
313
  const port = options.port || (process.env.PORT ? parseInt(process.env.PORT) : 3000);
306
314
  const host = options.host || '0.0.0.0';
307
- console.log(`Starting server on ${host}:${port}...`);
315
+ // Populate the OAuth runtime cache from auth.json. `providers.oauth.coconut`
316
+ // is the single source of truth: presence + `enabled: true` + `clientId`
317
+ // activates the Clerk Bearer path. Absent/disabled/missing-clientId all
318
+ // disable OAuth silently (no error — a coconut without OAuth is valid).
319
+ try {
320
+ const authConfig = await getAuthManager().loadAuthConfig();
321
+ setOAuthRuntimeConfig(oauthRuntimeFromAuthConfig(authConfig));
322
+ }
323
+ catch {
324
+ setOAuthRuntimeConfig({ enabled: false });
325
+ }
326
+ vlog(`Starting server on ${host}:${port}...`);
308
327
  const server = serve({
309
328
  fetch: app.fetch,
310
329
  port,
@@ -319,10 +338,10 @@ export async function startServer(options = {}) {
319
338
  httpServer.requestTimeout = 330_000;
320
339
  // Inject WebSocket support
321
340
  injectWebSocket(server);
322
- console.log(`🚀 Server running at http://${host === '0.0.0.0' ? 'localhost' : host}:${port}`);
323
- console.log(`🔌 WebSocket available at ws://${host === '0.0.0.0' ? 'localhost' : host}:${port}/ws/terminal/:sessionId`);
341
+ vlog(`🚀 Server running at http://${host === '0.0.0.0' ? 'localhost' : host}:${port}`);
342
+ vlog(`🔌 WebSocket available at ws://${host === '0.0.0.0' ? 'localhost' : host}:${port}/ws/terminal/:sessionId`);
324
343
  if (staticPath) {
325
- console.log(`🌐 Frontend available at http://${host === '0.0.0.0' ? 'localhost' : host}:${port}`);
344
+ vlog(`🌐 Frontend available at http://${host === '0.0.0.0' ? 'localhost' : host}:${port}`);
326
345
  }
327
346
  return server;
328
347
  }
package/dist/server.js CHANGED
@@ -11,6 +11,8 @@ import { fileURLToPath } from 'url';
11
11
  import fs from 'fs';
12
12
  import { getLogger } from '@lovelybunch/core/logging';
13
13
  import { getLogsDir } from '@lovelybunch/core';
14
+ import { oauthRuntimeFromAuthConfig, setOAuthRuntimeConfig } from './config/oauth.js';
15
+ import { getAuthManager } from './lib/auth/auth-manager.js';
14
16
  const __filename = fileURLToPath(import.meta.url);
15
17
  const __dirname = path.dirname(__filename);
16
18
  // Load environment variables from .env file in project root
@@ -99,6 +101,7 @@ app.use('/api/*', trimTrailingSlash());
99
101
  // Import and apply authentication middleware
100
102
  import { authMiddleware } from './middleware/auth.js';
101
103
  app.use('/api/*', authMiddleware);
104
+ app.use('/ws/*', authMiddleware);
102
105
  // Create WebSocket support
103
106
  const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app });
104
107
  // WebSocket route for terminal sessions
@@ -234,6 +237,15 @@ app.get(PUBLIC_AGENT_CARD_PATH, authMiddleware, async (c) => {
234
237
  app.get('/health', (c) => {
235
238
  return c.json({ status: 'ok', timestamp: new Date().toISOString() });
236
239
  });
240
+ // Populate the OAuth runtime cache from auth.json. See server-with-static.ts
241
+ // for the full rationale.
242
+ try {
243
+ const authConfig = await getAuthManager().loadAuthConfig();
244
+ setOAuthRuntimeConfig(oauthRuntimeFromAuthConfig(authConfig));
245
+ }
246
+ catch {
247
+ setOAuthRuntimeConfig({ enabled: false });
248
+ }
237
249
  // Start server
238
250
  const port = process.env.PORT ? parseInt(process.env.PORT) : 3001;
239
251
  console.log(`Starting server on port ${port}...`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovelybunch/api",
3
- "version": "1.0.76",
3
+ "version": "1.0.77-alpha.1",
4
4
  "type": "module",
5
5
  "main": "dist/server-with-static.js",
6
6
  "exports": {
@@ -11,18 +11,6 @@
11
11
  "dist/**/*",
12
12
  "static/**/*"
13
13
  ],
14
- "scripts": {
15
- "dev": "NODE_ENV=development GAIT_DEV_ROOT=../../.nut tsx watch src/server.ts",
16
- "build": "tsc",
17
- "build:bundle": "tsc && node scripts/bundle-frontend.js",
18
- "start": "node dist/server-with-static.js",
19
- "start:dev": "node dist/server.js",
20
- "clean": "rm -rf dist static tsconfig.tsbuildinfo coverage",
21
- "test": "vitest run",
22
- "test:coverage": "vitest run --coverage",
23
- "test:watch": "vitest watch",
24
- "test:ui": "vitest --ui"
25
- },
26
14
  "keywords": [
27
15
  "api",
28
16
  "server",
@@ -35,11 +23,8 @@
35
23
  "description": "Coconut API server",
36
24
  "dependencies": {
37
25
  "@ai-sdk/anthropic": "^3.0.41",
38
- "@hono/node-server": "^1.13.7",
39
- "@hono/node-ws": "^1.0.6",
40
- "@lovelybunch/core": "^1.0.76",
41
- "@lovelybunch/mcp": "^1.0.76",
42
- "@lovelybunch/types": "^1.0.76",
26
+ "@hono/node-server": "^1.19.11",
27
+ "@hono/node-ws": "^1.3.0",
43
28
  "adm-zip": "^0.5.16",
44
29
  "ai": "^6.0.79",
45
30
  "bcryptjs": "^2.4.3",
@@ -47,13 +32,17 @@
47
32
  "dotenv": "^17.2.1",
48
33
  "fuse.js": "^7.0.0",
49
34
  "gray-matter": "^4.0.3",
50
- "hono": "^4.9.5",
35
+ "hono": "^4.12.9",
36
+ "jose": "^6.2.2",
51
37
  "jsonwebtoken": "^9.0.2",
52
38
  "node-pty": "^1.0.0",
53
39
  "replicate": "^0.34.1",
54
40
  "sharp": "^0.33.5",
55
41
  "ws": "^8.18.0",
56
- "zod": "^3.23.0"
42
+ "zod": "^3.23.0",
43
+ "@lovelybunch/mcp": "1.0.77-alpha.1",
44
+ "@lovelybunch/types": "1.0.77-alpha.1",
45
+ "@lovelybunch/core": "1.0.77-alpha.1"
57
46
  },
58
47
  "devDependencies": {
59
48
  "@types/adm-zip": "^0.5.7",
@@ -62,9 +51,22 @@
62
51
  "@types/jsonwebtoken": "^9.0.5",
63
52
  "@types/node": "^22.10.2",
64
53
  "@types/ws": "^8.5.13",
65
- "@vitest/coverage-v8": "^1.6.1",
54
+ "@vitest/coverage-v8": "4.1.1",
55
+ "@vitest/ui": "4.1.1",
66
56
  "tsx": "^4.19.2",
67
57
  "typescript": "^5.7.2",
68
- "vitest": "^4.0.5"
58
+ "vitest": "4.1.1"
59
+ },
60
+ "scripts": {
61
+ "dev": "NODE_ENV=development GAIT_DEV_ROOT=../../.nut tsx watch src/server.ts",
62
+ "build": "tsc -b",
63
+ "build:bundle": "tsc && node scripts/bundle-frontend.js",
64
+ "start": "node dist/server-with-static.js",
65
+ "start:dev": "node dist/server.js",
66
+ "clean": "rm -rf dist static tsconfig.tsbuildinfo coverage",
67
+ "test": "vitest run",
68
+ "test:coverage": "vitest run --coverage",
69
+ "test:watch": "vitest watch",
70
+ "test:ui": "vitest --ui"
69
71
  }
70
- }
72
+ }
@@ -1 +1 @@
1
- import{r as a,A as p,j as e,v,bK as y,B as N,n as w,C as b}from"./index-UXL5-kaP.js";import{C as c,a as d,b as k,c as C}from"./card-DPLdBoa5.js";import{B as m}from"./badge-vIqE5SOP.js";import{R as E}from"./refresh-cw-tXYl1ePu.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-0zkOcODK.js";import{C as c,a as d,b as k,c as C}from"./card-DW9yx9FC.js";import{B as m}from"./badge-DyF_7_dv.js";import{R as E}from"./refresh-cw-CYBx0C_n.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,a1 as N}from"./index-UXL5-kaP.js";import{C as m,a as x,b as C,c as S}from"./card-DPLdBoa5.js";import{M as w}from"./markdown-editor-DBdRsbP2.js";import{A as y}from"./arrow-left-DWmf9YJp.js";import{C as A}from"./circle-check-big-BEY1IoIP.js";import"./index-DnZKG-_7.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-0zkOcODK.js";import{C as m,a as x,b as C,c as S}from"./card-DW9yx9FC.js";import{M as w}from"./markdown-editor-C8LFQE7K.js";import{A as y}from"./arrow-left-DzGSl0dC.js";import{C as A}from"./circle-check-big--yqXPZzU.js";import"./index-xBQb0rMo.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
 
@@ -0,0 +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-0zkOcODK.js";import{C as i,a as c,b}from"./card-DW9yx9FC.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 z,r as t,bD as y,j as e,B as a,P as R,bE as X,H as J,D as j,b as g,d as v,f,g as A,I as F,Y as N,ae as W,w as i}from"./index-UXL5-kaP.js";import{C as G,b as Q,c as V,d as Z,a as _}from"./card-DPLdBoa5.js";import{L as w}from"./label-8VKluf9w.js";import{B as ee}from"./badge-vIqE5SOP.js";import{A as I,a as C}from"./alert-Dw_RSroN.js";import{I as L}from"./info-D-UNBNx2.js";import{C as se}from"./circle-alert-Mv00T-P2.js";function oe(){const{authEnabled:n}=z(),[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"}),Y=s=>s?new Date(s)<new Date:!1,$=typeof window<"u"?window.location.origin:"http://localhost:3000",q=c?`curl -H "X-API-Key: ${c.key}" \\
2
- + ${$}/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(G,{children:[e.jsx(Q,{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(R,{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(X,{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}),Y(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(W,{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:q})})]})]}),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
+ 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-0zkOcODK.js";import{C as W,b as G,c as V,d as Z,a as _}from"./card-DW9yx9FC.js";import{L as w}from"./label-DyhnItJm.js";import{B as ee}from"./badge-DyF_7_dv.js";import{A as I,a as C}from"./alert-DxBTp_In.js";import{I as L}from"./info-DWORrO-s.js";import{C as se}from"./circle-alert-ByPjREVD.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
+ + ${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};
@@ -0,0 +1,11 @@
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-0zkOcODK.js";import{C as m,b as g,c as j,d as p,a as v}from"./card-DW9yx9FC.js";import{L as c}from"./label-DyhnItJm.js";import{S as X,a as Z,b as ee,c as se,d as a}from"./select-D_L7OXwN.js";import{S as N}from"./switch-DXojpqQ8.js";import{B as F}from"./badge-DyF_7_dv.js";import{C as be}from"./circle-alert-ByPjREVD.js";import"./index-xBQb0rMo.js";import"./chevron-up-BrSqNhfU.js";/**
2
+ * @license lucide-react v0.542.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const Ae=[["path",{d:"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z",key:"1s6t7t"}],["circle",{cx:"16.5",cy:"7.5",r:".5",fill:"currentColor",key:"w0ekpg"}]],Ee=te("key-round",Ae);/**
7
+ * @license lucide-react v0.542.0 - ISC
8
+ *
9
+ * This source code is licensed under the ISC license.
10
+ * See the LICENSE file in the root directory of this source tree.
11
+ */const Ue=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]],ke=te("user-plus",Ue);function Je(){const{user:S,authEnabled:ie,checkAuthStatus:P}=me(),[t,h]=n.useState(null),[re,I]=n.useState(!0),[R,T]=n.useState(!1),[O,b]=n.useState(""),[A,L]=n.useState(!1),[ne,E]=n.useState(!1),[U,$]=n.useState(""),[k,J]=n.useState(""),[M,V]=n.useState("viewer"),[D,f]=n.useState(null),[w,y]=n.useState(""),ae=!ie||S?.role==="admin";n.useEffect(()=>{C()},[]);const C=async()=>{try{I(!0);const s=await l("/api/v1/auth-settings");s.success?(h(s.data),b(s.data?.providers?.oauth?.coconut?.clientId??"")):h(null)}catch(s){console.error("Failed to load auth settings:",s),h(null)}finally{I(!1)}},W=async s=>{const i=O.trim();if(s&&!i){r({title:"Client ID required",description:"Enter the Coconut OAuth client ID before enabling. Run `nut init --oauth-client-id <id>` if you don't have one yet.",variant:"destructive"});return}try{L(!0);const o=await l("/api/v1/auth-settings/oauth/coconut",{method:"PUT",body:JSON.stringify({enabled:s,clientId:i||void 0})});if(!o.success)throw new Error(o.error||"Failed to update Coconut OAuth");h(u=>u&&{...u,providers:{...u.providers,oauth:{...u.providers.oauth,coconut:o.data.coconut}}}),b(o.data.coconut?.clientId??""),await P(),r({title:"Success",description:`Coconut OAuth ${s?"enabled":"disabled"}`})}catch(o){r({title:"Error",description:o.message||"Failed to update Coconut OAuth",variant:"destructive"})}finally{L(!1)}},oe=async()=>{if(!t)return;const s=!t.enabled;try{const i=await l("/api/v1/auth-settings",{method:"PUT",body:JSON.stringify({enabled:s})});if(i.success)h({...t,enabled:s}),await P(),r({title:"Success",description:`Authentication ${s?"enabled":"disabled"}`});else throw new Error(i.error||"Failed to toggle auth")}catch(i){r({title:"Error",description:i.message||"Failed to toggle authentication",variant:"destructive"})}},ce=async()=>{if(!t)return;const s=!t.allowRegistration;try{const i=await l("/api/v1/auth-settings",{method:"PUT",body:JSON.stringify({allowRegistration:s})});if(i.success)h({...t,allowRegistration:s}),r({title:"Success",description:`Self-registration ${s?"enabled":"disabled"}`});else throw new Error(i.error||"Failed to update setting")}catch(i){r({title:"Error",description:i.message||"Failed to update setting",variant:"destructive"})}},le=async()=>{if(!U||!k){r({title:"Error",description:"Please provide email and name",variant:"destructive"});return}try{const s=await l("/api/v1/auth-settings/users",{method:"POST",body:JSON.stringify({email:U,name:k,role:M})});if(s.success)await C(),E(!1),$(""),J(""),V("viewer"),r({title:"Success",description:"User added to whitelist"});else throw new Error(s.error||"Failed to add user")}catch(s){r({title:"Error",description:s.message||"Failed to add user",variant:"destructive"})}},de=async s=>{try{const i=await l(`/api/v1/auth-settings/users/${s}`,{method:"DELETE"});if(i.success)await C(),r({title:"Success",description:"User removed from whitelist"});else throw new Error(i.error||"Failed to remove user")}catch(i){r({title:"Error",description:i.message||"Failed to remove user",variant:"destructive"})}},he=async(s,i)=>{try{const o=await l(`/api/v1/auth-settings/users/${s}`,{method:"PUT",body:JSON.stringify({role:i})});if(o.success)await C(),r({title:"Success",description:"User role updated"});else throw new Error(o.error||"Failed to update role")}catch(o){r({title:"Error",description:o.message||"Failed to update role",variant:"destructive"})}},ue=async()=>{if(!(!D||!w)){if(w.length<8){r({title:"Error",description:"Password must be at least 8 characters",variant:"destructive"});return}try{const s=await l(`/api/v1/auth-settings/users/${D}/reset-password`,{method:"POST",body:JSON.stringify({newPassword:w})});if(s.success)f(null),y(""),r({title:"Success",description:"Password reset successfully"});else throw new Error(s.error||"Failed to reset password")}catch(s){r({title:"Error",description:s.message||"Failed to reset password",variant:"destructive"})}}},xe=async()=>{if(t)try{T(!0);const s=await l("/api/v1/auth-settings",{method:"PUT",body:JSON.stringify({session:t.session})});if(s.success)r({title:"Success",description:"Session settings updated"});else throw new Error(s.error||"Failed to update settings")}catch(s){r({title:"Error",description:s.message||"Failed to update settings",variant:"destructive"})}finally{T(!1)}};return re?e.jsx("div",{children:"Loading..."}):t?ae?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage authentication settings and user access."})]}),e.jsx(_,{}),e.jsxs(m,{children:[e.jsxs(g,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(H,{className:"h-5 w-5"}),e.jsx(j,{children:"Authentication Status"})]}),e.jsx(p,{children:"Control whether authentication is required to access Coconut."})]}),e.jsxs(v,{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(c,{htmlFor:"auth-enabled",children:"Require Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"When enabled, users must log in to access Coconut"})]}),e.jsx(N,{id:"auth-enabled",checked:t.enabled,onCheckedChange:oe})]}),t.enabled&&e.jsxs("div",{className:"flex items-center justify-between pt-2 border-t",children:[e.jsxs("div",{children:[e.jsx(c,{htmlFor:"allow-registration",children:"Allow Self-Registration"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Whitelisted users can create their own accounts"})]}),e.jsx(N,{id:"allow-registration",checked:t.allowRegistration,onCheckedChange:ce})]})]})]}),e.jsxs(m,{children:[e.jsx(g,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(j,{children:"Whitelisted Users"}),e.jsx(p,{children:"Manage users who can access this Coconut instance."})]}),e.jsxs(q,{open:ne,onOpenChange:E,children:[e.jsx(z,{asChild:!0,children:e.jsxs(d,{size:"sm",children:[e.jsx(ke,{className:"h-4 w-4 mr-2"}),"Add User"]})}),e.jsxs(B,{children:[e.jsxs(Y,{children:[e.jsx(K,{children:"Add User to Whitelist"}),e.jsx(Q,{children:"Add a user's email to allow them to register and access Coconut."})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{children:[e.jsx(c,{htmlFor:"new-email",children:"Email"}),e.jsx(x,{id:"new-email",type:"email",value:U,onChange:s=>$(s.target.value),placeholder:"user@example.com"})]}),e.jsxs("div",{children:[e.jsx(c,{htmlFor:"new-name",children:"Name"}),e.jsx(x,{id:"new-name",value:k,onChange:s=>J(s.target.value),placeholder:"User Name"})]}),e.jsxs("div",{children:[e.jsx(c,{htmlFor:"new-role",children:"Role"}),e.jsxs(X,{value:M,onValueChange:s=>V(s),children:[e.jsx(Z,{children:e.jsx(ee,{})}),e.jsxs(se,{children:[e.jsx(a,{value:"viewer",children:"Viewer"}),e.jsx(a,{value:"engineer",children:"Engineer"}),e.jsx(a,{value:"designer",children:"Designer"}),e.jsx(a,{value:"product_manager",children:"Product Manager"}),e.jsx(a,{value:"manager",children:"Manager"}),e.jsx(a,{value:"admin",children:"Admin"})]})]})]})]}),e.jsxs(G,{children:[e.jsx(d,{variant:"outline",onClick:()=>E(!1),children:"Cancel"}),e.jsx(d,{onClick:le,children:"Add User"})]})]})]})]})}),e.jsx(v,{children:e.jsx("div",{className:"space-y-4",children:t.providers.local.users.map(s=>e.jsxs("div",{className:"flex items-center justify-between p-4 border rounded-lg",children:[e.jsxs("div",{className:"space-y-1 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("p",{className:"font-medium",children:s.name}),s.registered?e.jsx(F,{variant:"default",className:"text-xs",children:"Registered"}):e.jsx(F,{variant:"secondary",className:"text-xs",children:"Pending"}),s.id===S?.id&&e.jsx(F,{variant:"outline",className:"text-xs",children:"You"})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:s.email}),s.lastLoginAt&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Last login: ",new Date(s.lastLoginAt).toLocaleString()]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(X,{value:s.role,onValueChange:i=>he(s.id,i),children:[e.jsx(Z,{className:"w-40",children:e.jsx(ee,{})}),e.jsxs(se,{children:[e.jsx(a,{value:"viewer",children:"Viewer"}),e.jsx(a,{value:"engineer",children:"Engineer"}),e.jsx(a,{value:"designer",children:"Designer"}),e.jsx(a,{value:"product_manager",children:"Product Manager"}),e.jsx(a,{value:"manager",children:"Manager"}),e.jsx(a,{value:"admin",children:"Admin"})]})]}),e.jsxs(q,{open:D===s.id,onOpenChange:i=>{i||(f(null),y(""))},children:[e.jsx(z,{asChild:!0,children:e.jsx(d,{size:"sm",variant:"outline",onClick:()=>f(s.id),children:e.jsx(Ee,{className:"h-4 w-4"})})}),e.jsxs(B,{children:[e.jsxs(Y,{children:[e.jsx(K,{children:"Reset Password"}),e.jsxs(Q,{children:["Set a new password for ",s.name]})]}),e.jsx("div",{className:"space-y-4 py-4",children:e.jsxs("div",{children:[e.jsx(c,{htmlFor:"reset-password",children:"New Password"}),e.jsx(x,{id:"reset-password",type:"password",value:w,onChange:i=>y(i.target.value),placeholder:"At least 8 characters",minLength:8})]})}),e.jsxs(G,{children:[e.jsx(d,{variant:"outline",onClick:()=>{f(null),y("")},children:"Cancel"}),e.jsx(d,{onClick:ue,children:"Reset Password"})]})]})]}),s.id!==S?.id&&e.jsxs(ge,{children:[e.jsx(je,{asChild:!0,children:e.jsx(d,{size:"sm",variant:"destructive",children:e.jsx(pe,{className:"h-4 w-4"})})}),e.jsxs(ve,{children:[e.jsxs(fe,{children:[e.jsx(we,{children:"Remove User"}),e.jsxs(ye,{children:["Are you sure you want to remove ",s.name," from the whitelist? They will no longer be able to access Coconut."]})]}),e.jsxs(Ce,{children:[e.jsx(Ne,{children:"Cancel"}),e.jsx(Se,{onClick:()=>de(s.id),children:"Remove"})]})]})]})]})]},s.id))})})]}),e.jsxs(m,{children:[e.jsxs(g,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(H,{className:"h-5 w-5"}),e.jsx(j,{children:"Coconut OAuth"})]}),e.jsx(p,{children:'Allow users to sign in with their Coconut control-plane account. Presence of a client ID and the toggle below together determine whether "Continue with Coconut" is offered on the login page.'})]}),e.jsxs(v,{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(c,{htmlFor:"coconut-client-id",children:"Client ID"}),e.jsx(x,{id:"coconut-client-id",value:O,onChange:s=>b(s.target.value),placeholder:"Issued by the Coconut control plane"}),e.jsxs("p",{className:"text-sm text-muted-foreground mt-1",children:["Stored in ",e.jsx("code",{children:"auth.json"}),". Also settable at provisioning time via ",e.jsx("code",{children:"nut init --oauth-client-id <id>"}),"."]})]}),t.providers.oauth.coconut?.issuer&&e.jsxs("div",{className:"rounded-md bg-muted p-3 text-xs font-mono text-muted-foreground space-y-1",children:[e.jsxs("div",{children:["Issuer: ",t.providers.oauth.coconut.issuer]}),t.providers.oauth.coconut.jwksUrl&&e.jsxs("div",{children:["JWKS: ",t.providers.oauth.coconut.jwksUrl]})]}),e.jsxs("div",{className:"flex items-center justify-between pt-2 border-t",children:[e.jsxs("div",{children:[e.jsx(c,{htmlFor:"coconut-oauth-enabled",children:"Enable Coconut OAuth"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:'When enabled, users see a "Continue with Coconut" button on the login page. Takes effect immediately.'})]}),e.jsx(N,{id:"coconut-oauth-enabled",checked:t.providers.oauth.coconut?.enabled??!1,disabled:A,onCheckedChange:s=>W(s)})]}),e.jsx("div",{className:"flex justify-end",children:e.jsx(d,{variant:"outline",disabled:A,onClick:()=>W(t.providers.oauth.coconut?.enabled??!1),children:A?"Saving...":"Save Client ID"})})]})]}),e.jsxs(m,{children:[e.jsxs(g,{children:[e.jsx(j,{children:"Session Settings"}),e.jsx(p,{children:"Configure session behavior and security."})]}),e.jsxs(v,{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(c,{htmlFor:"session-expiry",children:"Session Expiry"}),e.jsx(x,{id:"session-expiry",value:t.session.expiresIn,onChange:s=>h({...t,session:{...t.session,expiresIn:s.target.value}}),placeholder:"7d"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"Format: 30s, 15m, 24h, 7d"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(c,{htmlFor:"secure-cookies",children:"Secure Cookies (HTTPS only)"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Enable in production with HTTPS"})]}),e.jsx(N,{id:"secure-cookies",checked:t.session.secure||!1,onCheckedChange:s=>h({...t,session:{...t.session,secure:s}})})]})]})]}),e.jsx("div",{className:"flex justify-end",children:e.jsx(d,{onClick:xe,disabled:R,children:R?"Saving...":"Save Session Settings"})})]}):e.jsx("div",{className:"space-y-6",children:e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"You don't have permission to manage authentication settings."})]})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-medium",children:"Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Secure your Coconut instance with authentication."})]}),e.jsx(_,{}),e.jsxs(m,{children:[e.jsxs(g,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(be,{className:"h-5 w-5 text-muted-foreground"}),e.jsx(j,{children:"Authentication Not Configured"})]}),e.jsx(p,{children:"Authentication has not been initialized. Use the CLI to set up authentication."})]}),e.jsxs(v,{children:[e.jsx("div",{className:"bg-muted p-4 rounded-md",children:e.jsxs("code",{className:"text-sm",children:["$ nut auth init",e.jsx("br",{}),"$ nut auth toggle"]})}),e.jsx("p",{className:"text-sm text-muted-foreground mt-4",children:"This will create an admin user and enable authentication for your Coconut instance."})]})]})]})}export{Je as default};
@@ -1 +1 @@
1
- import{r as m,j as e,v as x,A as f}from"./index-UXL5-kaP.js";import{C as w}from"./circle-check-xMiP6SLO.js";import{C as b}from"./circle-x-z3iynaE7.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-0zkOcODK.js";import{C as w}from"./circle-check-D7peX4CI.js";import{C as b}from"./circle-x-Oj6Gai3s.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};
@@ -0,0 +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-0zkOcODK.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.access_token)throw new Error("Clerk did not return an access_token");const m=await C("/api/v1/auth/oauth/exchange",{method:"POST",body:JSON.stringify({accessToken:n.access_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};