feedback-vos 1.0.0 → 1.0.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.
package/dist/index.js CHANGED
@@ -60,7 +60,7 @@ function ScreenshotButton({
60
60
  "button",
61
61
  {
62
62
  type: "button",
63
- className: "p-1 w-10 h-10 rounded-md border-transparent flex \r\n justify-end items-end text-zinc-400 hover:text-zinc-100 transition-colors",
63
+ className: "p-1 w-10 h-10 rounded-md border-transparent flex \n justify-end items-end text-zinc-400 hover:text-zinc-100 transition-colors",
64
64
  onClick: () => onScreenshotTook(null),
65
65
  style: {
66
66
  backgroundImage: `url(${screenshot})`,
@@ -75,119 +75,384 @@ function ScreenshotButton({
75
75
  "button",
76
76
  {
77
77
  type: "button",
78
- className: "p-2 bg-zinc-800 rounded-md border-transparent hover:bg-zinc-700\r\n transitions-colors focus:outline-none focus:ring-2\r\n focus:ring-offset-2 focus:ring-offset-zinc-900 focus:ring-brand-500",
78
+ className: "p-2 bg-zinc-800 rounded-md border-transparent hover:bg-zinc-700\n transitions-colors focus:outline-none focus:ring-2\n focus:ring-offset-2 focus:ring-offset-zinc-900 focus:ring-brand-500",
79
79
  onClick: handleTakeScreenshot,
80
80
  children: isTakenScreenshot ? /* @__PURE__ */ jsxRuntime.jsx(Loading, {}) : /* @__PURE__ */ jsxRuntime.jsx(phosphorReact.Camera, { weight: "bold", className: "w-6 h-6" })
81
81
  }
82
82
  );
83
83
  }
84
84
 
85
- // src/lib/integrations/notion.ts
86
- async function sendToNotion(config, data) {
87
- const { apiKey, databaseId } = config;
88
- const { type, comment, screenshot } = data;
89
- const typeMap = {
90
- BUG: "Bug",
91
- IDEA: "Idea",
92
- OTHER: "Other"
93
- };
94
- const properties = {
95
- Type: {
96
- select: {
97
- name: typeMap[type]
85
+ // src/lib/integrations/github.ts
86
+ async function uploadScreenshotToRepo(token, owner, repo, screenshot, screenshotPath) {
87
+ const compressedScreenshot = await compressScreenshot(screenshot, 1920, 0.7);
88
+ const base64Data = compressedScreenshot.split(",")[1];
89
+ const binaryData = Uint8Array.from(atob(base64Data), (c) => c.charCodeAt(0));
90
+ const repoResponse = await fetch(
91
+ `https://api.github.com/repos/${owner}/${repo}`,
92
+ {
93
+ headers: {
94
+ "Authorization": `Bearer ${token}`,
95
+ "Accept": "application/vnd.github.v3+json",
96
+ "User-Agent": "feedback-vos"
98
97
  }
99
- },
100
- Comment: {
101
- rich_text: [
102
- {
103
- text: {
104
- content: comment
105
- }
106
- }
107
- ]
108
98
  }
109
- };
110
- const children = [];
111
- if (screenshot) {
112
- children.push({
113
- object: "block",
114
- type: "paragraph",
115
- paragraph: {
116
- rich_text: [
117
- {
118
- text: {
119
- content: "Screenshot provided (see comment for details)"
120
- }
121
- }
122
- ]
99
+ );
100
+ let defaultBranch = "main";
101
+ if (repoResponse.ok) {
102
+ const repoData = await repoResponse.json();
103
+ defaultBranch = repoData.default_branch || "main";
104
+ }
105
+ const folderPath = screenshotPath || ".feedback-vos";
106
+ const timestamp = Date.now();
107
+ const randomId = Math.random().toString(36).substring(2, 9);
108
+ const filename = `feedback-${timestamp}-${randomId}.jpg`;
109
+ const path = `${folderPath}/${filename}`;
110
+ const base64Content = btoa(String.fromCharCode(...binaryData));
111
+ const folderCheckUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${folderPath}`;
112
+ try {
113
+ const folderCheck = await fetch(folderCheckUrl, {
114
+ headers: {
115
+ "Authorization": `Bearer ${token}`,
116
+ "Accept": "application/vnd.github.v3+json",
117
+ "User-Agent": "feedback-vos"
123
118
  }
124
119
  });
125
- properties.Screenshot = {
126
- rich_text: [
127
- {
128
- text: {
129
- content: screenshot.substring(0, 2e3)
130
- // Truncate if too long
131
- }
120
+ if (folderCheck.status === 404) {
121
+ const readmeContent = btoa("# Feedback Screenshots\n\nThis folder contains screenshots from user feedback.\n");
122
+ try {
123
+ const folderCreateResponse = await fetch(`https://api.github.com/repos/${owner}/${repo}/contents/${folderPath}/README.md`, {
124
+ method: "PUT",
125
+ headers: {
126
+ "Authorization": `Bearer ${token}`,
127
+ "Accept": "application/vnd.github.v3+json",
128
+ "Content-Type": "application/json",
129
+ "User-Agent": "feedback-vos"
130
+ },
131
+ body: JSON.stringify({
132
+ message: "Create feedback screenshots folder",
133
+ content: readmeContent,
134
+ branch: defaultBranch
135
+ })
136
+ });
137
+ if (!folderCreateResponse.ok) {
138
+ const folderError = await folderCreateResponse.json().catch(() => ({}));
139
+ console.warn("Could not create folder, proceeding with upload anyway:", folderError);
140
+ } else {
141
+ console.log(`Folder ${folderPath} created successfully`);
132
142
  }
133
- ]
134
- };
143
+ } catch (folderCreateError) {
144
+ console.warn("Could not create folder, proceeding with upload:", folderCreateError);
145
+ }
146
+ } else if (folderCheck.status === 200) {
147
+ const folderData = await folderCheck.json().catch(() => null);
148
+ if (folderData && !Array.isArray(folderData)) {
149
+ throw new Error(`Path "${folderPath}" exists as a file, not a folder. Please use a different path or remove the file.`);
150
+ }
151
+ console.log(`Folder ${folderPath} already exists`);
152
+ }
153
+ } catch (folderError) {
154
+ if (folderError instanceof Error && folderError.message.includes("exists as a file")) {
155
+ throw folderError;
156
+ }
157
+ console.warn("Could not verify/create screenshots folder:", folderError);
135
158
  }
136
- const response = await fetch("https://api.notion.com/v1/pages", {
137
- method: "POST",
159
+ const uploadUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${path}`;
160
+ const response = await fetch(uploadUrl, {
161
+ method: "PUT",
138
162
  headers: {
139
- "Authorization": `Bearer ${apiKey}`,
163
+ "Authorization": `Bearer ${token}`,
164
+ "Accept": "application/vnd.github.v3+json",
140
165
  "Content-Type": "application/json",
141
- "Notion-Version": "2022-06-28"
166
+ "User-Agent": "feedback-vos"
142
167
  },
143
168
  body: JSON.stringify({
144
- parent: {
145
- database_id: databaseId
146
- },
147
- properties,
148
- children
169
+ message: `Add feedback screenshot: ${filename}`,
170
+ content: base64Content,
171
+ branch: defaultBranch
149
172
  })
150
173
  });
151
174
  if (!response.ok) {
152
- const error = await response.text();
153
- throw new Error(`Notion API error: ${error}`);
175
+ const errorData = await response.json().catch(() => ({}));
176
+ const errorMessage = errorData.message || "Unknown error";
177
+ if (response.status === 409) {
178
+ throw new Error(`File already exists. This is unexpected - please try again.`);
179
+ } else if (response.status === 403) {
180
+ throw new Error(`Permission denied. Make sure your token has write access to the repository.`);
181
+ } else if (response.status === 422) {
182
+ throw new Error(`Validation failed: ${errorMessage}. The file might be too large.`);
183
+ }
184
+ throw new Error(`Failed to upload screenshot (${response.status}): ${errorMessage}`);
185
+ }
186
+ await response.json();
187
+ const rawUrl = `https://github.com/${owner}/${repo}/blob/${defaultBranch}/${path}?raw=true`;
188
+ console.log(`Screenshot uploaded successfully to: ${rawUrl}`);
189
+ return rawUrl;
190
+ }
191
+ function compressScreenshot(dataUrl, maxWidth = 1920, quality = 0.7) {
192
+ return new Promise((resolve, reject) => {
193
+ if (typeof window === "undefined" || typeof document === "undefined") {
194
+ reject(new Error("Screenshot compression only works in browser environments"));
195
+ return;
196
+ }
197
+ const img = new Image();
198
+ img.onload = () => {
199
+ const canvas = document.createElement("canvas");
200
+ let width = img.width;
201
+ let height = img.height;
202
+ if (width > maxWidth) {
203
+ height = height * maxWidth / width;
204
+ width = maxWidth;
205
+ }
206
+ canvas.width = width;
207
+ canvas.height = height;
208
+ const ctx = canvas.getContext("2d");
209
+ if (!ctx) {
210
+ reject(new Error("Could not get canvas context"));
211
+ return;
212
+ }
213
+ ctx.drawImage(img, 0, 0, width, height);
214
+ const compressedDataUrl = canvas.toDataURL("image/jpeg", quality);
215
+ resolve(compressedDataUrl);
216
+ };
217
+ img.onerror = () => reject(new Error("Failed to load image"));
218
+ img.src = dataUrl;
219
+ });
220
+ }
221
+ async function verifyRepositoryAccess(token, owner, repo) {
222
+ try {
223
+ const response = await fetch(
224
+ `https://api.github.com/repos/${owner}/${repo}`,
225
+ {
226
+ headers: {
227
+ "Authorization": `Bearer ${token}`,
228
+ "Accept": "application/vnd.github.v3+json",
229
+ "User-Agent": "feedback-vos"
230
+ }
231
+ }
232
+ );
233
+ if (response.status === 404) {
234
+ return { exists: false, hasIssues: false, error: "Repository not found" };
235
+ }
236
+ if (!response.ok) {
237
+ const errorData = await response.json().catch(() => ({}));
238
+ return {
239
+ exists: false,
240
+ hasIssues: false,
241
+ error: errorData.message || `HTTP ${response.status}`
242
+ };
243
+ }
244
+ const repoData = await response.json();
245
+ return {
246
+ exists: true,
247
+ hasIssues: repoData.has_issues !== false
248
+ // Default is true if not specified
249
+ };
250
+ } catch (error) {
251
+ return {
252
+ exists: false,
253
+ hasIssues: false,
254
+ error: error instanceof Error ? error.message : "Unknown error"
255
+ };
154
256
  }
155
257
  }
156
-
157
- // src/lib/integrations/github.ts
158
258
  async function sendToGitHub(config, data) {
159
- const { token, owner, repo } = config;
259
+ const { token, owner, repo, screenshotPath } = config;
160
260
  const { type, comment, screenshot } = data;
261
+ if (!token || !owner || !repo) {
262
+ throw new Error("GitHub configuration is incomplete. Please provide token, owner, and repo.");
263
+ }
264
+ const verification = await verifyRepositoryAccess(token, owner, repo);
265
+ if (!verification.exists) {
266
+ throw new Error(
267
+ `Repository "${owner}/${repo}" not found or not accessible.
268
+ Error: ${verification.error || "Unknown error"}
269
+
270
+ Please verify:
271
+ - Repository exists at https://github.com/${owner}/${repo}
272
+ - Your token has access to this repository
273
+ - Token has "repo" scope (for private) or "public_repo" scope (for public)`
274
+ );
275
+ }
276
+ if (!verification.hasIssues) {
277
+ throw new Error(
278
+ `Issues are disabled for repository "${owner}/${repo}".
279
+
280
+ Please enable Issues in repository Settings \u2192 General \u2192 Features \u2192 Issues`
281
+ );
282
+ }
161
283
  const title = `[${type}] Feedback`;
284
+ const ABSOLUTE_MAX_LENGTH = 65536;
285
+ const BASE_BODY_LENGTH = 50;
286
+ const SCREENSHOT_URL_LENGTH = 150;
287
+ const SAFETY_MARGIN = 1e3;
288
+ const MAX_COMMENT_LENGTH = ABSOLUTE_MAX_LENGTH - BASE_BODY_LENGTH - SCREENSHOT_URL_LENGTH - SAFETY_MARGIN;
289
+ const limitedComment = comment.length > MAX_COMMENT_LENGTH ? comment.substring(0, MAX_COMMENT_LENGTH) + "\n\n... (comment truncated)" : comment;
162
290
  let body = `**Type:** ${type}
163
291
 
164
292
  **Comment:**
165
- ${comment}`;
293
+ ${limitedComment}`;
166
294
  if (screenshot) {
167
- body += `
295
+ try {
296
+ console.log("Uploading screenshot to repository...");
297
+ console.log("Screenshot path:", screenshotPath || ".feedback-vos");
298
+ const screenshotUrl = await uploadScreenshotToRepo(token, owner, repo, screenshot, screenshotPath);
299
+ console.log("Screenshot uploaded successfully, URL:", screenshotUrl);
300
+ body += `
168
301
 
169
302
  **Screenshot:**
170
- ![Screenshot](${screenshot})`;
303
+ ![Screenshot](${screenshotUrl})`;
304
+ console.log("Body length after adding screenshot URL:", body.length);
305
+ } catch (error) {
306
+ console.error("Failed to upload screenshot to repository:", error);
307
+ body += `
308
+
309
+ **Screenshot:** Upload failed - screenshot not included.`;
310
+ console.log("Body length after upload failure:", body.length);
311
+ }
171
312
  }
172
- const response = await fetch(
173
- `https://api.github.com/repos/${owner}/${repo}/issues`,
174
- {
313
+ const SAFE_MAX_LENGTH = 65e3;
314
+ console.log(`Issue body length before final check: ${body.length} characters`);
315
+ if (body.length > SAFE_MAX_LENGTH) {
316
+ console.warn(`Body is too long (${body.length}), truncating...`);
317
+ const excess = body.length - SAFE_MAX_LENGTH;
318
+ const commentStartMarker = "\n\n**Comment:**\n";
319
+ const commentStart = body.indexOf(commentStartMarker);
320
+ const screenshotStart = body.indexOf("\n\n**Screenshot:**");
321
+ if (commentStart > 0) {
322
+ const commentStartPos = commentStart + commentStartMarker.length;
323
+ const commentEndPos = screenshotStart > 0 ? screenshotStart : body.length;
324
+ const currentComment = body.substring(commentStartPos, commentEndPos);
325
+ const newCommentLength = Math.max(100, currentComment.length - excess - 500);
326
+ const truncatedComment = currentComment.substring(0, newCommentLength) + "\n\n... (truncated due to size limit)";
327
+ const beforeComment = body.substring(0, commentStartPos);
328
+ const afterComment = screenshotStart > 0 ? body.substring(screenshotStart) : "";
329
+ body = beforeComment + truncatedComment + afterComment;
330
+ }
331
+ }
332
+ if (body.length >= ABSOLUTE_MAX_LENGTH) {
333
+ console.error(`Body STILL too long after truncation: ${body.length} characters. Force truncating.`);
334
+ const baseText = `**Type:** ${type}
335
+
336
+ **Comment:**
337
+ `;
338
+ const maxCommentLength = ABSOLUTE_MAX_LENGTH - baseText.length - 1e3;
339
+ const safeComment = comment.substring(0, Math.max(100, maxCommentLength)) + "\n\n... (truncated due to size limit)";
340
+ body = baseText + safeComment;
341
+ const screenshotIndex = body.indexOf("\n\n**Screenshot:**");
342
+ if (screenshotIndex > 0) {
343
+ body = body.substring(0, screenshotIndex) + "\n\n**Screenshot:** Not included due to size limit.";
344
+ }
345
+ }
346
+ if (body.length >= ABSOLUTE_MAX_LENGTH) {
347
+ const minimalBase = `**Type:** ${type}
348
+
349
+ **Comment:**
350
+ `;
351
+ const maxSafeComment = ABSOLUTE_MAX_LENGTH - minimalBase.length - 100;
352
+ const minimalComment = comment.substring(0, Math.max(50, maxSafeComment)) + "\n\n... (truncated)";
353
+ body = minimalBase + minimalComment;
354
+ }
355
+ console.log(`Final issue body length: ${body.length} characters (limit: ${ABSOLUTE_MAX_LENGTH})`);
356
+ if (body.length >= ABSOLUTE_MAX_LENGTH) {
357
+ throw new Error(`CRITICAL: Cannot create issue - body is ${body.length} characters, exceeds GitHub limit of ${ABSOLUTE_MAX_LENGTH}.`);
358
+ }
359
+ const url = `https://api.github.com/repos/${owner}/${repo}/issues`;
360
+ try {
361
+ const response = await fetch(url, {
175
362
  method: "POST",
176
363
  headers: {
177
- "Authorization": `token ${token}`,
364
+ "Authorization": `Bearer ${token}`,
178
365
  "Accept": "application/vnd.github.v3+json",
179
- "Content-Type": "application/json"
366
+ "Content-Type": "application/json",
367
+ "User-Agent": "feedback-vos"
180
368
  },
181
369
  body: JSON.stringify({
182
370
  title,
183
371
  body,
372
+ // Note: Labels must exist in the repository. If they don't exist, GitHub will ignore them.
373
+ // You can create these labels in your repository settings if needed.
184
374
  labels: ["feedback", type.toLowerCase()]
185
375
  })
376
+ });
377
+ if (!response.ok) {
378
+ let errorMessage = `GitHub API error (${response.status}): `;
379
+ try {
380
+ const errorData = await response.json();
381
+ errorMessage += errorData.message || JSON.stringify(errorData);
382
+ if (response.status === 404) {
383
+ errorMessage += `
384
+
385
+ Trying to access: ${url}`;
386
+ errorMessage += `
387
+
388
+ Possible causes:
389
+ `;
390
+ errorMessage += `- Repository "${owner}/${repo}" does not exist or is not accessible
391
+ `;
392
+ errorMessage += `- Token does not have access to this repository
393
+ `;
394
+ errorMessage += `- Check that owner and repo names are correct (case-sensitive)
395
+ `;
396
+ errorMessage += `- Verify the repository URL: https://github.com/${owner}/${repo}
397
+ `;
398
+ errorMessage += `- Make sure Issues are enabled in repository settings
399
+ `;
400
+ errorMessage += `
401
+ To debug:
402
+ `;
403
+ errorMessage += `1. Visit https://github.com/${owner}/${repo} to verify it exists
404
+ `;
405
+ errorMessage += `2. Check repository Settings \u2192 General \u2192 Features \u2192 Issues (must be enabled)
406
+ `;
407
+ errorMessage += `3. Verify your token has "repo" scope (for private) or "public_repo" scope (for public)
408
+ `;
409
+ errorMessage += `4. Test token access: curl -H "Authorization: Bearer YOUR_TOKEN" https://api.github.com/repos/${owner}/${repo}`;
410
+ } else if (response.status === 401) {
411
+ errorMessage += `
412
+
413
+ Possible causes:
414
+ `;
415
+ errorMessage += `- Invalid or expired GitHub token
416
+ `;
417
+ errorMessage += `- Token does not have the required "repo" or "public_repo" scope
418
+ `;
419
+ errorMessage += `- Generate a new token at https://github.com/settings/tokens`;
420
+ } else if (response.status === 422) {
421
+ errorMessage += `
422
+
423
+ Possible causes:
424
+ `;
425
+ errorMessage += `- Issue body is too long (maximum is 65536 characters)
426
+ `;
427
+ errorMessage += `- Screenshot is too large - it will be automatically compressed
428
+ `;
429
+ errorMessage += `- Try reducing the comment length or removing the screenshot
430
+ `;
431
+ errorMessage += `- Invalid label names (labels must exist in the repository)`;
432
+ } else if (response.status === 403) {
433
+ errorMessage += `
434
+
435
+ Possible causes:
436
+ `;
437
+ errorMessage += `- Token does not have permission to create issues
438
+ `;
439
+ errorMessage += `- Repository has issues disabled
440
+ `;
441
+ errorMessage += `- Rate limit exceeded (check GitHub API rate limits)
442
+ `;
443
+ errorMessage += `- Check repository Settings \u2192 General \u2192 Features \u2192 Issues`;
444
+ }
445
+ } catch (parseError) {
446
+ const errorText = await response.text();
447
+ errorMessage += errorText || "Unknown error";
448
+ }
449
+ throw new Error(errorMessage);
186
450
  }
187
- );
188
- if (!response.ok) {
189
- const error = await response.text();
190
- throw new Error(`GitHub API error: ${error}`);
451
+ } catch (error) {
452
+ if (error instanceof Error) {
453
+ throw error;
454
+ }
455
+ throw new Error(`Failed to create GitHub issue: ${String(error)}`);
191
456
  }
192
457
  }
193
458
  function FeedbackContentStep({
@@ -195,7 +460,6 @@ function FeedbackContentStep({
195
460
  onFeedbackRestartRequest,
196
461
  onFeedbackSent,
197
462
  integration,
198
- notionConfig,
199
463
  githubConfig
200
464
  }) {
201
465
  const [screenshot, setScreenshot] = react$1.useState(null);
@@ -211,9 +475,7 @@ function FeedbackContentStep({
211
475
  comment,
212
476
  screenshot
213
477
  };
214
- if (integration === "notion" && notionConfig) {
215
- await sendToNotion(notionConfig, feedbackData);
216
- } else if (integration === "github" && githubConfig) {
478
+ if (integration === "github") {
217
479
  await sendToGitHub(githubConfig, feedbackData);
218
480
  } else {
219
481
  throw new Error("Invalid integration configuration");
@@ -254,7 +516,7 @@ function FeedbackContentStep({
254
516
  /* @__PURE__ */ jsxRuntime.jsx(
255
517
  "textarea",
256
518
  {
257
- className: "min-w-[384px] w-full min-h-[112px] text-sm \r\n placeholder-zinc-400 text-zinc-100 border-zinc-600 bg-transparent rounded-md \r\n focus:border-brand-500 focus:ring-brand-500 focus:ring-1 resize-none focus:outline-none\r\n scrollbar-thumb-zinc-700 scrollbar-track-transparent scrollbar-thin",
519
+ className: "min-w-[384px] w-full min-h-[112px] text-sm \n placeholder-zinc-400 text-zinc-100 border-zinc-600 bg-transparent rounded-md \n focus:border-brand-500 focus:ring-brand-500 focus:ring-1 resize-none focus:outline-none\n scrollbar-thumb-zinc-700 scrollbar-track-transparent scrollbar-thin",
258
520
  placeholder: "Tell in detail what is happening",
259
521
  onChange: (e) => setComment(e.target.value)
260
522
  }
@@ -272,7 +534,7 @@ function FeedbackContentStep({
272
534
  {
273
535
  type: "submit",
274
536
  disabled: comment.length === 0 || isSendingFeedback,
275
- className: "p-2 bg-brand-500 rounded-md border-transparent flex-1 justify-center\r\n items-center text-sm hover:bg-brand-300 focus:outline-none focus:ring-2\r\n focus:ring-offset-2 focus:ring-offset-zinc-900 focus:ring-brand-500\r\n transition-colors disabled:opacity-50 disabled:cursor-not-allowed\r\n disabled:hover:bg-brand-500",
537
+ className: "p-2 bg-brand-500 rounded-md border-transparent flex-1 justify-center\n items-center text-sm hover:bg-brand-300 focus:outline-none focus:ring-2\n focus:ring-offset-2 focus:ring-offset-zinc-900 focus:ring-brand-500\n transition-colors disabled:opacity-50 disabled:cursor-not-allowed\n disabled:hover:bg-brand-500",
276
538
  children: isSendingFeedback ? /* @__PURE__ */ jsxRuntime.jsx(Loading, {}) : "Send feedback"
277
539
  }
278
540
  )
@@ -324,7 +586,7 @@ var feedbackTypes = {
324
586
  }
325
587
  }
326
588
  };
327
- function WidgetForm({ integration, notionConfig, githubConfig }) {
589
+ function WidgetForm({ integration, githubConfig }) {
328
590
  const [feedbackType, setFeedbackType] = react$1.useState(null);
329
591
  const [feedbackSent, setFeedbackSent] = react$1.useState(false);
330
592
  function handleRestartFeedback() {
@@ -339,7 +601,6 @@ function WidgetForm({ integration, notionConfig, githubConfig }) {
339
601
  onFeedbackRestartRequest: handleRestartFeedback,
340
602
  onFeedbackSent: () => setFeedbackSent(true),
341
603
  integration,
342
- notionConfig,
343
604
  githubConfig
344
605
  }
345
606
  ) }),
@@ -359,7 +620,6 @@ function WidgetForm({ integration, notionConfig, githubConfig }) {
359
620
  }
360
621
  function Widget({
361
622
  integration,
362
- notionConfig,
363
623
  githubConfig,
364
624
  position = "bottom-right"
365
625
  }) {
@@ -374,7 +634,6 @@ function Widget({
374
634
  WidgetForm,
375
635
  {
376
636
  integration,
377
- notionConfig,
378
637
  githubConfig
379
638
  }
380
639
  ) }),