@lovelybunch/api 1.0.76-alpha.9 → 1.0.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/dist/lib/git.d.ts +3 -0
  2. package/dist/lib/git.js +35 -0
  3. package/dist/routes/api/v1/ai/route.js +214 -152
  4. package/dist/routes/api/v1/config/route.js +13 -9
  5. package/dist/routes/api/v1/context/agents/route.d.ts +3 -0
  6. package/dist/routes/api/v1/context/agents/route.js +159 -0
  7. package/dist/routes/api/v1/context/index.js +6 -4
  8. package/dist/routes/api/v1/context/memory/route.d.ts +3 -0
  9. package/dist/routes/api/v1/context/memory/route.js +163 -0
  10. package/dist/routes/api/v1/context/team/route.d.ts +3 -0
  11. package/dist/routes/api/v1/context/team/route.js +159 -0
  12. package/dist/routes/api/v1/git/index.js +27 -1
  13. package/dist/routes/api/v1/jobs/[id]/route.d.ts +26 -32
  14. package/dist/routes/api/v1/jobs/[id]/route.js +3 -3
  15. package/dist/routes/api/v1/jobs/route.d.ts +33 -33
  16. package/dist/routes/api/v1/jobs/route.js +17 -2
  17. package/dist/routes/api/v1/mcp/index.js +194 -21
  18. package/dist/routes/api/v1/resources/generate/route.js +10 -3
  19. package/package.json +4 -4
  20. package/static/assets/ActivityPage-sJEQn6DK.js +1 -0
  21. package/static/assets/AgentsContextEditPage-DU3qIXk9.js +9 -0
  22. package/static/assets/AgentsContextPage-tJ-LhFYb.js +1 -0
  23. package/static/assets/{ApiKeysSettingsPage-CjrCuHHE.js → ApiKeysSettingsPage-Bg84BQHV.js} +2 -2
  24. package/static/assets/{AuthSettingsPage-elJX4TCV.js → AuthSettingsPage-Bwr7uP3z.js} +1 -1
  25. package/static/assets/{CallbackPage-CUuZYgBL.js → CallbackPage-BFn0Np2S.js} +1 -1
  26. package/static/assets/CodePage-kp4s3wCJ.js +2 -0
  27. package/static/assets/{CollapsibleSection-DfTxWX0X.js → CollapsibleSection-CNs1mvsZ.js} +1 -1
  28. package/static/assets/{DashboardPage-CmS8UPSm.js → DashboardPage-DMJSzzgD.js} +9 -19
  29. package/static/assets/{GitPage-DSfn76oO.js → GitPage-uqene8zj.js} +3 -3
  30. package/static/assets/{GitSettingsPage-Bu8h7hcr.js → GitSettingsPage-CLswbZsT.js} +2 -2
  31. package/static/assets/{IdentityPage-NFKq2FHi.js → IdentityPage-BDTPXEo7.js} +2 -2
  32. package/static/assets/{ImplementationStepsEditor-Cn-MshnR.js → ImplementationStepsEditor-D4cvhPhz.js} +2 -2
  33. package/static/assets/IntegrationsSettingsPage-o7NXZGt9.js +1 -0
  34. package/static/assets/JobDetailPage-DuEiPz6X.js +1 -0
  35. package/static/assets/KnowledgeDetailPage-DFVud_VC.js +1 -0
  36. package/static/assets/{KnowledgeEditPage-B28N-7vM.js → KnowledgeEditPage-XG6HKK7E.js} +1 -1
  37. package/static/assets/{KnowledgePage-C3zoPEcH.js → KnowledgePage-B2zI3xwW.js} +2 -2
  38. package/static/assets/{LoginPage-BYNLGEnz.js → LoginPage-CUJRxwXy.js} +1 -1
  39. package/static/assets/MailInboxPage-BlCG-tba.js +1 -0
  40. package/static/assets/MailProcessingModal-BJIdHOqK.js +1 -0
  41. package/static/assets/MailReadPage-MoNo_gmW.js +1 -0
  42. package/static/assets/{MailSentPage-ClaVWZCR.js → MailSentPage-QzpuIJmT.js} +1 -1
  43. package/static/assets/{McpSettingsPage-CfhBioEH.js → McpSettingsPage-BZcCGkGM.js} +1 -1
  44. package/static/assets/MemoryEditPage-DXSQoCT4.js +13 -0
  45. package/static/assets/MemoryPage-oBnyuvSf.js +1 -0
  46. package/static/assets/{NewKnowledgePage-BUwh_DFd.js → NewKnowledgePage-deMsezK8.js} +1 -1
  47. package/static/assets/{NewSkillPage-B2rztwzD.js → NewSkillPage-DRYWdrlV.js} +1 -1
  48. package/static/assets/{NewTaskPage-Cvw20nug.js → NewTaskPage-B6xdic5_.js} +2 -2
  49. package/static/assets/{NotFoundPage-CXvLVHsT.js → NotFoundPage-Bxu9uKFO.js} +1 -1
  50. package/static/assets/{NotificationsSettingsPage-Df_GZ7_p.js → NotificationsSettingsPage-CLgtsCVM.js} +1 -1
  51. package/static/assets/{PromptsSettingsPage-QTxJgO5-.js → PromptsSettingsPage-BWaELCjG.js} +1 -1
  52. package/static/assets/{ResourceDetailPage-C9RHHVKu.js → ResourceDetailPage-CMPDRdVM.js} +1 -1
  53. package/static/assets/ResourcesPage-DspYILfG.js +41 -0
  54. package/static/assets/{RoleEditPage-N2-v2MXN.js → RoleEditPage-DXtzicVZ.js} +1 -1
  55. package/static/assets/{RolePage-Da0kZMUH.js → RolePage-DafGURGp.js} +1 -1
  56. package/static/assets/{RulesSettingsPage-CSd5iz22.js → RulesSettingsPage-E8V9cexV.js} +1 -1
  57. package/static/assets/RunDetailPage-DsxkqFst.js +1 -0
  58. package/static/assets/SchedulePage-B2YvNDHr.js +4 -0
  59. package/static/assets/{SkillDetailPage-QjqBAuFU.js → SkillDetailPage-CWkqSfuT.js} +1 -1
  60. package/static/assets/{SkillEditPage-BB0x4VVH.js → SkillEditPage-DwyebzFV.js} +1 -1
  61. package/static/assets/{SkillsPage-BMDNxMmZ.js → SkillsPage-CauK65X_.js} +2 -2
  62. package/static/assets/{SkillsSettingsPage-DcdeOlAl.js → SkillsSettingsPage-DXMRv3jR.js} +1 -1
  63. package/static/assets/{SourceInput-rc4KSqcv.js → SourceInput-C0iKqbQ1.js} +1 -1
  64. package/static/assets/{TagInput-bxFcAknC.js → TagInput-Ct-WRvTs.js} +1 -1
  65. package/static/assets/{TaskDetailPage-CAmREdfh.js → TaskDetailPage-CApk2iBh.js} +1 -1
  66. package/static/assets/{TaskEditPage-BDgZtG36.js → TaskEditPage-NgOVShfK.js} +1 -1
  67. package/static/assets/{TasksPage-BQ6eLw0T.js → TasksPage-BoPrP_Rl.js} +3 -3
  68. package/static/assets/TeamEditPage-ChY6mYm8.js +9 -0
  69. package/static/assets/TeamPage-DH-dJhFG.js +1 -0
  70. package/static/assets/{TerminalPage-BhWGRGf1.js → TerminalPage-CRhcscF2.js} +1 -1
  71. package/static/assets/{TerminalSessionPage-Bu-WiE0d.js → TerminalSessionPage-CSCQg2sn.js} +2 -2
  72. package/static/assets/{UserPreferencesPage-B_Tu1a8h.js → UserPreferencesPage-DxCSWJnS.js} +1 -1
  73. package/static/assets/{UserSettingsPage-BnEGtrGo.js → UserSettingsPage-DKkOLNPV.js} +1 -1
  74. package/static/assets/UtilitiesPage-CBNSvixW.js +1 -0
  75. package/static/assets/{alert-C42EBWiI.js → alert-Dw_RSroN.js} +1 -1
  76. package/static/assets/{arrow-down-CuFFg288.js → arrow-down-UClxXzT-.js} +1 -1
  77. package/static/assets/{arrow-left-C8VbyW3d.js → arrow-left-DWmf9YJp.js} +1 -1
  78. package/static/assets/{arrow-up-down-GN3qK2mU.js → arrow-up-down-Btc3okb3.js} +1 -1
  79. package/static/assets/{arrow-up-vC1c-5gW.js → arrow-up-fLCh7Hvh.js} +1 -1
  80. package/static/assets/{badge-CKwUSKzT.js → badge-vIqE5SOP.js} +1 -1
  81. package/static/assets/{browser-modal-C9VBJ_El.js → browser-modal-DgMJTsMd.js} +2 -2
  82. package/static/assets/{card-DRBgMGuU.js → card-DPLdBoa5.js} +1 -1
  83. package/static/assets/{chevron-left-2sP4ienq.js → chevron-left-CiNaLX-v.js} +1 -1
  84. package/static/assets/{chevron-up-DJfyvHso.js → chevron-up-DFd-7wxW.js} +1 -1
  85. package/static/assets/{chevrons-up-DfFpzHXf.js → chevrons-up-BfU70OcQ.js} +1 -1
  86. package/static/assets/{circle-alert-DP4rtmEK.js → circle-alert-Mv00T-P2.js} +1 -1
  87. package/static/assets/{circle-check-big-3mrGMFVn.js → circle-check-big-BEY1IoIP.js} +1 -1
  88. package/static/assets/{circle-check-Cnp-EoKX.js → circle-check-xMiP6SLO.js} +1 -1
  89. package/static/assets/{circle-play-7F5AVehH.js → circle-play-iZZwaGbV.js} +1 -1
  90. package/static/assets/{circle-x-DxbiyJ6w.js → circle-x-z3iynaE7.js} +1 -1
  91. package/static/assets/{clipboard-CQNR4_yT.js → clipboard-C8wZRPDH.js} +1 -1
  92. package/static/assets/{clock-DGw3R_UL.js → clock-C_9shc08.js} +1 -1
  93. package/static/assets/{code-DSNMK8tD.js → code-DH-sRhus.js} +1 -1
  94. package/static/assets/{download-BWL6PFiw.js → download-CE8b59ER.js} +1 -1
  95. package/static/assets/{external-link-BqUE-DMN.js → external-link-DPyKt8NE.js} +1 -1
  96. package/static/assets/{eye-BD57N1qQ.js → eye-BpGD-yoS.js} +1 -1
  97. package/static/assets/{folder-git-2-CW5Zi8Bm.js → folder-git-2-BIw4zbmy.js} +1 -1
  98. package/static/assets/globe-CUo7eHKN.js +6 -0
  99. package/static/assets/{index-CheR43vH.js → index-B07hel4U.js} +1 -1
  100. package/static/assets/{index-B0fLM-4F.js → index-BCwmQxLC.js} +1 -1
  101. package/static/assets/{index-DO47L-WG.js → index-BOKaM9K-.js} +1 -1
  102. package/static/assets/{index-EpelXypg.js → index-BaR4iUzg.js} +1 -1
  103. package/static/assets/index-BcCuKdbf.css +1 -0
  104. package/static/assets/{index-BG5vEV31.js → index-Bfb3OTwj.js} +1 -1
  105. package/static/assets/{index-CMQcknsg.js → index-Bkt1rQVV.js} +1 -1
  106. package/static/assets/{index-BmTTXfmk.js → index-C65b3D5_.js} +1 -1
  107. package/static/assets/{index-CXWGFCS-.js → index-CGbmjmEy.js} +1 -1
  108. package/static/assets/{index-BArpuuuE.js → index-CTouvf2d.js} +1 -1
  109. package/static/assets/{index-D4awulBm.js → index-Cdwx6Zps.js} +1 -1
  110. package/static/assets/{index-CMt1ExW-.js → index-ClO9-JVh.js} +1 -1
  111. package/static/assets/{index-CVVL2h9f.js → index-CpJ0uBf3.js} +1 -1
  112. package/static/assets/{index-B9OOTqx4.js → index-CsBxEWw5.js} +1 -1
  113. package/static/assets/{index-stPObw-o.js → index-DZAYfTI2.js} +1 -1
  114. package/static/assets/{index-X4fPPLHI.js → index-Dkr9CBL7.js} +1 -1
  115. package/static/assets/{index-Bedu89qc.js → index-DnZKG-_7.js} +1 -1
  116. package/static/assets/index-UXL5-kaP.js +497 -0
  117. package/static/assets/{index-uxv5vQZF.js → index-iB8oed57.js} +1 -1
  118. package/static/assets/{index-BWktaW8U.js → index-jaRIZ6SY.js} +1 -1
  119. package/static/assets/{info-DMJxIp7i.js → info-D-UNBNx2.js} +1 -1
  120. package/static/assets/{label-DxDedS8x.js → label-8VKluf9w.js} +1 -1
  121. package/static/assets/{markdown-editor-DJ2CscSp.js → markdown-editor-DBdRsbP2.js} +3 -3
  122. package/static/assets/{message-square-DF58cqKJ.js → message-square-CO8kDUed.js} +1 -1
  123. package/static/assets/{paperclip-CHyfSVll.js → paperclip-DlLXZbru.js} +1 -1
  124. package/static/assets/{pause-B-ouFhaQ.js → pause-zSiaxJBu.js} +1 -1
  125. package/static/assets/{play-B0y1weCV.js → play-DVBhRokt.js} +1 -1
  126. package/static/assets/{radio-group-DFNQiPDU.js → radio-group-CThYUcA4.js} +1 -1
  127. package/static/assets/{refresh-cw-5y5jTc6x.js → refresh-cw-tXYl1ePu.js} +1 -1
  128. package/static/assets/{search-B5deRThk.js → search-BxF7Wwex.js} +1 -1
  129. package/static/assets/{select-BzOa_wZx.js → select-CyHFRA1Y.js} +1 -1
  130. package/static/assets/server-lRxThHjr.js +6 -0
  131. package/static/assets/{switch-Bf2z8aaj.js → switch-BUpDbrux.js} +1 -1
  132. package/static/assets/{tabs-DkdBSep3.js → tabs-DkvCmQEX.js} +1 -1
  133. package/static/assets/{tag-gRsTk0jY.js → tag-CkcZNLnh.js} +1 -1
  134. package/static/assets/{terminal-preview-BfrUN2ok.js → terminal-preview-CLWDhoOZ.js} +1 -1
  135. package/static/assets/triangle-alert-CmjG_mbF.js +6 -0
  136. package/static/assets/{use-terminal-D6Qe1nwM.js → use-terminal-D3iV7-iC.js} +1 -1
  137. package/static/assets/{video-DXo9sCfT.js → video-CY_dOujm.js} +1 -1
  138. package/static/index.html +2 -2
  139. package/static/assets/ActivityPage-BaSoKgwZ.js +0 -1
  140. package/static/assets/ArchitectureEditPage-MYU7btLs.js +0 -21
  141. package/static/assets/ArchitecturePage-CGqWy8b1.js +0 -1
  142. package/static/assets/CodePage-C_bzfOnI.js +0 -2
  143. package/static/assets/IntegrationsSettingsPage-Cw6ItrNf.js +0 -1
  144. package/static/assets/JobDetailPage-DLSD4HiU.js +0 -1
  145. package/static/assets/KnowledgeDetailPage-DY8PpD9X.js +0 -1
  146. package/static/assets/MailInboxPage-DDYg0W70.js +0 -1
  147. package/static/assets/MailProcessingModal-CXIrtSz0.js +0 -6
  148. package/static/assets/MailReadPage-CVz6oD-y.js +0 -1
  149. package/static/assets/ProjectEditPage-DKf6ZoiG.js +0 -11
  150. package/static/assets/ProjectPage-CHhx9s1k.js +0 -1
  151. package/static/assets/ResourcesPage-BI8tfYZ2.js +0 -41
  152. package/static/assets/SchedulePage-CS8g2Db-.js +0 -4
  153. package/static/assets/UtilitiesPage-k7ABCAig.js +0 -1
  154. package/static/assets/index-Cht-fo9a.css +0 -1
  155. package/static/assets/index-DB2Tq9wz.js +0 -487
@@ -1,16 +1,16 @@
1
1
  import { Context } from 'hono';
2
- import { DayOfWeek, ScheduledJobSchedule, ScheduledJobStatus } from '@lovelybunch/types';
2
+ import { DayOfWeek, ScheduledJobRun, ScheduledJobRunMeta, ScheduledJobSchedule, ScheduledJobStatus } from '@lovelybunch/types';
3
3
  export declare function normalizeSchedule(schedule?: Partial<ScheduledJobSchedule>): ScheduledJobSchedule;
4
4
  export declare function normalizeStatus(status?: ScheduledJobStatus): ScheduledJobStatus;
5
+ export declare function toRunMeta(run: ScheduledJobRun): ScheduledJobRunMeta;
6
+ export declare function withLightweightRuns<T extends {
7
+ runs: ScheduledJobRun[];
8
+ }>(job: T): Omit<T, 'runs'> & {
9
+ runs: ScheduledJobRunMeta[];
10
+ };
5
11
  export declare function GET(c: Context): Promise<(Response & import("hono").TypedResponse<{
6
12
  success: true;
7
13
  data: {
8
- id: string;
9
- name: string;
10
- description?: string;
11
- prompt: string;
12
- model: string;
13
- status: ScheduledJobStatus;
14
14
  schedule: {
15
15
  type: "cron";
16
16
  expression: string;
@@ -23,29 +23,32 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
23
23
  timezone?: string;
24
24
  anchorHour?: number;
25
25
  };
26
+ description?: string;
27
+ id: string;
28
+ name: string;
29
+ prompt: string;
30
+ model: string;
31
+ status: ScheduledJobStatus;
26
32
  metadata: {
27
33
  createdAt: string;
28
34
  updatedAt: string;
29
35
  lastRunAt?: string;
30
36
  nextRunAt?: string;
31
37
  };
38
+ tags?: string[];
39
+ contextPaths?: string[];
40
+ agentId?: string;
41
+ agentIds?: string[];
42
+ mcpServers?: string[];
32
43
  runs: {
44
+ error?: string;
33
45
  id: string;
46
+ status: import("@lovelybunch/types").ScheduledJobRunStatus;
34
47
  jobId: string;
35
48
  trigger: import("@lovelybunch/types").ScheduledJobTrigger;
36
- status: import("@lovelybunch/types").ScheduledJobRunStatus;
37
49
  startedAt: string;
38
50
  finishedAt?: string;
39
- outputPath?: string;
40
- summary?: string;
41
- error?: string;
42
- cliCommand?: string;
43
51
  }[];
44
- tags?: string[];
45
- contextPaths?: string[];
46
- agentId?: string;
47
- agentIds?: string[];
48
- mcpServers?: string[];
49
52
  }[];
50
53
  }, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
51
54
  success: false;
@@ -63,12 +66,6 @@ export declare function POST(c: Context): Promise<(Response & import("hono").Typ
63
66
  }, 400, "json">) | (Response & import("hono").TypedResponse<{
64
67
  success: true;
65
68
  data: {
66
- id: string;
67
- name: string;
68
- description?: string;
69
- prompt: string;
70
- model: string;
71
- status: ScheduledJobStatus;
72
69
  schedule: {
73
70
  type: "cron";
74
71
  expression: string;
@@ -81,29 +78,32 @@ export declare function POST(c: Context): Promise<(Response & import("hono").Typ
81
78
  timezone?: string;
82
79
  anchorHour?: number;
83
80
  };
81
+ description?: string;
82
+ id: string;
83
+ name: string;
84
+ prompt: string;
85
+ model: string;
86
+ status: ScheduledJobStatus;
84
87
  metadata: {
85
88
  createdAt: string;
86
89
  updatedAt: string;
87
90
  lastRunAt?: string;
88
91
  nextRunAt?: string;
89
92
  };
93
+ tags?: string[];
94
+ contextPaths?: string[];
95
+ agentId?: string;
96
+ agentIds?: string[];
97
+ mcpServers?: string[];
90
98
  runs: {
99
+ error?: string;
91
100
  id: string;
101
+ status: import("@lovelybunch/types").ScheduledJobRunStatus;
92
102
  jobId: string;
93
103
  trigger: import("@lovelybunch/types").ScheduledJobTrigger;
94
- status: import("@lovelybunch/types").ScheduledJobRunStatus;
95
104
  startedAt: string;
96
105
  finishedAt?: string;
97
- outputPath?: string;
98
- summary?: string;
99
- error?: string;
100
- cliCommand?: string;
101
106
  }[];
102
- tags?: string[];
103
- contextPaths?: string[];
104
- agentId?: string;
105
- agentIds?: string[];
106
- mcpServers?: string[];
107
107
  };
108
108
  }, 201, "json">) | (Response & import("hono").TypedResponse<{
109
109
  success: false;
@@ -58,12 +58,27 @@ export function normalizeSchedule(schedule) {
58
58
  export function normalizeStatus(status) {
59
59
  return status === 'active' ? 'active' : 'paused';
60
60
  }
61
+ export function toRunMeta(run) {
62
+ return {
63
+ id: run.id,
64
+ jobId: run.jobId,
65
+ trigger: run.trigger,
66
+ status: run.status,
67
+ startedAt: run.startedAt,
68
+ finishedAt: run.finishedAt,
69
+ error: run.error,
70
+ };
71
+ }
72
+ export function withLightweightRuns(job) {
73
+ const { runs, ...rest } = job;
74
+ return { ...rest, runs: runs.map(toRunMeta) };
75
+ }
61
76
  export async function GET(c) {
62
77
  try {
63
78
  const jobs = await store.listJobs();
64
79
  return c.json({
65
80
  success: true,
66
- data: jobs
81
+ data: jobs.map(withLightweightRuns)
67
82
  });
68
83
  }
69
84
  catch (error) {
@@ -131,7 +146,7 @@ export async function POST(c) {
131
146
  const created = await store.getJob(job.id);
132
147
  return c.json({
133
148
  success: true,
134
- data: created ?? job
149
+ data: withLightweightRuns(created ?? job)
135
150
  }, 201);
136
151
  }
137
152
  catch (error) {
@@ -3,10 +3,36 @@ import { promises as fs } from 'fs';
3
3
  import path from 'path';
4
4
  import { ZodError } from 'zod';
5
5
  import { listTasks, getTask, createTask, updateTask, deleteTask, getContext, updateContext, appendContext, replaceContextSection, listKnowledge, getKnowledge, createKnowledge, updateKnowledge, listEvents, } from '@lovelybunch/core';
6
- import { tasksFullTool, knowledgeTool, normalizeKnowledgeMetadata, eventsTool, projectContextTool, architectureContextTool, roleContextTool, resourcesTool } from '@lovelybunch/mcp';
6
+ import { tasksFullTool, knowledgeTool, normalizeKnowledgeMetadata, eventsTool, roleContextTool, agentsContextTool, teamContextTool, memoryContextTool, resourcesTool, listConnectorsTool, connectorRequestTool, resolveConnectorUrl } from '@lovelybunch/mcp';
7
7
  import { FileStorageAdapter } from '../../../../lib/storage/file-storage.js';
8
+ import { homedir } from 'os';
9
+ import { readFileSync, existsSync } from 'fs';
8
10
  const app = new Hono();
9
11
  const storage = new FileStorageAdapter();
12
+ const COCONUT_HOST = 'https://app.coconut.dev';
13
+ function getCallbackToken() {
14
+ try {
15
+ const platform = process.platform;
16
+ let configDir;
17
+ if (platform === 'win32') {
18
+ configDir = path.join(process.env.APPDATA || homedir(), 'coconuts');
19
+ }
20
+ else if (platform === 'darwin') {
21
+ configDir = path.join(homedir(), 'Library', 'Application Support', 'coconuts');
22
+ }
23
+ else {
24
+ configDir = path.join(process.env.XDG_CONFIG_HOME || path.join(homedir(), '.config'), 'coconuts');
25
+ }
26
+ const configFile = path.join(configDir, 'config.json');
27
+ if (!existsSync(configFile))
28
+ return null;
29
+ const config = JSON.parse(readFileSync(configFile, 'utf-8'));
30
+ return config.apiKeys?.callbackToken || null;
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ }
10
36
  function resolveGaitPath() {
11
37
  let basePath;
12
38
  if (process.env.NODE_ENV === 'development' && process.env.GAIT_DEV_ROOT) {
@@ -78,15 +104,18 @@ app.get('/', async (c) => {
78
104
  }
79
105
  const names = Object.keys(externalServers);
80
106
  // Add built-in tools (include full JSON schema for parameters)
81
- // Note: tasks now supports full CRUD, knowledge/project/architecture are read+write, events is read-only
107
+ // Note: tasks now supports full CRUD, knowledge/context tools are read+write, events is read-only
82
108
  const builtInTools = {
83
109
  tasks: tasksFullTool,
84
110
  knowledge_documents: knowledgeTool,
85
111
  activity_events: eventsTool,
86
- project_context: projectContextTool,
87
- architecture_context: architectureContextTool,
88
112
  role_context: roleContextTool,
89
- resources: resourcesTool
113
+ agents_context: agentsContextTool,
114
+ team_context: teamContextTool,
115
+ memory_context: memoryContextTool,
116
+ resources: resourcesTool,
117
+ list_connectors: listConnectorsTool,
118
+ connector_request: connectorRequestTool
90
119
  };
91
120
  return c.json({
92
121
  success: true,
@@ -106,16 +135,19 @@ app.get('/', async (c) => {
106
135
  */
107
136
  app.get('/schema', async (c) => {
108
137
  try {
109
- // Note: tasks now supports full CRUD, knowledge/project/architecture are read+write, events is read-only
138
+ // Note: tasks now supports full CRUD, knowledge/context tools are read+write, events is read-only
110
139
  const schema = {
111
140
  tools: {
112
141
  tasks: tasksFullTool,
113
142
  knowledge_documents: knowledgeTool,
114
143
  activity_events: eventsTool,
115
- project_context: projectContextTool,
116
- architecture_context: architectureContextTool,
117
144
  role_context: roleContextTool,
118
- resources: resourcesTool
145
+ agents_context: agentsContextTool,
146
+ team_context: teamContextTool,
147
+ memory_context: memoryContextTool,
148
+ resources: resourcesTool,
149
+ list_connectors: listConnectorsTool,
150
+ connector_request: connectorRequestTool
119
151
  }
120
152
  };
121
153
  return c.json(schema);
@@ -144,18 +176,27 @@ app.post('/execute', async (c) => {
144
176
  if (tool === 'activity_events') {
145
177
  return await executeEventsTool(c, args);
146
178
  }
147
- if (tool === 'project_context') {
148
- return await executeProjectContextTool(c, args);
149
- }
150
- if (tool === 'architecture_context') {
151
- return await executeArchitectureContextTool(c, args);
152
- }
153
179
  if (tool === 'role_context') {
154
180
  return await executeRoleContextTool(c, args);
155
181
  }
182
+ if (tool === 'agents_context') {
183
+ return await executeAgentsContextTool(c, args);
184
+ }
185
+ if (tool === 'team_context') {
186
+ return await executeTeamContextTool(c, args);
187
+ }
188
+ if (tool === 'memory_context') {
189
+ return await executeMemoryContextTool(c, args);
190
+ }
156
191
  if (tool === 'resources') {
157
192
  return await executeResourcesTool(c, args);
158
193
  }
194
+ if (tool === 'list_connectors') {
195
+ return await executeListConnectorsTool(c);
196
+ }
197
+ if (tool === 'connector_request') {
198
+ return await executeConnectorRequestTool(c, args);
199
+ }
159
200
  return c.json({ success: false, error: 'Unknown tool' }, 400);
160
201
  }
161
202
  catch (error) {
@@ -446,15 +487,18 @@ async function executeContextTool(c, contextType, args) {
446
487
  }
447
488
  }
448
489
  // Wrapper functions for each context type (maintain API compatibility)
449
- async function executeProjectContextTool(c, args) {
450
- return executeContextTool(c, 'project', args);
451
- }
452
- async function executeArchitectureContextTool(c, args) {
453
- return executeContextTool(c, 'architecture', args);
454
- }
455
490
  async function executeRoleContextTool(c, args) {
456
491
  return executeContextTool(c, 'role', args);
457
492
  }
493
+ async function executeAgentsContextTool(c, args) {
494
+ return executeContextTool(c, 'agents', args);
495
+ }
496
+ async function executeTeamContextTool(c, args) {
497
+ return executeContextTool(c, 'team', args);
498
+ }
499
+ async function executeMemoryContextTool(c, args) {
500
+ return executeContextTool(c, 'memory', args);
501
+ }
458
502
  // Resources tool executor — proxies to the resource API endpoints on the same server
459
503
  async function executeResourcesTool(c, args) {
460
504
  const { operation, query, type_filter, resource_id, prompt, model, aspect_ratio, text, voice, duration, resolution, url, tags, description } = args;
@@ -525,6 +569,135 @@ async function executeResourcesTool(c, args) {
525
569
  return c.json({ success: false, error: error.message || 'Resources tool execution failed' }, 500);
526
570
  }
527
571
  }
572
+ async function executeListConnectorsTool(c) {
573
+ const token = getCallbackToken();
574
+ if (!token) {
575
+ return c.json({
576
+ success: false,
577
+ error: 'Callback token not configured. Set it via PUT /api/v1/config?type=global with { "apiKeys": { "callbackToken": "cpt_xxx" } }'
578
+ }, 400);
579
+ }
580
+ try {
581
+ const res = await fetch(`${COCONUT_HOST}/api/connectors/accounts`, {
582
+ headers: { 'X-Callback-Token': token }
583
+ });
584
+ if (!res.ok) {
585
+ const body = await res.text().catch(() => '');
586
+ return c.json({
587
+ success: false,
588
+ error: `Control plane returned ${res.status}: ${body || res.statusText}`
589
+ }, res.status >= 500 ? 502 : 400);
590
+ }
591
+ const data = await res.json();
592
+ const accounts = Array.isArray(data) ? data : (data.accounts ?? data.data ?? []);
593
+ return c.json({
594
+ success: true,
595
+ data: accounts,
596
+ count: accounts.length,
597
+ message: `Found ${accounts.length} connected service${accounts.length === 1 ? '' : 's'}`
598
+ });
599
+ }
600
+ catch (error) {
601
+ console.error('Error listing connectors:', error);
602
+ return c.json({ success: false, error: error.message || 'Failed to list connectors' }, 500);
603
+ }
604
+ }
605
+ async function executeConnectorRequestTool(c, args) {
606
+ const { app: appSlug, method, path: apiPath, body, headers: extraHeaders } = args;
607
+ if (!appSlug || !method || !apiPath) {
608
+ return c.json({ success: false, error: 'app, method, and path are required' }, 400);
609
+ }
610
+ const token = getCallbackToken();
611
+ if (!token) {
612
+ return c.json({
613
+ success: false,
614
+ error: 'Callback token not configured. Set it via PUT /api/v1/config?type=global with { "apiKeys": { "callbackToken": "cpt_xxx" } }'
615
+ }, 400);
616
+ }
617
+ try {
618
+ const accounts = await fetchConnectorAccounts(token);
619
+ const account = accounts.find((a) => a.appSlug === appSlug || a.appName?.toLowerCase() === appSlug.toLowerCase());
620
+ if (!account) {
621
+ return c.json({
622
+ success: false,
623
+ error: `No connected account found for "${appSlug}"`,
624
+ available: accounts.map((a) => a.appSlug || a.appName)
625
+ }, 404);
626
+ }
627
+ const url = resolveConnectorUrl(appSlug, apiPath);
628
+ if (!url) {
629
+ return c.json({
630
+ success: false,
631
+ error: `Unknown app "${appSlug}" and path is not a full URL. Use a full URL (https://...) or a known app slug.`
632
+ }, 400);
633
+ }
634
+ let parsedBody = undefined;
635
+ if (body) {
636
+ try {
637
+ parsedBody = typeof body === 'string' ? JSON.parse(body) : body;
638
+ }
639
+ catch {
640
+ return c.json({ success: false, error: 'Invalid JSON in body parameter' }, 400);
641
+ }
642
+ }
643
+ let parsedHeaders = {};
644
+ if (extraHeaders) {
645
+ try {
646
+ parsedHeaders = typeof extraHeaders === 'string' ? JSON.parse(extraHeaders) : extraHeaders;
647
+ }
648
+ catch {
649
+ return c.json({ success: false, error: 'Invalid JSON in headers parameter' }, 400);
650
+ }
651
+ }
652
+ const proxyPayload = {
653
+ accountId: account.accountId,
654
+ url,
655
+ method: method.toUpperCase()
656
+ };
657
+ if (parsedBody !== undefined)
658
+ proxyPayload.body = parsedBody;
659
+ if (Object.keys(parsedHeaders).length > 0)
660
+ proxyPayload.headers = parsedHeaders;
661
+ const proxyRes = await fetch(`${COCONUT_HOST}/api/connectors/proxy`, {
662
+ method: 'POST',
663
+ headers: {
664
+ 'Content-Type': 'application/json',
665
+ 'X-Callback-Token': token
666
+ },
667
+ body: JSON.stringify(proxyPayload)
668
+ });
669
+ if (!proxyRes.ok) {
670
+ const errBody = await proxyRes.text().catch(() => '');
671
+ return c.json({
672
+ success: false,
673
+ error: `Proxy request failed (${proxyRes.status}): ${errBody || proxyRes.statusText}`
674
+ }, proxyRes.status >= 500 ? 502 : 400);
675
+ }
676
+ const responseData = await proxyRes.json().catch(async () => {
677
+ return await proxyRes.text().catch(() => null);
678
+ });
679
+ return c.json({
680
+ success: true,
681
+ data: responseData,
682
+ message: `${method.toUpperCase()} ${apiPath} via ${appSlug}`
683
+ });
684
+ }
685
+ catch (error) {
686
+ console.error('Error executing connector request:', error);
687
+ return c.json({ success: false, error: error.message || 'Connector request failed' }, 500);
688
+ }
689
+ }
690
+ async function fetchConnectorAccounts(token) {
691
+ const res = await fetch(`${COCONUT_HOST}/api/connectors/accounts`, {
692
+ headers: { 'X-Callback-Token': token }
693
+ });
694
+ if (!res.ok) {
695
+ const body = await res.text().catch(() => '');
696
+ throw new Error(`Failed to fetch accounts (${res.status}): ${body || res.statusText}`);
697
+ }
698
+ const data = await res.json();
699
+ return Array.isArray(data) ? data : (data.accounts ?? data.data ?? []);
700
+ }
528
701
  /**
529
702
  * GET /api/v1/mcp/raw-config
530
703
  * Returns the raw MCP configuration for editing in settings UI
@@ -70,6 +70,7 @@ const THUMBNAILS_DIR = path.join(RESOURCES_DIR, 'thumbnails');
70
70
  // Model ID mapping from frontend values to Replicate model identifiers
71
71
  const MODEL_ID_MAP = {
72
72
  'nano-banana-pro': 'google/nano-banana-pro',
73
+ 'nano-banana-2': 'google/nano-banana-2',
73
74
  'flux-2-dev': 'black-forest-labs/flux-2-dev',
74
75
  'flux-2-pro': 'black-forest-labs/flux-2-pro',
75
76
  'gpt-image-1.5': 'openai/gpt-image-1.5',
@@ -135,7 +136,7 @@ export async function POST(c) {
135
136
  }, 400);
136
137
  }
137
138
  const body = await c.req.json();
138
- const { prompt, model = 'nano-banana-pro', dimensions, resolution, output_format = 'png', output_quality, quality, go_fast, safety_tolerance, background, image_input,
139
+ const { prompt, model = 'nano-banana-2', dimensions, resolution, output_format = 'png', output_quality, quality, go_fast, safety_tolerance, background, image_input,
139
140
  // Legacy
140
141
  inspiration } = body;
141
142
  if (!prompt) {
@@ -215,7 +216,7 @@ export async function POST(c) {
215
216
  }
216
217
  }
217
218
  // Map model selector value to Replicate model ID
218
- const replicateModelId = MODEL_ID_MAP[model] || MODEL_ID_MAP['nano-banana-pro'];
219
+ const replicateModelId = MODEL_ID_MAP[model] || MODEL_ID_MAP['nano-banana-2'];
219
220
  // Build model-specific input payload
220
221
  const input = {
221
222
  prompt: fullPrompt,
@@ -233,7 +234,13 @@ export async function POST(c) {
233
234
  }
234
235
  // Model-specific parameters
235
236
  if (model === 'nano-banana-pro' || model === 'Nano Banana Pro') {
236
- // Nano Banana Pro specific settings
237
+ input.resolution = resolution || '2K';
238
+ input.safety_filter_level = 'block_only_high';
239
+ if (imageInputArray.length > 0) {
240
+ input.image_input = imageInputArray;
241
+ }
242
+ }
243
+ else if (model === 'nano-banana-2') {
237
244
  input.resolution = resolution || '2K';
238
245
  input.safety_filter_level = 'block_only_high';
239
246
  if (imageInputArray.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovelybunch/api",
3
- "version": "1.0.76-alpha.9",
3
+ "version": "1.0.76",
4
4
  "type": "module",
5
5
  "main": "dist/server-with-static.js",
6
6
  "exports": {
@@ -37,9 +37,9 @@
37
37
  "@ai-sdk/anthropic": "^3.0.41",
38
38
  "@hono/node-server": "^1.13.7",
39
39
  "@hono/node-ws": "^1.0.6",
40
- "@lovelybunch/core": "^1.0.76-alpha.9",
41
- "@lovelybunch/mcp": "^1.0.76-alpha.9",
42
- "@lovelybunch/types": "^1.0.76-alpha.9",
40
+ "@lovelybunch/core": "^1.0.76",
41
+ "@lovelybunch/mcp": "^1.0.76",
42
+ "@lovelybunch/types": "^1.0.76",
43
43
  "adm-zip": "^0.5.16",
44
44
  "ai": "^6.0.79",
45
45
  "bcryptjs": "^2.4.3",
@@ -0,0 +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};
@@ -0,0 +1,9 @@
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...
2
+
3
+ ## Agent Definitions
4
+
5
+ Describe agents, their capabilities, and configurations.
6
+
7
+ ## Agent Guidelines
8
+
9
+ Key guidelines for agent behavior and interaction patterns.`,height:800})})]})]})}export{F as default};
@@ -0,0 +1 @@
1
+ import{a as g,r as t,A as N,j as e,v,av as C,B as a,L as d,_ as l,M as w,au as y,aq as E}from"./index-UXL5-kaP.js";import{C as i,a as c,b}from"./card-DPLdBoa5.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{s as R,r as t,bw as y,j as e,B as a,P as W,bx as X,E as Y,D as j,b as g,d as v,f,g as A,I as F,W as N,ae as J,v as i}from"./index-DB2Tq9wz.js";import{C as G,b as Q,c as V,d as Z,a as _}from"./card-DRBgMGuU.js";import{L as w}from"./label-DxDedS8x.js";import{B as ee}from"./badge-CKwUSKzT.js";import{A as I,a as C}from"./alert-C42EBWiI.js";import{I as L}from"./info-DMJxIp7i.js";import{C as se}from"./circle-alert-DP4rtmEK.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(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(W,{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}),$(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(Y,{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(J,{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
+ 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,4 +1,4 @@
1
- import{c as Y,s as le,r as n,bw as c,j as e,bv as O,i as ce,D as I,V as M,B as l,b as V,d as $,f as H,g as J,I as j,W as z,y as oe,z as de,E as he,H as ue,J as xe,N as me,O as ge,Q as je,R as pe,U as ve,v as r}from"./index-DB2Tq9wz.js";import{C as p,b as v,c as w,d as f,a as y}from"./card-DRBgMGuU.js";import{L as o}from"./label-DxDedS8x.js";import{S as _,a as W,b as q,c as B,d as a}from"./select-BzOa_wZx.js";import{S as U}from"./switch-Bf2z8aaj.js";import{B as k}from"./badge-CKwUSKzT.js";import{C as we}from"./circle-alert-DP4rtmEK.js";import"./index-Bedu89qc.js";import"./chevron-up-DJfyvHso.js";/**
1
+ import{c as Y,t as le,r as n,bD as c,j as e,bx as O,i as ce,D as I,W as M,B as l,b as V,d as $,f as H,g as J,I as j,Y as z,z as oe,E as de,H as he,J as ue,N as xe,O as me,Q as ge,R as je,U as pe,V as ve,w as r}from"./index-UXL5-kaP.js";import{C as p,b as v,c as w,d as f,a as y}from"./card-DPLdBoa5.js";import{L as o}from"./label-8VKluf9w.js";import{S as _,a as W,b as q,c as B,d as a}from"./select-CyHFRA1Y.js";import{S as U}from"./switch-BUpDbrux.js";import{B as k}from"./badge-vIqE5SOP.js";import{C as we}from"./circle-alert-Mv00T-P2.js";import"./index-DnZKG-_7.js";import"./chevron-up-DFd-7wxW.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,t as x,A as f}from"./index-DB2Tq9wz.js";import{C as w}from"./circle-check-Cnp-EoKX.js";import{C as b}from"./circle-x-DxbiyJ6w.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 v=()=>{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{v as default};
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};