@contractspec/integration.providers-impls 1.56.1 → 1.58.0

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 (238) hide show
  1. package/README.md +115 -1
  2. package/dist/analytics.d.ts +2 -0
  3. package/dist/analytics.d.ts.map +1 -0
  4. package/dist/analytics.js +3 -0
  5. package/dist/calendar.d.ts +1 -7
  6. package/dist/calendar.d.ts.map +1 -1
  7. package/dist/calendar.js +3 -3
  8. package/dist/database.d.ts +2 -0
  9. package/dist/database.d.ts.map +1 -0
  10. package/dist/database.js +3 -0
  11. package/dist/email.d.ts +1 -7
  12. package/dist/email.d.ts.map +1 -1
  13. package/dist/email.js +3 -3
  14. package/dist/embedding.d.ts +1 -7
  15. package/dist/embedding.d.ts.map +1 -1
  16. package/dist/embedding.js +3 -3
  17. package/dist/impls/elevenlabs-voice.d.ts +14 -18
  18. package/dist/impls/elevenlabs-voice.d.ts.map +1 -1
  19. package/dist/impls/elevenlabs-voice.js +98 -88
  20. package/dist/impls/fal-voice.d.ts +25 -0
  21. package/dist/impls/fal-voice.d.ts.map +1 -0
  22. package/dist/impls/fal-voice.js +113 -0
  23. package/dist/impls/fathom-meeting-recorder.d.ts +38 -0
  24. package/dist/impls/fathom-meeting-recorder.d.ts.map +1 -0
  25. package/dist/impls/fathom-meeting-recorder.js +288 -0
  26. package/dist/impls/fathom-meeting-recorder.mapper.d.ts +5 -0
  27. package/dist/impls/fathom-meeting-recorder.mapper.d.ts.map +1 -0
  28. package/dist/impls/fathom-meeting-recorder.mapper.js +106 -0
  29. package/dist/impls/fathom-meeting-recorder.types.d.ts +20 -0
  30. package/dist/impls/fathom-meeting-recorder.types.d.ts.map +1 -0
  31. package/dist/impls/fathom-meeting-recorder.types.js +1 -0
  32. package/dist/impls/fathom-meeting-recorder.utils.d.ts +11 -0
  33. package/dist/impls/fathom-meeting-recorder.utils.d.ts.map +1 -0
  34. package/dist/impls/fathom-meeting-recorder.utils.js +73 -0
  35. package/dist/impls/fathom-meeting-recorder.webhooks.d.ts +4 -0
  36. package/dist/impls/fathom-meeting-recorder.webhooks.d.ts.map +1 -0
  37. package/dist/impls/fathom-meeting-recorder.webhooks.js +30 -0
  38. package/dist/impls/fireflies-meeting-recorder.d.ts +24 -0
  39. package/dist/impls/fireflies-meeting-recorder.d.ts.map +1 -0
  40. package/dist/impls/fireflies-meeting-recorder.js +275 -0
  41. package/dist/impls/fireflies-meeting-recorder.queries.d.ts +4 -0
  42. package/dist/impls/fireflies-meeting-recorder.queries.d.ts.map +1 -0
  43. package/dist/impls/fireflies-meeting-recorder.queries.js +86 -0
  44. package/dist/impls/fireflies-meeting-recorder.types.d.ts +32 -0
  45. package/dist/impls/fireflies-meeting-recorder.types.d.ts.map +1 -0
  46. package/dist/impls/fireflies-meeting-recorder.types.js +1 -0
  47. package/dist/impls/fireflies-meeting-recorder.utils.d.ts +5 -0
  48. package/dist/impls/fireflies-meeting-recorder.utils.d.ts.map +1 -0
  49. package/dist/impls/fireflies-meeting-recorder.utils.js +43 -0
  50. package/dist/impls/gcs-storage.d.ts +18 -22
  51. package/dist/impls/gcs-storage.d.ts.map +1 -1
  52. package/dist/impls/gcs-storage.js +92 -84
  53. package/dist/impls/gmail-inbound.d.ts +20 -24
  54. package/dist/impls/gmail-inbound.d.ts.map +1 -1
  55. package/dist/impls/gmail-inbound.js +212 -185
  56. package/dist/impls/gmail-outbound.d.ts +12 -16
  57. package/dist/impls/gmail-outbound.d.ts.map +1 -1
  58. package/dist/impls/gmail-outbound.js +126 -92
  59. package/dist/impls/google-calendar.d.ts +17 -21
  60. package/dist/impls/google-calendar.d.ts.map +1 -1
  61. package/dist/impls/google-calendar.js +182 -145
  62. package/dist/impls/gradium-voice.d.ts +24 -0
  63. package/dist/impls/gradium-voice.d.ts.map +1 -0
  64. package/dist/impls/gradium-voice.js +91 -0
  65. package/dist/impls/granola-meeting-recorder.d.ts +34 -0
  66. package/dist/impls/granola-meeting-recorder.d.ts.map +1 -0
  67. package/dist/impls/granola-meeting-recorder.js +513 -0
  68. package/dist/impls/granola-meeting-recorder.mcp.d.ts +25 -0
  69. package/dist/impls/granola-meeting-recorder.mcp.d.ts.map +1 -0
  70. package/dist/impls/granola-meeting-recorder.mcp.js +279 -0
  71. package/dist/impls/granola-meeting-recorder.types.d.ts +61 -0
  72. package/dist/impls/granola-meeting-recorder.types.d.ts.map +1 -0
  73. package/dist/impls/granola-meeting-recorder.types.js +1 -0
  74. package/dist/impls/index.d.ts +28 -15
  75. package/dist/impls/index.d.ts.map +1 -0
  76. package/dist/impls/index.js +4659 -16
  77. package/dist/impls/jira.d.ts +21 -0
  78. package/dist/impls/jira.d.ts.map +1 -0
  79. package/dist/impls/jira.js +125 -0
  80. package/dist/impls/linear.d.ts +20 -0
  81. package/dist/impls/linear.d.ts.map +1 -0
  82. package/dist/impls/linear.js +84 -0
  83. package/dist/impls/mistral-embedding.d.ts +17 -21
  84. package/dist/impls/mistral-embedding.d.ts.map +1 -1
  85. package/dist/impls/mistral-embedding.js +41 -39
  86. package/dist/impls/mistral-llm.d.ts +25 -29
  87. package/dist/impls/mistral-llm.d.ts.map +1 -1
  88. package/dist/impls/mistral-llm.js +266 -244
  89. package/dist/impls/notion.d.ts +23 -0
  90. package/dist/impls/notion.d.ts.map +1 -0
  91. package/dist/impls/notion.js +161 -0
  92. package/dist/impls/posthog-reader.d.ts +22 -0
  93. package/dist/impls/posthog-reader.d.ts.map +1 -0
  94. package/dist/impls/posthog-reader.js +160 -0
  95. package/dist/impls/posthog-utils.d.ts +5 -0
  96. package/dist/impls/posthog-utils.d.ts.map +1 -0
  97. package/dist/impls/posthog-utils.js +39 -0
  98. package/dist/impls/posthog.d.ts +36 -0
  99. package/dist/impls/posthog.d.ts.map +1 -0
  100. package/dist/impls/posthog.js +323 -0
  101. package/dist/impls/postmark-email.d.ts +13 -17
  102. package/dist/impls/postmark-email.d.ts.map +1 -1
  103. package/dist/impls/postmark-email.js +55 -50
  104. package/dist/impls/powens-client.d.ts +111 -114
  105. package/dist/impls/powens-client.d.ts.map +1 -1
  106. package/dist/impls/powens-client.js +194 -170
  107. package/dist/impls/powens-openbanking.d.ts +22 -26
  108. package/dist/impls/powens-openbanking.d.ts.map +1 -1
  109. package/dist/impls/powens-openbanking.js +425 -217
  110. package/dist/impls/provider-factory.d.ts +29 -25
  111. package/dist/impls/provider-factory.d.ts.map +1 -1
  112. package/dist/impls/provider-factory.js +4074 -136
  113. package/dist/impls/qdrant-vector.d.ts +18 -22
  114. package/dist/impls/qdrant-vector.d.ts.map +1 -1
  115. package/dist/impls/qdrant-vector.js +76 -69
  116. package/dist/impls/stripe-payments.d.ts +22 -26
  117. package/dist/impls/stripe-payments.d.ts.map +1 -1
  118. package/dist/impls/stripe-payments.js +219 -193
  119. package/dist/impls/supabase-psql.d.ts +24 -0
  120. package/dist/impls/supabase-psql.d.ts.map +1 -0
  121. package/dist/impls/supabase-psql.js +151 -0
  122. package/dist/impls/supabase-vector.d.ts +32 -0
  123. package/dist/impls/supabase-vector.d.ts.map +1 -0
  124. package/dist/impls/supabase-vector.js +324 -0
  125. package/dist/impls/tldv-meeting-recorder.d.ts +21 -0
  126. package/dist/impls/tldv-meeting-recorder.d.ts.map +1 -0
  127. package/dist/impls/tldv-meeting-recorder.js +146 -0
  128. package/dist/impls/twilio-sms.d.ts +14 -17
  129. package/dist/impls/twilio-sms.d.ts.map +1 -1
  130. package/dist/impls/twilio-sms.js +62 -55
  131. package/dist/index.d.ts +15 -43
  132. package/dist/index.d.ts.map +1 -1
  133. package/dist/index.js +4700 -69
  134. package/dist/llm.d.ts +1 -7
  135. package/dist/llm.d.ts.map +1 -1
  136. package/dist/llm.js +3 -3
  137. package/dist/meeting-recorder.d.ts +2 -0
  138. package/dist/meeting-recorder.d.ts.map +1 -0
  139. package/dist/meeting-recorder.js +3 -0
  140. package/dist/node/analytics.js +2 -0
  141. package/dist/node/calendar.js +2 -0
  142. package/dist/node/database.js +2 -0
  143. package/dist/node/email.js +2 -0
  144. package/dist/node/embedding.js +2 -0
  145. package/dist/node/impls/elevenlabs-voice.js +102 -0
  146. package/dist/node/impls/fal-voice.js +112 -0
  147. package/dist/node/impls/fathom-meeting-recorder.js +287 -0
  148. package/dist/node/impls/fathom-meeting-recorder.mapper.js +105 -0
  149. package/dist/node/impls/fathom-meeting-recorder.types.js +0 -0
  150. package/dist/node/impls/fathom-meeting-recorder.utils.js +72 -0
  151. package/dist/node/impls/fathom-meeting-recorder.webhooks.js +29 -0
  152. package/dist/node/impls/fireflies-meeting-recorder.js +274 -0
  153. package/dist/node/impls/fireflies-meeting-recorder.queries.js +85 -0
  154. package/dist/node/impls/fireflies-meeting-recorder.types.js +0 -0
  155. package/dist/node/impls/fireflies-meeting-recorder.utils.js +42 -0
  156. package/dist/node/impls/gcs-storage.js +97 -0
  157. package/dist/node/impls/gmail-inbound.js +227 -0
  158. package/dist/node/impls/gmail-outbound.js +139 -0
  159. package/dist/node/impls/google-calendar.js +191 -0
  160. package/dist/node/impls/gradium-voice.js +90 -0
  161. package/dist/node/impls/granola-meeting-recorder.js +512 -0
  162. package/dist/node/impls/granola-meeting-recorder.mcp.js +278 -0
  163. package/dist/node/impls/granola-meeting-recorder.types.js +0 -0
  164. package/dist/node/impls/index.js +4658 -0
  165. package/dist/node/impls/jira.js +124 -0
  166. package/dist/node/impls/linear.js +83 -0
  167. package/dist/node/impls/mistral-embedding.js +43 -0
  168. package/dist/node/impls/mistral-llm.js +269 -0
  169. package/dist/node/impls/notion.js +160 -0
  170. package/dist/node/impls/posthog-reader.js +159 -0
  171. package/dist/node/impls/posthog-utils.js +38 -0
  172. package/dist/node/impls/posthog.js +322 -0
  173. package/dist/node/impls/postmark-email.js +60 -0
  174. package/dist/node/impls/powens-client.js +195 -0
  175. package/dist/node/impls/powens-openbanking.js +426 -0
  176. package/dist/node/impls/provider-factory.js +4080 -0
  177. package/dist/node/impls/qdrant-vector.js +78 -0
  178. package/dist/node/impls/stripe-payments.js +228 -0
  179. package/dist/node/impls/supabase-psql.js +150 -0
  180. package/dist/node/impls/supabase-vector.js +323 -0
  181. package/dist/node/impls/tldv-meeting-recorder.js +145 -0
  182. package/dist/node/impls/twilio-sms.js +65 -0
  183. package/dist/node/index.js +4699 -0
  184. package/dist/node/llm.js +2 -0
  185. package/dist/node/meeting-recorder.js +2 -0
  186. package/dist/node/openbanking.js +2 -0
  187. package/dist/node/payments.js +2 -0
  188. package/dist/node/project-management.js +2 -0
  189. package/dist/node/runtime.js +0 -0
  190. package/dist/node/secrets/provider.js +11 -0
  191. package/dist/node/sms.js +2 -0
  192. package/dist/node/storage.js +2 -0
  193. package/dist/node/vector-store.js +2 -0
  194. package/dist/node/voice.js +2 -0
  195. package/dist/openbanking.d.ts +1 -7
  196. package/dist/openbanking.d.ts.map +1 -1
  197. package/dist/openbanking.js +3 -3
  198. package/dist/payments.d.ts +1 -7
  199. package/dist/payments.d.ts.map +1 -1
  200. package/dist/payments.js +3 -3
  201. package/dist/project-management.d.ts +2 -0
  202. package/dist/project-management.d.ts.map +1 -0
  203. package/dist/project-management.js +3 -0
  204. package/dist/runtime.d.ts +2 -2
  205. package/dist/runtime.d.ts.map +1 -0
  206. package/dist/runtime.js +1 -0
  207. package/dist/secrets/provider.d.ts +3 -2
  208. package/dist/secrets/provider.d.ts.map +1 -0
  209. package/dist/secrets/provider.js +12 -3
  210. package/dist/sms.d.ts +1 -7
  211. package/dist/sms.d.ts.map +1 -1
  212. package/dist/sms.js +3 -3
  213. package/dist/storage.d.ts +1 -7
  214. package/dist/storage.d.ts.map +1 -1
  215. package/dist/storage.js +3 -3
  216. package/dist/vector-store.d.ts +1 -7
  217. package/dist/vector-store.d.ts.map +1 -1
  218. package/dist/vector-store.js +3 -3
  219. package/dist/voice.d.ts +1 -7
  220. package/dist/voice.d.ts.map +1 -1
  221. package/dist/voice.js +3 -3
  222. package/package.json +419 -76
  223. package/dist/_virtual/rolldown_runtime.js +0 -36
  224. package/dist/impls/elevenlabs-voice.js.map +0 -1
  225. package/dist/impls/gcs-storage.js.map +0 -1
  226. package/dist/impls/gmail-inbound.js.map +0 -1
  227. package/dist/impls/gmail-outbound.js.map +0 -1
  228. package/dist/impls/google-calendar.js.map +0 -1
  229. package/dist/impls/mistral-embedding.js.map +0 -1
  230. package/dist/impls/mistral-llm.js.map +0 -1
  231. package/dist/impls/postmark-email.js.map +0 -1
  232. package/dist/impls/powens-client.js.map +0 -1
  233. package/dist/impls/powens-openbanking.js.map +0 -1
  234. package/dist/impls/provider-factory.js.map +0 -1
  235. package/dist/impls/qdrant-vector.js.map +0 -1
  236. package/dist/impls/stripe-payments.js.map +0 -1
  237. package/dist/impls/twilio-sms.js.map +0 -1
  238. package/dist/index.js.map +0 -1
@@ -0,0 +1,278 @@
1
+ // src/impls/granola-meeting-recorder.mcp.ts
2
+ var UNKNOWN_EMAIL = "unknown@granola.local";
3
+ var EPOCH = "1970-01-01T00:00:00.000Z";
4
+
5
+ class GranolaMcpClient {
6
+ requestId = 0;
7
+ mcpUrl;
8
+ mcpAccessToken;
9
+ mcpHeaders;
10
+ fetchFn;
11
+ constructor(options) {
12
+ this.mcpUrl = options.mcpUrl;
13
+ this.mcpAccessToken = options.mcpAccessToken;
14
+ this.mcpHeaders = options.mcpHeaders;
15
+ this.fetchFn = options.fetchFn ?? fetch;
16
+ }
17
+ async callTool(name, args) {
18
+ const headers = {
19
+ "Content-Type": "application/json",
20
+ ...this.mcpHeaders ?? {}
21
+ };
22
+ if (this.mcpAccessToken) {
23
+ headers.Authorization = `Bearer ${this.mcpAccessToken}`;
24
+ }
25
+ const response = await this.fetchFn(this.mcpUrl, {
26
+ method: "POST",
27
+ headers,
28
+ body: JSON.stringify({
29
+ jsonrpc: "2.0",
30
+ id: ++this.requestId,
31
+ method: "tools/call",
32
+ params: {
33
+ name,
34
+ arguments: args
35
+ }
36
+ })
37
+ });
38
+ if (!response.ok) {
39
+ const message = await safeReadText(response);
40
+ throw new Error(`Granola MCP error (${response.status}): ${message}`);
41
+ }
42
+ const rpc = await response.json();
43
+ if (rpc.error) {
44
+ throw new Error(rpc.error.message ?? "Granola MCP returned an error.");
45
+ }
46
+ return extractRpcResult(rpc);
47
+ }
48
+ }
49
+ function normalizeMcpListResult(payload) {
50
+ const root = asObject(payload);
51
+ const list = asArray(payload) ?? asArray(root?.notes) ?? asArray(root?.meetings) ?? asArray(root?.items) ?? asArray(root?.results) ?? asArray(root?.data) ?? [];
52
+ const notes = list.map((item) => mapSummaryItem(item)).filter((item) => Boolean(item));
53
+ return {
54
+ notes,
55
+ nextCursor: readString(root, ["nextCursor", "next_cursor", "cursor"]),
56
+ hasMore: readBoolean(root, ["hasMore", "has_more"])
57
+ };
58
+ }
59
+ function normalizeMcpMeeting(payload, targetMeetingId) {
60
+ const root = asObject(payload);
61
+ const candidates = asArray(payload) ?? asArray(root?.meetings) ?? asArray(root?.notes) ?? asArray(root?.items) ?? asArray(root?.results) ?? asArray(root?.data);
62
+ if (candidates?.length) {
63
+ const selected = candidates.find((item) => readId(item) === targetMeetingId) ?? candidates.find((item) => String(readId(item) ?? "").includes(targetMeetingId)) ?? candidates[0];
64
+ return selected ? mapMeetingItem(selected) : undefined;
65
+ }
66
+ const direct = mapMeetingItem(payload);
67
+ if (direct && direct.id === targetMeetingId) {
68
+ return direct;
69
+ }
70
+ return direct;
71
+ }
72
+ function normalizeMcpTranscript(payload) {
73
+ const root = asObject(payload);
74
+ const list = asArray(payload) ?? asArray(root?.transcript) ?? asArray(root?.segments) ?? asArray(root?.items) ?? asArray(root?.data) ?? [];
75
+ if (list.length === 0 && typeof payload === "string") {
76
+ return [
77
+ {
78
+ text: payload,
79
+ start_time: "00:00:00",
80
+ end_time: "00:00:00"
81
+ }
82
+ ];
83
+ }
84
+ return list.map((item) => mapTranscriptSegment(item)).filter((item) => Boolean(item));
85
+ }
86
+ function extractRpcResult(rpc) {
87
+ const result = rpc.result;
88
+ if (!result)
89
+ return null;
90
+ if (result.structuredContent !== undefined)
91
+ return result.structuredContent;
92
+ if (result.data !== undefined)
93
+ return result.data;
94
+ const textPayload = result.content?.find((entry) => entry?.type === "text")?.text;
95
+ if (!textPayload)
96
+ return result;
97
+ try {
98
+ return JSON.parse(textPayload);
99
+ } catch {
100
+ return textPayload;
101
+ }
102
+ }
103
+ function mapSummaryItem(value) {
104
+ const object = asObject(value);
105
+ if (!object)
106
+ return;
107
+ const id = readId(object);
108
+ if (!id)
109
+ return;
110
+ const owner = mapOwner(object);
111
+ return {
112
+ id,
113
+ title: readString(object, ["title", "name", "meeting_title"]) ?? null,
114
+ owner,
115
+ created_at: readString(object, ["created_at", "createdAt", "date", "meeting_date"]) ?? EPOCH
116
+ };
117
+ }
118
+ function mapMeetingItem(value) {
119
+ const summary = mapSummaryItem(value);
120
+ if (!summary)
121
+ return;
122
+ const object = asObject(value) ?? {};
123
+ const attendees = asArray(object.attendees) ?? asArray(object.participants) ?? asArray(object.invitees) ?? [];
124
+ const mappedAttendees = attendees.map((entry) => mapUser(entry)).filter((entry) => Boolean(entry));
125
+ const folders = asArray(object.folder_membership) ?? asArray(object.folders) ?? [];
126
+ const folderMembership = folders.map((entry, index) => mapFolder(entry, index)).filter((entry) => Boolean(entry));
127
+ const calendarEvent = asObject(object.calendar_event) ? {
128
+ event_title: readString(asObject(object.calendar_event), [
129
+ "event_title",
130
+ "title"
131
+ ]) ?? null,
132
+ invitees: mappedAttendees.map((attendee) => ({
133
+ email: attendee.email
134
+ })),
135
+ organiser: readString(asObject(object.calendar_event), [
136
+ "organiser",
137
+ "organizer"
138
+ ]) ?? summary.owner.email,
139
+ calendar_event_id: readString(asObject(object.calendar_event), [
140
+ "calendar_event_id",
141
+ "id"
142
+ ]) ?? null,
143
+ scheduled_start_time: readString(asObject(object.calendar_event), [
144
+ "scheduled_start_time",
145
+ "start_time",
146
+ "start"
147
+ ]) ?? null,
148
+ scheduled_end_time: readString(asObject(object.calendar_event), [
149
+ "scheduled_end_time",
150
+ "end_time",
151
+ "end"
152
+ ]) ?? null
153
+ } : null;
154
+ const transcript = normalizeMcpTranscript(object.transcript ?? object.segments);
155
+ return {
156
+ ...summary,
157
+ calendar_event: calendarEvent,
158
+ attendees: mappedAttendees,
159
+ folder_membership: folderMembership,
160
+ summary_text: readString(object, ["summary_text", "summary", "enhanced_notes"]) ?? "",
161
+ transcript: transcript.length ? transcript : null
162
+ };
163
+ }
164
+ function mapTranscriptSegment(value) {
165
+ const object = asObject(value);
166
+ if (!object) {
167
+ if (typeof value !== "string")
168
+ return;
169
+ return {
170
+ text: value,
171
+ start_time: "00:00:00",
172
+ end_time: "00:00:00"
173
+ };
174
+ }
175
+ const text = readString(object, ["text", "content", "utterance"]);
176
+ if (!text)
177
+ return;
178
+ const speakerSource = readString(asObject(object.speaker), ["source", "name"]) ?? readString(object, ["speaker", "speaker_name"]);
179
+ return {
180
+ speaker: speakerSource ? { source: speakerSource } : undefined,
181
+ text,
182
+ start_time: readString(object, ["start_time", "startTime", "timestamp", "time"]) ?? "00:00:00",
183
+ end_time: readString(object, ["end_time", "endTime"]) ?? "00:00:00"
184
+ };
185
+ }
186
+ function mapOwner(object) {
187
+ const ownerObject = asObject(object.owner) ?? asObject(object.organizer) ?? asObject(object.organiser);
188
+ const attendee = asArray(object.attendees)?.[0] ?? asArray(object.participants)?.[0] ?? asArray(object.invitees)?.[0];
189
+ const ownerCandidate = ownerObject ?? asObject(attendee) ?? {};
190
+ return {
191
+ name: readString(ownerCandidate, ["name", "displayName"]) ?? null,
192
+ email: readString(ownerCandidate, ["email"]) ?? UNKNOWN_EMAIL
193
+ };
194
+ }
195
+ function mapUser(value) {
196
+ if (typeof value === "string") {
197
+ return {
198
+ name: null,
199
+ email: value
200
+ };
201
+ }
202
+ const object = asObject(value);
203
+ if (!object)
204
+ return;
205
+ const email = readString(object, ["email"]);
206
+ if (!email)
207
+ return;
208
+ return {
209
+ name: readString(object, ["name", "displayName"]) ?? null,
210
+ email
211
+ };
212
+ }
213
+ function mapFolder(value, index) {
214
+ const object = asObject(value);
215
+ if (!object)
216
+ return;
217
+ const id = readString(object, ["id"]) ?? `folder-${index}`;
218
+ const name = readString(object, ["name"]) ?? "Folder";
219
+ return {
220
+ id,
221
+ object: "folder",
222
+ name
223
+ };
224
+ }
225
+ function readId(value) {
226
+ const object = asObject(value);
227
+ if (!object)
228
+ return;
229
+ return readString(object, [
230
+ "id",
231
+ "meeting_id",
232
+ "meetingId",
233
+ "note_id",
234
+ "noteId"
235
+ ]);
236
+ }
237
+ function readString(object, keys) {
238
+ if (!object)
239
+ return;
240
+ for (const key of keys) {
241
+ const value = object[key];
242
+ if (typeof value === "string" && value.trim().length > 0) {
243
+ return value;
244
+ }
245
+ }
246
+ return;
247
+ }
248
+ function readBoolean(object, keys) {
249
+ if (!object)
250
+ return;
251
+ for (const key of keys) {
252
+ const value = object[key];
253
+ if (typeof value === "boolean")
254
+ return value;
255
+ }
256
+ return;
257
+ }
258
+ function asObject(value) {
259
+ if (!value || typeof value !== "object" || Array.isArray(value))
260
+ return;
261
+ return value;
262
+ }
263
+ function asArray(value) {
264
+ return Array.isArray(value) ? value : undefined;
265
+ }
266
+ async function safeReadText(response) {
267
+ try {
268
+ return await response.text();
269
+ } catch {
270
+ return response.statusText;
271
+ }
272
+ }
273
+ export {
274
+ normalizeMcpTranscript,
275
+ normalizeMcpMeeting,
276
+ normalizeMcpListResult,
277
+ GranolaMcpClient
278
+ };