@seed-ship/mcp-ui-solid 2.0.0 → 2.1.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 (140) hide show
  1. package/README.md +50 -1
  2. package/dist/components/AutocompleteDropdown.cjs +201 -0
  3. package/dist/components/AutocompleteDropdown.cjs.map +1 -0
  4. package/dist/components/AutocompleteDropdown.d.ts +71 -0
  5. package/dist/components/AutocompleteDropdown.d.ts.map +1 -0
  6. package/dist/components/AutocompleteDropdown.js +201 -0
  7. package/dist/components/AutocompleteDropdown.js.map +1 -0
  8. package/dist/components/AutocompleteFormField.cjs +289 -0
  9. package/dist/components/AutocompleteFormField.cjs.map +1 -0
  10. package/dist/components/AutocompleteFormField.d.ts +52 -0
  11. package/dist/components/AutocompleteFormField.d.ts.map +1 -0
  12. package/dist/components/AutocompleteFormField.js +289 -0
  13. package/dist/components/AutocompleteFormField.js.map +1 -0
  14. package/dist/components/DraggableGridItem.cjs +133 -0
  15. package/dist/components/DraggableGridItem.cjs.map +1 -0
  16. package/dist/components/DraggableGridItem.d.ts +95 -0
  17. package/dist/components/DraggableGridItem.d.ts.map +1 -0
  18. package/dist/components/DraggableGridItem.js +133 -0
  19. package/dist/components/DraggableGridItem.js.map +1 -0
  20. package/dist/components/EditableUIResourceRenderer.cjs +203 -0
  21. package/dist/components/EditableUIResourceRenderer.cjs.map +1 -0
  22. package/dist/components/EditableUIResourceRenderer.d.ts +43 -0
  23. package/dist/components/EditableUIResourceRenderer.d.ts.map +1 -0
  24. package/dist/components/EditableUIResourceRenderer.js +203 -0
  25. package/dist/components/EditableUIResourceRenderer.js.map +1 -0
  26. package/dist/components/GhostText.cjs +105 -0
  27. package/dist/components/GhostText.cjs.map +1 -0
  28. package/dist/components/GhostText.d.ts +113 -0
  29. package/dist/components/GhostText.d.ts.map +1 -0
  30. package/dist/components/GhostText.js +105 -0
  31. package/dist/components/GhostText.js.map +1 -0
  32. package/dist/components/ResizeHandle.cjs +173 -0
  33. package/dist/components/ResizeHandle.cjs.map +1 -0
  34. package/dist/components/ResizeHandle.d.ts +50 -0
  35. package/dist/components/ResizeHandle.d.ts.map +1 -0
  36. package/dist/components/ResizeHandle.js +173 -0
  37. package/dist/components/ResizeHandle.js.map +1 -0
  38. package/dist/context/AutocompleteContext.cjs +158 -0
  39. package/dist/context/AutocompleteContext.cjs.map +1 -0
  40. package/dist/context/AutocompleteContext.d.ts +77 -0
  41. package/dist/context/AutocompleteContext.d.ts.map +1 -0
  42. package/dist/context/AutocompleteContext.js +158 -0
  43. package/dist/context/AutocompleteContext.js.map +1 -0
  44. package/dist/hooks/index.d.ts +6 -0
  45. package/dist/hooks/index.d.ts.map +1 -1
  46. package/dist/hooks/useAutocomplete.cjs +234 -0
  47. package/dist/hooks/useAutocomplete.cjs.map +1 -0
  48. package/dist/hooks/useAutocomplete.d.ts +119 -0
  49. package/dist/hooks/useAutocomplete.d.ts.map +1 -0
  50. package/dist/hooks/useAutocomplete.js +234 -0
  51. package/dist/hooks/useAutocomplete.js.map +1 -0
  52. package/dist/hooks/useDragDrop.cjs +170 -0
  53. package/dist/hooks/useDragDrop.cjs.map +1 -0
  54. package/dist/hooks/useDragDrop.d.ts +100 -0
  55. package/dist/hooks/useDragDrop.d.ts.map +1 -0
  56. package/dist/hooks/useDragDrop.js +170 -0
  57. package/dist/hooks/useDragDrop.js.map +1 -0
  58. package/dist/hooks/useResize.cjs +209 -0
  59. package/dist/hooks/useResize.cjs.map +1 -0
  60. package/dist/hooks/useResize.d.ts +87 -0
  61. package/dist/hooks/useResize.d.ts.map +1 -0
  62. package/dist/hooks/useResize.js +209 -0
  63. package/dist/hooks/useResize.js.map +1 -0
  64. package/dist/hooks.cjs +6 -0
  65. package/dist/hooks.cjs.map +1 -1
  66. package/dist/hooks.d.cts +6 -0
  67. package/dist/hooks.d.ts +6 -0
  68. package/dist/hooks.js +6 -0
  69. package/dist/hooks.js.map +1 -1
  70. package/dist/index.cjs +29 -0
  71. package/dist/index.cjs.map +1 -1
  72. package/dist/index.d.cts +18 -3
  73. package/dist/index.d.ts +18 -3
  74. package/dist/index.d.ts.map +1 -1
  75. package/dist/index.js +29 -0
  76. package/dist/index.js.map +1 -1
  77. package/dist/plugins/duckdb.cjs +192 -0
  78. package/dist/plugins/duckdb.cjs.map +1 -0
  79. package/dist/plugins/duckdb.d.ts +20 -0
  80. package/dist/plugins/duckdb.d.ts.map +1 -0
  81. package/dist/plugins/duckdb.js +170 -0
  82. package/dist/plugins/duckdb.js.map +1 -0
  83. package/dist/plugins/groq.cjs +97 -0
  84. package/dist/plugins/groq.cjs.map +1 -0
  85. package/dist/plugins/groq.d.ts +13 -0
  86. package/dist/plugins/groq.d.ts.map +1 -0
  87. package/dist/plugins/groq.js +97 -0
  88. package/dist/plugins/groq.js.map +1 -0
  89. package/dist/plugins/index.d.ts +10 -0
  90. package/dist/plugins/index.d.ts.map +1 -0
  91. package/dist/plugins/rest.cjs +92 -0
  92. package/dist/plugins/rest.cjs.map +1 -0
  93. package/dist/plugins/rest.d.ts +13 -0
  94. package/dist/plugins/rest.d.ts.map +1 -0
  95. package/dist/plugins/rest.js +92 -0
  96. package/dist/plugins/rest.js.map +1 -0
  97. package/dist/plugins/supabase.cjs +79 -0
  98. package/dist/plugins/supabase.cjs.map +1 -0
  99. package/dist/plugins/supabase.d.ts +13 -0
  100. package/dist/plugins/supabase.d.ts.map +1 -0
  101. package/dist/plugins/supabase.js +79 -0
  102. package/dist/plugins/supabase.js.map +1 -0
  103. package/dist/services/validation.cjs +40 -1
  104. package/dist/services/validation.cjs.map +1 -1
  105. package/dist/services/validation.d.ts.map +1 -1
  106. package/dist/services/validation.js +40 -1
  107. package/dist/services/validation.js.map +1 -1
  108. package/dist/types/index.d.ts +430 -0
  109. package/dist/types/index.d.ts.map +1 -1
  110. package/dist/types.d.cts +430 -0
  111. package/dist/types.d.ts +430 -0
  112. package/package.json +16 -1
  113. package/src/components/AutocompleteDropdown.tsx +329 -0
  114. package/src/components/AutocompleteFormField.tsx +288 -0
  115. package/src/components/DraggableGridItem.tsx +274 -0
  116. package/src/components/EditableUIResourceRenderer.tsx +273 -0
  117. package/src/components/GhostText.tsx +262 -0
  118. package/src/components/ResizeHandle.tsx +262 -0
  119. package/src/context/AutocompleteContext.tsx +317 -0
  120. package/src/hooks/index.ts +23 -0
  121. package/src/hooks/useAutocomplete.test.ts +334 -0
  122. package/src/hooks/useAutocomplete.ts +466 -0
  123. package/src/hooks/useDragDrop.test.ts +355 -0
  124. package/src/hooks/useDragDrop.ts +379 -0
  125. package/src/hooks/useResize.test.ts +313 -0
  126. package/src/hooks/useResize.ts +372 -0
  127. package/src/index.ts +71 -0
  128. package/src/plugins/duckdb.ts +269 -0
  129. package/src/plugins/groq.ts +137 -0
  130. package/src/plugins/index.ts +14 -0
  131. package/src/plugins/rest.ts +147 -0
  132. package/src/plugins/supabase.ts +120 -0
  133. package/src/services/validation.ts +46 -0
  134. package/src/styles/autocomplete.css +356 -0
  135. package/src/styles/drag-drop.css +297 -0
  136. package/src/styles/index.css +7 -0
  137. package/src/types/index.ts +529 -0
  138. package/src/vite-env.d.ts +18 -0
  139. package/tsconfig.tsbuildinfo +1 -1
  140. package/vite.config.ts +2 -0
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ const DEFAULT_SYSTEM_PROMPT = `You are an autocomplete assistant. Given the user's partial input, provide a natural completion.
4
+ Rules:
5
+ - Complete the text naturally and concisely
6
+ - Return ONLY the completed text (including the original input)
7
+ - Do not add quotes, explanations, or additional text
8
+ - If unsure, return the original input unchanged`;
9
+ function createGroqPlugin(config) {
10
+ const {
11
+ apiKey,
12
+ model = "mixtral-8x7b-32768",
13
+ systemPrompt = DEFAULT_SYSTEM_PROMPT,
14
+ maxTokens = 50,
15
+ temperature = 0.3
16
+ } = config;
17
+ let isConfigured = !!apiKey;
18
+ return {
19
+ id: "groq",
20
+ name: "Groq LLM",
21
+ configure(newConfig) {
22
+ if (newConfig.apiKey) {
23
+ isConfigured = true;
24
+ }
25
+ },
26
+ isReady() {
27
+ return isConfigured;
28
+ },
29
+ async getSuggestions(input, context) {
30
+ var _a, _b, _c, _d;
31
+ if (!isConfigured) {
32
+ console.warn("[Groq Plugin] API key not configured");
33
+ return { type: "completion", completion: input };
34
+ }
35
+ if (!input.trim()) {
36
+ return { type: "completion", completion: "" };
37
+ }
38
+ try {
39
+ let userPrompt = `Complete this text: "${input}"`;
40
+ if (context == null ? void 0 : context.fieldName) {
41
+ userPrompt = `Field: ${context.fieldName}
42
+ Complete this text: "${input}"`;
43
+ }
44
+ if ((context == null ? void 0 : context.formData) && Object.keys(context.formData).length > 0) {
45
+ const formContext = Object.entries(context.formData).filter(([key, value]) => value && key !== context.fieldName).map(([key, value]) => `${key}: ${value}`).join(", ");
46
+ if (formContext) {
47
+ userPrompt = `Form context: ${formContext}
48
+ ${userPrompt}`;
49
+ }
50
+ }
51
+ const response = await fetch("https://api.groq.com/openai/v1/chat/completions", {
52
+ method: "POST",
53
+ headers: {
54
+ "Content-Type": "application/json",
55
+ "Authorization": `Bearer ${apiKey}`
56
+ },
57
+ body: JSON.stringify({
58
+ model,
59
+ messages: [
60
+ { role: "system", content: systemPrompt },
61
+ { role: "user", content: userPrompt }
62
+ ],
63
+ max_tokens: maxTokens,
64
+ temperature,
65
+ stream: false
66
+ })
67
+ });
68
+ if (!response.ok) {
69
+ const errorText = await response.text();
70
+ console.error("[Groq Plugin] API error:", response.status, errorText);
71
+ return { type: "completion", completion: input };
72
+ }
73
+ const data = await response.json();
74
+ const completion = ((_d = (_c = (_b = (_a = data.choices) == null ? void 0 : _a[0]) == null ? void 0 : _b.message) == null ? void 0 : _c.content) == null ? void 0 : _d.trim()) || input;
75
+ let cleanCompletion = completion;
76
+ if (cleanCompletion.startsWith('"') && cleanCompletion.endsWith('"')) {
77
+ cleanCompletion = cleanCompletion.slice(1, -1);
78
+ }
79
+ if (cleanCompletion.startsWith("'") && cleanCompletion.endsWith("'")) {
80
+ cleanCompletion = cleanCompletion.slice(1, -1);
81
+ }
82
+ return {
83
+ type: "completion",
84
+ completion: cleanCompletion
85
+ };
86
+ } catch (error) {
87
+ console.error("[Groq Plugin] Error:", error);
88
+ return { type: "completion", completion: input };
89
+ }
90
+ },
91
+ dispose() {
92
+ }
93
+ };
94
+ }
95
+ exports.createGroqPlugin = createGroqPlugin;
96
+ exports.default = createGroqPlugin;
97
+ //# sourceMappingURL=groq.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groq.cjs","sources":["../../src/plugins/groq.ts"],"sourcesContent":["/**\n * Groq LLM Autocomplete Plugin\n * Provides LLM-powered text completion suggestions using Groq API\n *\n * Sprint Autocomplete Feature\n */\n\nimport type {\n AutocompletePlugin,\n AutocompleteResult,\n AutocompleteContext,\n GroqPluginConfig\n} from '../types'\n\n/**\n * Default system prompt for completion\n */\nconst DEFAULT_SYSTEM_PROMPT = `You are an autocomplete assistant. Given the user's partial input, provide a natural completion.\nRules:\n- Complete the text naturally and concisely\n- Return ONLY the completed text (including the original input)\n- Do not add quotes, explanations, or additional text\n- If unsure, return the original input unchanged`\n\n/**\n * Create a Groq LLM autocomplete plugin\n */\nexport function createGroqPlugin(config: GroqPluginConfig): AutocompletePlugin {\n const {\n apiKey,\n model = 'mixtral-8x7b-32768',\n systemPrompt = DEFAULT_SYSTEM_PROMPT,\n maxTokens = 50,\n temperature = 0.3\n } = config\n\n let isConfigured = !!apiKey\n\n return {\n id: 'groq',\n name: 'Groq LLM',\n\n configure(newConfig: Record<string, any>) {\n if (newConfig.apiKey) {\n isConfigured = true\n }\n },\n\n isReady() {\n return isConfigured\n },\n\n async getSuggestions(\n input: string,\n context?: AutocompleteContext\n ): Promise<AutocompleteResult> {\n if (!isConfigured) {\n console.warn('[Groq Plugin] API key not configured')\n return { type: 'completion', completion: input }\n }\n\n if (!input.trim()) {\n return { type: 'completion', completion: '' }\n }\n\n try {\n // Build context-aware prompt\n let userPrompt = `Complete this text: \"${input}\"`\n\n if (context?.fieldName) {\n userPrompt = `Field: ${context.fieldName}\\nComplete this text: \"${input}\"`\n }\n\n if (context?.formData && Object.keys(context.formData).length > 0) {\n const formContext = Object.entries(context.formData)\n .filter(([key, value]) => value && key !== context.fieldName)\n .map(([key, value]) => `${key}: ${value}`)\n .join(', ')\n\n if (formContext) {\n userPrompt = `Form context: ${formContext}\\n${userPrompt}`\n }\n }\n\n const response = await fetch('https://api.groq.com/openai/v1/chat/completions', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`\n },\n body: JSON.stringify({\n model,\n messages: [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt }\n ],\n max_tokens: maxTokens,\n temperature,\n stream: false\n })\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n console.error('[Groq Plugin] API error:', response.status, errorText)\n return { type: 'completion', completion: input }\n }\n\n const data = await response.json()\n const completion = data.choices?.[0]?.message?.content?.trim() || input\n\n // Clean up the completion (remove quotes if present)\n let cleanCompletion = completion\n if (cleanCompletion.startsWith('\"') && cleanCompletion.endsWith('\"')) {\n cleanCompletion = cleanCompletion.slice(1, -1)\n }\n if (cleanCompletion.startsWith(\"'\") && cleanCompletion.endsWith(\"'\")) {\n cleanCompletion = cleanCompletion.slice(1, -1)\n }\n\n return {\n type: 'completion',\n completion: cleanCompletion\n }\n } catch (error) {\n console.error('[Groq Plugin] Error:', error)\n return { type: 'completion', completion: input }\n }\n },\n\n dispose() {\n // No cleanup needed\n }\n }\n}\n\nexport default createGroqPlugin\n"],"names":[],"mappings":";;AAiBA,MAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAUvB,SAAS,iBAAiB,QAA8C;AAC7E,QAAM;AAAA,IACJ;AAAA,IACA,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,cAAc;AAAA,EAAA,IACZ;AAEJ,MAAI,eAAe,CAAC,CAAC;AAErB,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IAEN,UAAU,WAAgC;AACxC,UAAI,UAAU,QAAQ;AACpB,uBAAe;AAAA,MACjB;AAAA,IACF;AAAA,IAEA,UAAU;AACR,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,eACJ,OACA,SAC6B;;AAC7B,UAAI,CAAC,cAAc;AACjB,gBAAQ,KAAK,sCAAsC;AACnD,eAAO,EAAE,MAAM,cAAc,YAAY,MAAA;AAAA,MAC3C;AAEA,UAAI,CAAC,MAAM,QAAQ;AACjB,eAAO,EAAE,MAAM,cAAc,YAAY,GAAA;AAAA,MAC3C;AAEA,UAAI;AAEF,YAAI,aAAa,wBAAwB,KAAK;AAE9C,YAAI,mCAAS,WAAW;AACtB,uBAAa,UAAU,QAAQ,SAAS;AAAA,uBAA0B,KAAK;AAAA,QACzE;AAEA,aAAI,mCAAS,aAAY,OAAO,KAAK,QAAQ,QAAQ,EAAE,SAAS,GAAG;AACjE,gBAAM,cAAc,OAAO,QAAQ,QAAQ,QAAQ,EAChD,OAAO,CAAC,CAAC,KAAK,KAAK,MAAM,SAAS,QAAQ,QAAQ,SAAS,EAC3D,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,GAAG,KAAK,KAAK,EAAE,EACxC,KAAK,IAAI;AAEZ,cAAI,aAAa;AACf,yBAAa,iBAAiB,WAAW;AAAA,EAAK,UAAU;AAAA,UAC1D;AAAA,QACF;AAEA,cAAM,WAAW,MAAM,MAAM,mDAAmD;AAAA,UAC9E,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,iBAAiB,UAAU,MAAM;AAAA,UAAA;AAAA,UAEnC,MAAM,KAAK,UAAU;AAAA,YACnB;AAAA,YACA,UAAU;AAAA,cACR,EAAE,MAAM,UAAU,SAAS,aAAA;AAAA,cAC3B,EAAE,MAAM,QAAQ,SAAS,WAAA;AAAA,YAAW;AAAA,YAEtC,YAAY;AAAA,YACZ;AAAA,YACA,QAAQ;AAAA,UAAA,CACT;AAAA,QAAA,CACF;AAED,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,YAAY,MAAM,SAAS,KAAA;AACjC,kBAAQ,MAAM,4BAA4B,SAAS,QAAQ,SAAS;AACpE,iBAAO,EAAE,MAAM,cAAc,YAAY,MAAA;AAAA,QAC3C;AAEA,cAAM,OAAO,MAAM,SAAS,KAAA;AAC5B,cAAM,eAAa,4BAAK,YAAL,mBAAe,OAAf,mBAAmB,YAAnB,mBAA4B,YAA5B,mBAAqC,WAAU;AAGlE,YAAI,kBAAkB;AACtB,YAAI,gBAAgB,WAAW,GAAG,KAAK,gBAAgB,SAAS,GAAG,GAAG;AACpE,4BAAkB,gBAAgB,MAAM,GAAG,EAAE;AAAA,QAC/C;AACA,YAAI,gBAAgB,WAAW,GAAG,KAAK,gBAAgB,SAAS,GAAG,GAAG;AACpE,4BAAkB,gBAAgB,MAAM,GAAG,EAAE;AAAA,QAC/C;AAEA,eAAO;AAAA,UACL,MAAM;AAAA,UACN,YAAY;AAAA,QAAA;AAAA,MAEhB,SAAS,OAAO;AACd,gBAAQ,MAAM,wBAAwB,KAAK;AAC3C,eAAO,EAAE,MAAM,cAAc,YAAY,MAAA;AAAA,MAC3C;AAAA,IACF;AAAA,IAEA,UAAU;AAAA,IAEV;AAAA,EAAA;AAEJ;;;"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Groq LLM Autocomplete Plugin
3
+ * Provides LLM-powered text completion suggestions using Groq API
4
+ *
5
+ * Sprint Autocomplete Feature
6
+ */
7
+ import type { AutocompletePlugin, GroqPluginConfig } from '../types';
8
+ /**
9
+ * Create a Groq LLM autocomplete plugin
10
+ */
11
+ export declare function createGroqPlugin(config: GroqPluginConfig): AutocompletePlugin;
12
+ export default createGroqPlugin;
13
+ //# sourceMappingURL=groq.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groq.d.ts","sourceRoot":"","sources":["../../src/plugins/groq.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAGlB,gBAAgB,EACjB,MAAM,UAAU,CAAA;AAYjB;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,kBAAkB,CA2G7E;AAED,eAAe,gBAAgB,CAAA"}
@@ -0,0 +1,97 @@
1
+ const DEFAULT_SYSTEM_PROMPT = `You are an autocomplete assistant. Given the user's partial input, provide a natural completion.
2
+ Rules:
3
+ - Complete the text naturally and concisely
4
+ - Return ONLY the completed text (including the original input)
5
+ - Do not add quotes, explanations, or additional text
6
+ - If unsure, return the original input unchanged`;
7
+ function createGroqPlugin(config) {
8
+ const {
9
+ apiKey,
10
+ model = "mixtral-8x7b-32768",
11
+ systemPrompt = DEFAULT_SYSTEM_PROMPT,
12
+ maxTokens = 50,
13
+ temperature = 0.3
14
+ } = config;
15
+ let isConfigured = !!apiKey;
16
+ return {
17
+ id: "groq",
18
+ name: "Groq LLM",
19
+ configure(newConfig) {
20
+ if (newConfig.apiKey) {
21
+ isConfigured = true;
22
+ }
23
+ },
24
+ isReady() {
25
+ return isConfigured;
26
+ },
27
+ async getSuggestions(input, context) {
28
+ var _a, _b, _c, _d;
29
+ if (!isConfigured) {
30
+ console.warn("[Groq Plugin] API key not configured");
31
+ return { type: "completion", completion: input };
32
+ }
33
+ if (!input.trim()) {
34
+ return { type: "completion", completion: "" };
35
+ }
36
+ try {
37
+ let userPrompt = `Complete this text: "${input}"`;
38
+ if (context == null ? void 0 : context.fieldName) {
39
+ userPrompt = `Field: ${context.fieldName}
40
+ Complete this text: "${input}"`;
41
+ }
42
+ if ((context == null ? void 0 : context.formData) && Object.keys(context.formData).length > 0) {
43
+ const formContext = Object.entries(context.formData).filter(([key, value]) => value && key !== context.fieldName).map(([key, value]) => `${key}: ${value}`).join(", ");
44
+ if (formContext) {
45
+ userPrompt = `Form context: ${formContext}
46
+ ${userPrompt}`;
47
+ }
48
+ }
49
+ const response = await fetch("https://api.groq.com/openai/v1/chat/completions", {
50
+ method: "POST",
51
+ headers: {
52
+ "Content-Type": "application/json",
53
+ "Authorization": `Bearer ${apiKey}`
54
+ },
55
+ body: JSON.stringify({
56
+ model,
57
+ messages: [
58
+ { role: "system", content: systemPrompt },
59
+ { role: "user", content: userPrompt }
60
+ ],
61
+ max_tokens: maxTokens,
62
+ temperature,
63
+ stream: false
64
+ })
65
+ });
66
+ if (!response.ok) {
67
+ const errorText = await response.text();
68
+ console.error("[Groq Plugin] API error:", response.status, errorText);
69
+ return { type: "completion", completion: input };
70
+ }
71
+ const data = await response.json();
72
+ const completion = ((_d = (_c = (_b = (_a = data.choices) == null ? void 0 : _a[0]) == null ? void 0 : _b.message) == null ? void 0 : _c.content) == null ? void 0 : _d.trim()) || input;
73
+ let cleanCompletion = completion;
74
+ if (cleanCompletion.startsWith('"') && cleanCompletion.endsWith('"')) {
75
+ cleanCompletion = cleanCompletion.slice(1, -1);
76
+ }
77
+ if (cleanCompletion.startsWith("'") && cleanCompletion.endsWith("'")) {
78
+ cleanCompletion = cleanCompletion.slice(1, -1);
79
+ }
80
+ return {
81
+ type: "completion",
82
+ completion: cleanCompletion
83
+ };
84
+ } catch (error) {
85
+ console.error("[Groq Plugin] Error:", error);
86
+ return { type: "completion", completion: input };
87
+ }
88
+ },
89
+ dispose() {
90
+ }
91
+ };
92
+ }
93
+ export {
94
+ createGroqPlugin,
95
+ createGroqPlugin as default
96
+ };
97
+ //# sourceMappingURL=groq.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groq.js","sources":["../../src/plugins/groq.ts"],"sourcesContent":["/**\n * Groq LLM Autocomplete Plugin\n * Provides LLM-powered text completion suggestions using Groq API\n *\n * Sprint Autocomplete Feature\n */\n\nimport type {\n AutocompletePlugin,\n AutocompleteResult,\n AutocompleteContext,\n GroqPluginConfig\n} from '../types'\n\n/**\n * Default system prompt for completion\n */\nconst DEFAULT_SYSTEM_PROMPT = `You are an autocomplete assistant. Given the user's partial input, provide a natural completion.\nRules:\n- Complete the text naturally and concisely\n- Return ONLY the completed text (including the original input)\n- Do not add quotes, explanations, or additional text\n- If unsure, return the original input unchanged`\n\n/**\n * Create a Groq LLM autocomplete plugin\n */\nexport function createGroqPlugin(config: GroqPluginConfig): AutocompletePlugin {\n const {\n apiKey,\n model = 'mixtral-8x7b-32768',\n systemPrompt = DEFAULT_SYSTEM_PROMPT,\n maxTokens = 50,\n temperature = 0.3\n } = config\n\n let isConfigured = !!apiKey\n\n return {\n id: 'groq',\n name: 'Groq LLM',\n\n configure(newConfig: Record<string, any>) {\n if (newConfig.apiKey) {\n isConfigured = true\n }\n },\n\n isReady() {\n return isConfigured\n },\n\n async getSuggestions(\n input: string,\n context?: AutocompleteContext\n ): Promise<AutocompleteResult> {\n if (!isConfigured) {\n console.warn('[Groq Plugin] API key not configured')\n return { type: 'completion', completion: input }\n }\n\n if (!input.trim()) {\n return { type: 'completion', completion: '' }\n }\n\n try {\n // Build context-aware prompt\n let userPrompt = `Complete this text: \"${input}\"`\n\n if (context?.fieldName) {\n userPrompt = `Field: ${context.fieldName}\\nComplete this text: \"${input}\"`\n }\n\n if (context?.formData && Object.keys(context.formData).length > 0) {\n const formContext = Object.entries(context.formData)\n .filter(([key, value]) => value && key !== context.fieldName)\n .map(([key, value]) => `${key}: ${value}`)\n .join(', ')\n\n if (formContext) {\n userPrompt = `Form context: ${formContext}\\n${userPrompt}`\n }\n }\n\n const response = await fetch('https://api.groq.com/openai/v1/chat/completions', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`\n },\n body: JSON.stringify({\n model,\n messages: [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt }\n ],\n max_tokens: maxTokens,\n temperature,\n stream: false\n })\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n console.error('[Groq Plugin] API error:', response.status, errorText)\n return { type: 'completion', completion: input }\n }\n\n const data = await response.json()\n const completion = data.choices?.[0]?.message?.content?.trim() || input\n\n // Clean up the completion (remove quotes if present)\n let cleanCompletion = completion\n if (cleanCompletion.startsWith('\"') && cleanCompletion.endsWith('\"')) {\n cleanCompletion = cleanCompletion.slice(1, -1)\n }\n if (cleanCompletion.startsWith(\"'\") && cleanCompletion.endsWith(\"'\")) {\n cleanCompletion = cleanCompletion.slice(1, -1)\n }\n\n return {\n type: 'completion',\n completion: cleanCompletion\n }\n } catch (error) {\n console.error('[Groq Plugin] Error:', error)\n return { type: 'completion', completion: input }\n }\n },\n\n dispose() {\n // No cleanup needed\n }\n }\n}\n\nexport default createGroqPlugin\n"],"names":[],"mappings":"AAiBA,MAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAUvB,SAAS,iBAAiB,QAA8C;AAC7E,QAAM;AAAA,IACJ;AAAA,IACA,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,cAAc;AAAA,EAAA,IACZ;AAEJ,MAAI,eAAe,CAAC,CAAC;AAErB,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IAEN,UAAU,WAAgC;AACxC,UAAI,UAAU,QAAQ;AACpB,uBAAe;AAAA,MACjB;AAAA,IACF;AAAA,IAEA,UAAU;AACR,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,eACJ,OACA,SAC6B;AAtCnC;AAuCM,UAAI,CAAC,cAAc;AACjB,gBAAQ,KAAK,sCAAsC;AACnD,eAAO,EAAE,MAAM,cAAc,YAAY,MAAA;AAAA,MAC3C;AAEA,UAAI,CAAC,MAAM,QAAQ;AACjB,eAAO,EAAE,MAAM,cAAc,YAAY,GAAA;AAAA,MAC3C;AAEA,UAAI;AAEF,YAAI,aAAa,wBAAwB,KAAK;AAE9C,YAAI,mCAAS,WAAW;AACtB,uBAAa,UAAU,QAAQ,SAAS;AAAA,uBAA0B,KAAK;AAAA,QACzE;AAEA,aAAI,mCAAS,aAAY,OAAO,KAAK,QAAQ,QAAQ,EAAE,SAAS,GAAG;AACjE,gBAAM,cAAc,OAAO,QAAQ,QAAQ,QAAQ,EAChD,OAAO,CAAC,CAAC,KAAK,KAAK,MAAM,SAAS,QAAQ,QAAQ,SAAS,EAC3D,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,GAAG,KAAK,KAAK,EAAE,EACxC,KAAK,IAAI;AAEZ,cAAI,aAAa;AACf,yBAAa,iBAAiB,WAAW;AAAA,EAAK,UAAU;AAAA,UAC1D;AAAA,QACF;AAEA,cAAM,WAAW,MAAM,MAAM,mDAAmD;AAAA,UAC9E,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,iBAAiB,UAAU,MAAM;AAAA,UAAA;AAAA,UAEnC,MAAM,KAAK,UAAU;AAAA,YACnB;AAAA,YACA,UAAU;AAAA,cACR,EAAE,MAAM,UAAU,SAAS,aAAA;AAAA,cAC3B,EAAE,MAAM,QAAQ,SAAS,WAAA;AAAA,YAAW;AAAA,YAEtC,YAAY;AAAA,YACZ;AAAA,YACA,QAAQ;AAAA,UAAA,CACT;AAAA,QAAA,CACF;AAED,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,YAAY,MAAM,SAAS,KAAA;AACjC,kBAAQ,MAAM,4BAA4B,SAAS,QAAQ,SAAS;AACpE,iBAAO,EAAE,MAAM,cAAc,YAAY,MAAA;AAAA,QAC3C;AAEA,cAAM,OAAO,MAAM,SAAS,KAAA;AAC5B,cAAM,eAAa,4BAAK,YAAL,mBAAe,OAAf,mBAAmB,YAAnB,mBAA4B,YAA5B,mBAAqC,WAAU;AAGlE,YAAI,kBAAkB;AACtB,YAAI,gBAAgB,WAAW,GAAG,KAAK,gBAAgB,SAAS,GAAG,GAAG;AACpE,4BAAkB,gBAAgB,MAAM,GAAG,EAAE;AAAA,QAC/C;AACA,YAAI,gBAAgB,WAAW,GAAG,KAAK,gBAAgB,SAAS,GAAG,GAAG;AACpE,4BAAkB,gBAAgB,MAAM,GAAG,EAAE;AAAA,QAC/C;AAEA,eAAO;AAAA,UACL,MAAM;AAAA,UACN,YAAY;AAAA,QAAA;AAAA,MAEhB,SAAS,OAAO;AACd,gBAAQ,MAAM,wBAAwB,KAAK;AAC3C,eAAO,EAAE,MAAM,cAAc,YAAY,MAAA;AAAA,MAC3C;AAAA,IACF;AAAA,IAEA,UAAU;AAAA,IAEV;AAAA,EAAA;AAEJ;"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Autocomplete Plugins Index
3
+ * Re-exports all available autocomplete plugins
4
+ *
5
+ * Sprint Autocomplete Feature
6
+ */
7
+ export { createGroqPlugin } from './groq';
8
+ export { createSupabasePlugin } from './supabase';
9
+ export { createRestPlugin } from './rest';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAA;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAA"}
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ function getByPath(obj, path) {
4
+ return path.split(".").reduce((current, key) => current == null ? void 0 : current[key], obj);
5
+ }
6
+ function defaultTransform(data, valueField, labelField) {
7
+ return data.map((item) => ({
8
+ value: String(item[valueField] ?? item.value ?? item.id ?? ""),
9
+ label: String(item[labelField] ?? item.label ?? item.name ?? item[valueField] ?? ""),
10
+ metadata: item
11
+ }));
12
+ }
13
+ function createRestPlugin(config) {
14
+ const {
15
+ endpoint,
16
+ method = "GET",
17
+ headers = {},
18
+ bodyTemplate,
19
+ transform,
20
+ resultPath,
21
+ valueField = "value",
22
+ labelField = "label"
23
+ } = config;
24
+ return {
25
+ id: "rest",
26
+ name: "REST API",
27
+ configure(newConfig) {
28
+ Object.assign(config, newConfig);
29
+ },
30
+ isReady() {
31
+ return !!endpoint;
32
+ },
33
+ async getSuggestions(input, _context) {
34
+ if (!endpoint) {
35
+ console.warn("[REST Plugin] Endpoint not configured");
36
+ return { type: "options", options: [] };
37
+ }
38
+ if (!input.trim()) {
39
+ return { type: "options", options: [] };
40
+ }
41
+ try {
42
+ const url = endpoint.replace(/\{search\}/g, encodeURIComponent(input));
43
+ const requestOptions = {
44
+ method,
45
+ headers: {
46
+ "Content-Type": "application/json",
47
+ ...headers
48
+ }
49
+ };
50
+ if (method === "POST" && bodyTemplate) {
51
+ const body = bodyTemplate.replace(/\{search\}/g, input);
52
+ requestOptions.body = body;
53
+ } else if (method === "POST") {
54
+ requestOptions.body = JSON.stringify({ search: input });
55
+ }
56
+ const response = await fetch(url, requestOptions);
57
+ if (!response.ok) {
58
+ const errorText = await response.text();
59
+ console.error("[REST Plugin] API error:", response.status, errorText);
60
+ return { type: "options", options: [] };
61
+ }
62
+ const data = await response.json();
63
+ let results = resultPath ? getByPath(data, resultPath) : data;
64
+ if (!Array.isArray(results)) {
65
+ if (results && typeof results === "object") {
66
+ results = results.data || results.results || results.items || [results];
67
+ } else {
68
+ results = [];
69
+ }
70
+ }
71
+ let options;
72
+ if (transform) {
73
+ options = transform(results);
74
+ } else {
75
+ options = defaultTransform(results, valueField, labelField);
76
+ }
77
+ return {
78
+ type: "options",
79
+ options
80
+ };
81
+ } catch (error) {
82
+ console.error("[REST Plugin] Error:", error);
83
+ return { type: "options", options: [] };
84
+ }
85
+ },
86
+ dispose() {
87
+ }
88
+ };
89
+ }
90
+ exports.createRestPlugin = createRestPlugin;
91
+ exports.default = createRestPlugin;
92
+ //# sourceMappingURL=rest.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest.cjs","sources":["../../src/plugins/rest.ts"],"sourcesContent":["/**\n * REST API Autocomplete Plugin\n * Provides suggestions from any REST API endpoint\n *\n * Sprint Autocomplete Feature\n */\n\nimport type {\n AutocompletePlugin,\n AutocompleteResult,\n AutocompleteContext,\n AutocompleteOption,\n RestPluginConfig\n} from '../types'\n\n/**\n * Get value at path (e.g., \"data.results\" -> obj.data.results)\n */\nfunction getByPath(obj: any, path: string): any {\n return path.split('.').reduce((current, key) => current?.[key], obj)\n}\n\n/**\n * Default transform function\n */\nfunction defaultTransform(\n data: any[],\n valueField: string,\n labelField: string\n): AutocompleteOption[] {\n return data.map(item => ({\n value: String(item[valueField] ?? item.value ?? item.id ?? ''),\n label: String(item[labelField] ?? item.label ?? item.name ?? item[valueField] ?? ''),\n metadata: item\n }))\n}\n\n/**\n * Create a REST API autocomplete plugin\n */\nexport function createRestPlugin(config: RestPluginConfig): AutocompletePlugin {\n const {\n endpoint,\n method = 'GET',\n headers = {},\n bodyTemplate,\n transform,\n resultPath,\n valueField = 'value',\n labelField = 'label'\n } = config\n\n return {\n id: 'rest',\n name: 'REST API',\n\n configure(newConfig: Record<string, any>) {\n Object.assign(config, newConfig)\n },\n\n isReady() {\n return !!endpoint\n },\n\n async getSuggestions(\n input: string,\n _context?: AutocompleteContext\n ): Promise<AutocompleteResult> {\n if (!endpoint) {\n console.warn('[REST Plugin] Endpoint not configured')\n return { type: 'options', options: [] }\n }\n\n if (!input.trim()) {\n return { type: 'options', options: [] }\n }\n\n try {\n // Build URL with search placeholder\n const url = endpoint.replace(/\\{search\\}/g, encodeURIComponent(input))\n\n // Build request options\n const requestOptions: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...headers\n }\n }\n\n // Add body for POST requests\n if (method === 'POST' && bodyTemplate) {\n const body = bodyTemplate.replace(/\\{search\\}/g, input)\n requestOptions.body = body\n } else if (method === 'POST') {\n requestOptions.body = JSON.stringify({ search: input })\n }\n\n const response = await fetch(url, requestOptions)\n\n if (!response.ok) {\n const errorText = await response.text()\n console.error('[REST Plugin] API error:', response.status, errorText)\n return { type: 'options', options: [] }\n }\n\n const data = await response.json()\n\n // Extract results from path if specified\n let results = resultPath ? getByPath(data, resultPath) : data\n\n // Ensure results is an array\n if (!Array.isArray(results)) {\n if (results && typeof results === 'object') {\n // Try common result structures\n results = results.data || results.results || results.items || [results]\n } else {\n results = []\n }\n }\n\n // Transform results to options\n let options: AutocompleteOption[]\n\n if (transform) {\n options = transform(results)\n } else {\n options = defaultTransform(results, valueField, labelField)\n }\n\n return {\n type: 'options',\n options\n }\n } catch (error) {\n console.error('[REST Plugin] Error:', error)\n return { type: 'options', options: [] }\n }\n },\n\n dispose() {\n // No cleanup needed\n }\n }\n}\n\nexport default createRestPlugin\n"],"names":[],"mappings":";;AAkBA,SAAS,UAAU,KAAU,MAAmB;AAC9C,SAAO,KAAK,MAAM,GAAG,EAAE,OAAO,CAAC,SAAS,QAAQ,mCAAU,MAAM,GAAG;AACrE;AAKA,SAAS,iBACP,MACA,YACA,YACsB;AACtB,SAAO,KAAK,IAAI,CAAA,UAAS;AAAA,IACvB,OAAO,OAAO,KAAK,UAAU,KAAK,KAAK,SAAS,KAAK,MAAM,EAAE;AAAA,IAC7D,OAAO,OAAO,KAAK,UAAU,KAAK,KAAK,SAAS,KAAK,QAAQ,KAAK,UAAU,KAAK,EAAE;AAAA,IACnF,UAAU;AAAA,EAAA,EACV;AACJ;AAKO,SAAS,iBAAiB,QAA8C;AAC7E,QAAM;AAAA,IACJ;AAAA,IACA,SAAS;AAAA,IACT,UAAU,CAAA;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,EAAA,IACX;AAEJ,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IAEN,UAAU,WAAgC;AACxC,aAAO,OAAO,QAAQ,SAAS;AAAA,IACjC;AAAA,IAEA,UAAU;AACR,aAAO,CAAC,CAAC;AAAA,IACX;AAAA,IAEA,MAAM,eACJ,OACA,UAC6B;AAC7B,UAAI,CAAC,UAAU;AACb,gBAAQ,KAAK,uCAAuC;AACpD,eAAO,EAAE,MAAM,WAAW,SAAS,CAAA,EAAC;AAAA,MACtC;AAEA,UAAI,CAAC,MAAM,QAAQ;AACjB,eAAO,EAAE,MAAM,WAAW,SAAS,CAAA,EAAC;AAAA,MACtC;AAEA,UAAI;AAEF,cAAM,MAAM,SAAS,QAAQ,eAAe,mBAAmB,KAAK,CAAC;AAGrE,cAAM,iBAA8B;AAAA,UAClC;AAAA,UACA,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,GAAG;AAAA,UAAA;AAAA,QACL;AAIF,YAAI,WAAW,UAAU,cAAc;AACrC,gBAAM,OAAO,aAAa,QAAQ,eAAe,KAAK;AACtD,yBAAe,OAAO;AAAA,QACxB,WAAW,WAAW,QAAQ;AAC5B,yBAAe,OAAO,KAAK,UAAU,EAAE,QAAQ,OAAO;AAAA,QACxD;AAEA,cAAM,WAAW,MAAM,MAAM,KAAK,cAAc;AAEhD,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,YAAY,MAAM,SAAS,KAAA;AACjC,kBAAQ,MAAM,4BAA4B,SAAS,QAAQ,SAAS;AACpE,iBAAO,EAAE,MAAM,WAAW,SAAS,CAAA,EAAC;AAAA,QACtC;AAEA,cAAM,OAAO,MAAM,SAAS,KAAA;AAG5B,YAAI,UAAU,aAAa,UAAU,MAAM,UAAU,IAAI;AAGzD,YAAI,CAAC,MAAM,QAAQ,OAAO,GAAG;AAC3B,cAAI,WAAW,OAAO,YAAY,UAAU;AAE1C,sBAAU,QAAQ,QAAQ,QAAQ,WAAW,QAAQ,SAAS,CAAC,OAAO;AAAA,UACxE,OAAO;AACL,sBAAU,CAAA;AAAA,UACZ;AAAA,QACF;AAGA,YAAI;AAEJ,YAAI,WAAW;AACb,oBAAU,UAAU,OAAO;AAAA,QAC7B,OAAO;AACL,oBAAU,iBAAiB,SAAS,YAAY,UAAU;AAAA,QAC5D;AAEA,eAAO;AAAA,UACL,MAAM;AAAA,UACN;AAAA,QAAA;AAAA,MAEJ,SAAS,OAAO;AACd,gBAAQ,MAAM,wBAAwB,KAAK;AAC3C,eAAO,EAAE,MAAM,WAAW,SAAS,CAAA,EAAC;AAAA,MACtC;AAAA,IACF;AAAA,IAEA,UAAU;AAAA,IAEV;AAAA,EAAA;AAEJ;;;"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * REST API Autocomplete Plugin
3
+ * Provides suggestions from any REST API endpoint
4
+ *
5
+ * Sprint Autocomplete Feature
6
+ */
7
+ import type { AutocompletePlugin, RestPluginConfig } from '../types';
8
+ /**
9
+ * Create a REST API autocomplete plugin
10
+ */
11
+ export declare function createRestPlugin(config: RestPluginConfig): AutocompletePlugin;
12
+ export default createRestPlugin;
13
+ //# sourceMappingURL=rest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest.d.ts","sourceRoot":"","sources":["../../src/plugins/rest.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAIlB,gBAAgB,EACjB,MAAM,UAAU,CAAA;AAwBjB;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,kBAAkB,CAwG7E;AAED,eAAe,gBAAgB,CAAA"}
@@ -0,0 +1,92 @@
1
+ function getByPath(obj, path) {
2
+ return path.split(".").reduce((current, key) => current == null ? void 0 : current[key], obj);
3
+ }
4
+ function defaultTransform(data, valueField, labelField) {
5
+ return data.map((item) => ({
6
+ value: String(item[valueField] ?? item.value ?? item.id ?? ""),
7
+ label: String(item[labelField] ?? item.label ?? item.name ?? item[valueField] ?? ""),
8
+ metadata: item
9
+ }));
10
+ }
11
+ function createRestPlugin(config) {
12
+ const {
13
+ endpoint,
14
+ method = "GET",
15
+ headers = {},
16
+ bodyTemplate,
17
+ transform,
18
+ resultPath,
19
+ valueField = "value",
20
+ labelField = "label"
21
+ } = config;
22
+ return {
23
+ id: "rest",
24
+ name: "REST API",
25
+ configure(newConfig) {
26
+ Object.assign(config, newConfig);
27
+ },
28
+ isReady() {
29
+ return !!endpoint;
30
+ },
31
+ async getSuggestions(input, _context) {
32
+ if (!endpoint) {
33
+ console.warn("[REST Plugin] Endpoint not configured");
34
+ return { type: "options", options: [] };
35
+ }
36
+ if (!input.trim()) {
37
+ return { type: "options", options: [] };
38
+ }
39
+ try {
40
+ const url = endpoint.replace(/\{search\}/g, encodeURIComponent(input));
41
+ const requestOptions = {
42
+ method,
43
+ headers: {
44
+ "Content-Type": "application/json",
45
+ ...headers
46
+ }
47
+ };
48
+ if (method === "POST" && bodyTemplate) {
49
+ const body = bodyTemplate.replace(/\{search\}/g, input);
50
+ requestOptions.body = body;
51
+ } else if (method === "POST") {
52
+ requestOptions.body = JSON.stringify({ search: input });
53
+ }
54
+ const response = await fetch(url, requestOptions);
55
+ if (!response.ok) {
56
+ const errorText = await response.text();
57
+ console.error("[REST Plugin] API error:", response.status, errorText);
58
+ return { type: "options", options: [] };
59
+ }
60
+ const data = await response.json();
61
+ let results = resultPath ? getByPath(data, resultPath) : data;
62
+ if (!Array.isArray(results)) {
63
+ if (results && typeof results === "object") {
64
+ results = results.data || results.results || results.items || [results];
65
+ } else {
66
+ results = [];
67
+ }
68
+ }
69
+ let options;
70
+ if (transform) {
71
+ options = transform(results);
72
+ } else {
73
+ options = defaultTransform(results, valueField, labelField);
74
+ }
75
+ return {
76
+ type: "options",
77
+ options
78
+ };
79
+ } catch (error) {
80
+ console.error("[REST Plugin] Error:", error);
81
+ return { type: "options", options: [] };
82
+ }
83
+ },
84
+ dispose() {
85
+ }
86
+ };
87
+ }
88
+ export {
89
+ createRestPlugin,
90
+ createRestPlugin as default
91
+ };
92
+ //# sourceMappingURL=rest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest.js","sources":["../../src/plugins/rest.ts"],"sourcesContent":["/**\n * REST API Autocomplete Plugin\n * Provides suggestions from any REST API endpoint\n *\n * Sprint Autocomplete Feature\n */\n\nimport type {\n AutocompletePlugin,\n AutocompleteResult,\n AutocompleteContext,\n AutocompleteOption,\n RestPluginConfig\n} from '../types'\n\n/**\n * Get value at path (e.g., \"data.results\" -> obj.data.results)\n */\nfunction getByPath(obj: any, path: string): any {\n return path.split('.').reduce((current, key) => current?.[key], obj)\n}\n\n/**\n * Default transform function\n */\nfunction defaultTransform(\n data: any[],\n valueField: string,\n labelField: string\n): AutocompleteOption[] {\n return data.map(item => ({\n value: String(item[valueField] ?? item.value ?? item.id ?? ''),\n label: String(item[labelField] ?? item.label ?? item.name ?? item[valueField] ?? ''),\n metadata: item\n }))\n}\n\n/**\n * Create a REST API autocomplete plugin\n */\nexport function createRestPlugin(config: RestPluginConfig): AutocompletePlugin {\n const {\n endpoint,\n method = 'GET',\n headers = {},\n bodyTemplate,\n transform,\n resultPath,\n valueField = 'value',\n labelField = 'label'\n } = config\n\n return {\n id: 'rest',\n name: 'REST API',\n\n configure(newConfig: Record<string, any>) {\n Object.assign(config, newConfig)\n },\n\n isReady() {\n return !!endpoint\n },\n\n async getSuggestions(\n input: string,\n _context?: AutocompleteContext\n ): Promise<AutocompleteResult> {\n if (!endpoint) {\n console.warn('[REST Plugin] Endpoint not configured')\n return { type: 'options', options: [] }\n }\n\n if (!input.trim()) {\n return { type: 'options', options: [] }\n }\n\n try {\n // Build URL with search placeholder\n const url = endpoint.replace(/\\{search\\}/g, encodeURIComponent(input))\n\n // Build request options\n const requestOptions: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...headers\n }\n }\n\n // Add body for POST requests\n if (method === 'POST' && bodyTemplate) {\n const body = bodyTemplate.replace(/\\{search\\}/g, input)\n requestOptions.body = body\n } else if (method === 'POST') {\n requestOptions.body = JSON.stringify({ search: input })\n }\n\n const response = await fetch(url, requestOptions)\n\n if (!response.ok) {\n const errorText = await response.text()\n console.error('[REST Plugin] API error:', response.status, errorText)\n return { type: 'options', options: [] }\n }\n\n const data = await response.json()\n\n // Extract results from path if specified\n let results = resultPath ? getByPath(data, resultPath) : data\n\n // Ensure results is an array\n if (!Array.isArray(results)) {\n if (results && typeof results === 'object') {\n // Try common result structures\n results = results.data || results.results || results.items || [results]\n } else {\n results = []\n }\n }\n\n // Transform results to options\n let options: AutocompleteOption[]\n\n if (transform) {\n options = transform(results)\n } else {\n options = defaultTransform(results, valueField, labelField)\n }\n\n return {\n type: 'options',\n options\n }\n } catch (error) {\n console.error('[REST Plugin] Error:', error)\n return { type: 'options', options: [] }\n }\n },\n\n dispose() {\n // No cleanup needed\n }\n }\n}\n\nexport default createRestPlugin\n"],"names":[],"mappings":"AAkBA,SAAS,UAAU,KAAU,MAAmB;AAC9C,SAAO,KAAK,MAAM,GAAG,EAAE,OAAO,CAAC,SAAS,QAAQ,mCAAU,MAAM,GAAG;AACrE;AAKA,SAAS,iBACP,MACA,YACA,YACsB;AACtB,SAAO,KAAK,IAAI,CAAA,UAAS;AAAA,IACvB,OAAO,OAAO,KAAK,UAAU,KAAK,KAAK,SAAS,KAAK,MAAM,EAAE;AAAA,IAC7D,OAAO,OAAO,KAAK,UAAU,KAAK,KAAK,SAAS,KAAK,QAAQ,KAAK,UAAU,KAAK,EAAE;AAAA,IACnF,UAAU;AAAA,EAAA,EACV;AACJ;AAKO,SAAS,iBAAiB,QAA8C;AAC7E,QAAM;AAAA,IACJ;AAAA,IACA,SAAS;AAAA,IACT,UAAU,CAAA;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,EAAA,IACX;AAEJ,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IAEN,UAAU,WAAgC;AACxC,aAAO,OAAO,QAAQ,SAAS;AAAA,IACjC;AAAA,IAEA,UAAU;AACR,aAAO,CAAC,CAAC;AAAA,IACX;AAAA,IAEA,MAAM,eACJ,OACA,UAC6B;AAC7B,UAAI,CAAC,UAAU;AACb,gBAAQ,KAAK,uCAAuC;AACpD,eAAO,EAAE,MAAM,WAAW,SAAS,CAAA,EAAC;AAAA,MACtC;AAEA,UAAI,CAAC,MAAM,QAAQ;AACjB,eAAO,EAAE,MAAM,WAAW,SAAS,CAAA,EAAC;AAAA,MACtC;AAEA,UAAI;AAEF,cAAM,MAAM,SAAS,QAAQ,eAAe,mBAAmB,KAAK,CAAC;AAGrE,cAAM,iBAA8B;AAAA,UAClC;AAAA,UACA,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,GAAG;AAAA,UAAA;AAAA,QACL;AAIF,YAAI,WAAW,UAAU,cAAc;AACrC,gBAAM,OAAO,aAAa,QAAQ,eAAe,KAAK;AACtD,yBAAe,OAAO;AAAA,QACxB,WAAW,WAAW,QAAQ;AAC5B,yBAAe,OAAO,KAAK,UAAU,EAAE,QAAQ,OAAO;AAAA,QACxD;AAEA,cAAM,WAAW,MAAM,MAAM,KAAK,cAAc;AAEhD,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,YAAY,MAAM,SAAS,KAAA;AACjC,kBAAQ,MAAM,4BAA4B,SAAS,QAAQ,SAAS;AACpE,iBAAO,EAAE,MAAM,WAAW,SAAS,CAAA,EAAC;AAAA,QACtC;AAEA,cAAM,OAAO,MAAM,SAAS,KAAA;AAG5B,YAAI,UAAU,aAAa,UAAU,MAAM,UAAU,IAAI;AAGzD,YAAI,CAAC,MAAM,QAAQ,OAAO,GAAG;AAC3B,cAAI,WAAW,OAAO,YAAY,UAAU;AAE1C,sBAAU,QAAQ,QAAQ,QAAQ,WAAW,QAAQ,SAAS,CAAC,OAAO;AAAA,UACxE,OAAO;AACL,sBAAU,CAAA;AAAA,UACZ;AAAA,QACF;AAGA,YAAI;AAEJ,YAAI,WAAW;AACb,oBAAU,UAAU,OAAO;AAAA,QAC7B,OAAO;AACL,oBAAU,iBAAiB,SAAS,YAAY,UAAU;AAAA,QAC5D;AAEA,eAAO;AAAA,UACL,MAAM;AAAA,UACN;AAAA,QAAA;AAAA,MAEJ,SAAS,OAAO;AACd,gBAAQ,MAAM,wBAAwB,KAAK;AAC3C,eAAO,EAAE,MAAM,WAAW,SAAS,CAAA,EAAC;AAAA,MACtC;AAAA,IACF;AAAA,IAEA,UAAU;AAAA,IAEV;AAAA,EAAA;AAEJ;"}
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ function createSupabasePlugin(config) {
4
+ const {
5
+ url,
6
+ anonKey,
7
+ table,
8
+ column,
9
+ searchColumn,
10
+ labelColumn,
11
+ limit = 10,
12
+ filter
13
+ } = config;
14
+ const isConfigured = !!(url && anonKey && table && column);
15
+ const effectiveSearchColumn = searchColumn || column;
16
+ const effectiveLabelColumn = labelColumn || column;
17
+ return {
18
+ id: "supabase",
19
+ name: "Supabase",
20
+ configure(newConfig) {
21
+ Object.assign(config, newConfig);
22
+ },
23
+ isReady() {
24
+ return isConfigured;
25
+ },
26
+ async getSuggestions(input, _context) {
27
+ if (!isConfigured) {
28
+ console.warn("[Supabase Plugin] Not properly configured");
29
+ return { type: "options", options: [] };
30
+ }
31
+ if (!input.trim()) {
32
+ return { type: "options", options: [] };
33
+ }
34
+ try {
35
+ let queryUrl = `${url}/rest/v1/${table}?select=${column}`;
36
+ if (column !== effectiveLabelColumn) {
37
+ queryUrl += `,${effectiveLabelColumn}`;
38
+ }
39
+ queryUrl += `&${effectiveSearchColumn}=ilike.${encodeURIComponent(input)}%`;
40
+ queryUrl += `&limit=${limit}`;
41
+ if (filter) {
42
+ Object.entries(filter).forEach(([key, value]) => {
43
+ queryUrl += `&${key}=eq.${encodeURIComponent(String(value))}`;
44
+ });
45
+ }
46
+ const response = await fetch(queryUrl, {
47
+ headers: {
48
+ "apikey": anonKey,
49
+ "Authorization": `Bearer ${anonKey}`,
50
+ "Content-Type": "application/json"
51
+ }
52
+ });
53
+ if (!response.ok) {
54
+ const errorText = await response.text();
55
+ console.error("[Supabase Plugin] API error:", response.status, errorText);
56
+ return { type: "options", options: [] };
57
+ }
58
+ const data = await response.json();
59
+ const options = data.map((row) => ({
60
+ value: String(row[column]),
61
+ label: String(row[effectiveLabelColumn]),
62
+ metadata: row
63
+ }));
64
+ return {
65
+ type: "options",
66
+ options
67
+ };
68
+ } catch (error) {
69
+ console.error("[Supabase Plugin] Error:", error);
70
+ return { type: "options", options: [] };
71
+ }
72
+ },
73
+ dispose() {
74
+ }
75
+ };
76
+ }
77
+ exports.createSupabasePlugin = createSupabasePlugin;
78
+ exports.default = createSupabasePlugin;
79
+ //# sourceMappingURL=supabase.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase.cjs","sources":["../../src/plugins/supabase.ts"],"sourcesContent":["/**\n * Supabase Autocomplete Plugin\n * Provides data-driven suggestions from a Supabase table\n *\n * Sprint Autocomplete Feature\n */\n\nimport type {\n AutocompletePlugin,\n AutocompleteResult,\n AutocompleteContext,\n AutocompleteOption,\n SupabasePluginConfig\n} from '../types'\n\n/**\n * Create a Supabase autocomplete plugin\n */\nexport function createSupabasePlugin(config: SupabasePluginConfig): AutocompletePlugin {\n const {\n url,\n anonKey,\n table,\n column,\n searchColumn,\n labelColumn,\n limit = 10,\n filter\n } = config\n\n const isConfigured = !!(url && anonKey && table && column)\n const effectiveSearchColumn = searchColumn || column\n const effectiveLabelColumn = labelColumn || column\n\n return {\n id: 'supabase',\n name: 'Supabase',\n\n configure(newConfig: Record<string, any>) {\n // Allow runtime reconfiguration\n Object.assign(config, newConfig)\n },\n\n isReady() {\n return isConfigured\n },\n\n async getSuggestions(\n input: string,\n _context?: AutocompleteContext\n ): Promise<AutocompleteResult> {\n if (!isConfigured) {\n console.warn('[Supabase Plugin] Not properly configured')\n return { type: 'options', options: [] }\n }\n\n if (!input.trim()) {\n return { type: 'options', options: [] }\n }\n\n try {\n // Build query URL\n let queryUrl = `${url}/rest/v1/${table}?select=${column}`\n\n if (column !== effectiveLabelColumn) {\n queryUrl += `,${effectiveLabelColumn}`\n }\n\n // Add ILIKE filter for search\n queryUrl += `&${effectiveSearchColumn}=ilike.${encodeURIComponent(input)}%`\n\n // Add limit\n queryUrl += `&limit=${limit}`\n\n // Add custom filters\n if (filter) {\n Object.entries(filter).forEach(([key, value]) => {\n queryUrl += `&${key}=eq.${encodeURIComponent(String(value))}`\n })\n }\n\n const response = await fetch(queryUrl, {\n headers: {\n 'apikey': anonKey,\n 'Authorization': `Bearer ${anonKey}`,\n 'Content-Type': 'application/json'\n }\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n console.error('[Supabase Plugin] API error:', response.status, errorText)\n return { type: 'options', options: [] }\n }\n\n const data = await response.json()\n\n const options: AutocompleteOption[] = data.map((row: Record<string, any>) => ({\n value: String(row[column]),\n label: String(row[effectiveLabelColumn]),\n metadata: row\n }))\n\n return {\n type: 'options',\n options\n }\n } catch (error) {\n console.error('[Supabase Plugin] Error:', error)\n return { type: 'options', options: [] }\n }\n },\n\n dispose() {\n // No cleanup needed\n }\n }\n}\n\nexport default createSupabasePlugin\n"],"names":[],"mappings":";;AAkBO,SAAS,qBAAqB,QAAkD;AACrF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,EAAA,IACE;AAEJ,QAAM,eAAe,CAAC,EAAE,OAAO,WAAW,SAAS;AACnD,QAAM,wBAAwB,gBAAgB;AAC9C,QAAM,uBAAuB,eAAe;AAE5C,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IAEN,UAAU,WAAgC;AAExC,aAAO,OAAO,QAAQ,SAAS;AAAA,IACjC;AAAA,IAEA,UAAU;AACR,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,eACJ,OACA,UAC6B;AAC7B,UAAI,CAAC,cAAc;AACjB,gBAAQ,KAAK,2CAA2C;AACxD,eAAO,EAAE,MAAM,WAAW,SAAS,CAAA,EAAC;AAAA,MACtC;AAEA,UAAI,CAAC,MAAM,QAAQ;AACjB,eAAO,EAAE,MAAM,WAAW,SAAS,CAAA,EAAC;AAAA,MACtC;AAEA,UAAI;AAEF,YAAI,WAAW,GAAG,GAAG,YAAY,KAAK,WAAW,MAAM;AAEvD,YAAI,WAAW,sBAAsB;AACnC,sBAAY,IAAI,oBAAoB;AAAA,QACtC;AAGA,oBAAY,IAAI,qBAAqB,UAAU,mBAAmB,KAAK,CAAC;AAGxE,oBAAY,UAAU,KAAK;AAG3B,YAAI,QAAQ;AACV,iBAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAC/C,wBAAY,IAAI,GAAG,OAAO,mBAAmB,OAAO,KAAK,CAAC,CAAC;AAAA,UAC7D,CAAC;AAAA,QACH;AAEA,cAAM,WAAW,MAAM,MAAM,UAAU;AAAA,UACrC,SAAS;AAAA,YACP,UAAU;AAAA,YACV,iBAAiB,UAAU,OAAO;AAAA,YAClC,gBAAgB;AAAA,UAAA;AAAA,QAClB,CACD;AAED,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,YAAY,MAAM,SAAS,KAAA;AACjC,kBAAQ,MAAM,gCAAgC,SAAS,QAAQ,SAAS;AACxE,iBAAO,EAAE,MAAM,WAAW,SAAS,CAAA,EAAC;AAAA,QACtC;AAEA,cAAM,OAAO,MAAM,SAAS,KAAA;AAE5B,cAAM,UAAgC,KAAK,IAAI,CAAC,SAA8B;AAAA,UAC5E,OAAO,OAAO,IAAI,MAAM,CAAC;AAAA,UACzB,OAAO,OAAO,IAAI,oBAAoB,CAAC;AAAA,UACvC,UAAU;AAAA,QAAA,EACV;AAEF,eAAO;AAAA,UACL,MAAM;AAAA,UACN;AAAA,QAAA;AAAA,MAEJ,SAAS,OAAO;AACd,gBAAQ,MAAM,4BAA4B,KAAK;AAC/C,eAAO,EAAE,MAAM,WAAW,SAAS,CAAA,EAAC;AAAA,MACtC;AAAA,IACF;AAAA,IAEA,UAAU;AAAA,IAEV;AAAA,EAAA;AAEJ;;;"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Supabase Autocomplete Plugin
3
+ * Provides data-driven suggestions from a Supabase table
4
+ *
5
+ * Sprint Autocomplete Feature
6
+ */
7
+ import type { AutocompletePlugin, SupabasePluginConfig } from '../types';
8
+ /**
9
+ * Create a Supabase autocomplete plugin
10
+ */
11
+ export declare function createSupabasePlugin(config: SupabasePluginConfig): AutocompletePlugin;
12
+ export default createSupabasePlugin;
13
+ //# sourceMappingURL=supabase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/plugins/supabase.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAIlB,oBAAoB,EACrB,MAAM,UAAU,CAAA;AAEjB;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,kBAAkB,CAmGrF;AAED,eAAe,oBAAoB,CAAA"}