sparkecoder 0.1.99 → 0.1.100

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 (137) hide show
  1. package/README.md +41 -41
  2. package/dist/agent/index.js +17 -1
  3. package/dist/agent/index.js.map +1 -1
  4. package/dist/cli.js +17 -1
  5. package/dist/cli.js.map +1 -1
  6. package/dist/index.js +17 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/server/index.js +17 -1
  9. package/dist/server/index.js.map +1 -1
  10. package/package.json +1 -1
  11. package/web/.next/BUILD_ID +1 -1
  12. package/web/.next/standalone/web/.next/BUILD_ID +1 -1
  13. package/web/.next/standalone/web/.next/build-manifest.json +2 -2
  14. package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
  15. package/web/.next/standalone/web/.next/server/app/(main)/agents/page_client-reference-manifest.js +1 -1
  16. package/web/.next/standalone/web/.next/server/app/(main)/page_client-reference-manifest.js +1 -1
  17. package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page.js.nft.json +1 -1
  18. package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page_client-reference-manifest.js +1 -1
  19. package/web/.next/standalone/web/.next/server/app/(main)/settings/page_client-reference-manifest.js +1 -1
  20. package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
  21. package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
  22. package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  23. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  24. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  25. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  26. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  27. package/web/.next/standalone/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  28. package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
  29. package/web/.next/standalone/web/.next/server/app/_not-found.rsc +2 -2
  30. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  31. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  32. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  33. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  34. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  35. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  36. package/web/.next/standalone/web/.next/server/app/agents.html +1 -1
  37. package/web/.next/standalone/web/.next/server/app/agents.rsc +4 -4
  38. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +2 -2
  39. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents.segment.rsc +1 -1
  40. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p.segment.rsc +2 -2
  41. package/web/.next/standalone/web/.next/server/app/agents.segments/_full.segment.rsc +4 -4
  42. package/web/.next/standalone/web/.next/server/app/agents.segments/_head.segment.rsc +1 -1
  43. package/web/.next/standalone/web/.next/server/app/agents.segments/_index.segment.rsc +2 -2
  44. package/web/.next/standalone/web/.next/server/app/agents.segments/_tree.segment.rsc +1 -1
  45. package/web/.next/standalone/web/.next/server/app/docs/installation/page_client-reference-manifest.js +1 -1
  46. package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
  47. package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +3 -3
  48. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +3 -3
  49. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
  50. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +2 -2
  51. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
  52. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +2 -2
  53. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
  54. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +2 -2
  55. package/web/.next/standalone/web/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  56. package/web/.next/standalone/web/.next/server/app/docs/skills/page_client-reference-manifest.js +1 -1
  57. package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
  58. package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +3 -3
  59. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +3 -3
  60. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
  61. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +2 -2
  62. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
  63. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
  64. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
  65. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +2 -2
  66. package/web/.next/standalone/web/.next/server/app/docs/tools/page_client-reference-manifest.js +1 -1
  67. package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
  68. package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +3 -3
  69. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +3 -3
  70. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
  71. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +2 -2
  72. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
  73. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +2 -2
  74. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
  75. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +2 -2
  76. package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
  77. package/web/.next/standalone/web/.next/server/app/docs.rsc +3 -3
  78. package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +3 -3
  79. package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
  80. package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +2 -2
  81. package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
  82. package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +2 -2
  83. package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +2 -2
  84. package/web/.next/standalone/web/.next/server/app/index.html +1 -1
  85. package/web/.next/standalone/web/.next/server/app/index.rsc +4 -4
  86. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +2 -2
  87. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +2 -2
  88. package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +4 -4
  89. package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  90. package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +2 -2
  91. package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  92. package/web/.next/standalone/web/.next/server/app/settings.html +1 -1
  93. package/web/.next/standalone/web/.next/server/app/settings.rsc +4 -4
  94. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings/__PAGE__.segment.rsc +2 -2
  95. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings.segment.rsc +1 -1
  96. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p.segment.rsc +2 -2
  97. package/web/.next/standalone/web/.next/server/app/settings.segments/_full.segment.rsc +4 -4
  98. package/web/.next/standalone/web/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  99. package/web/.next/standalone/web/.next/server/app/settings.segments/_index.segment.rsc +2 -2
  100. package/web/.next/standalone/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  101. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_b57914d2._.js → 2374f_1f3f2d00._.js} +1 -1
  102. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_3b04c7b5._.js → 2374f_38945fd9._.js} +1 -1
  103. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_e6dbbf5d._.js → 2374f_570c34dc._.js} +1 -1
  104. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_db1d6704._.js → 2374f_9c560f3a._.js} +1 -1
  105. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_9e444fb0._.js → 2374f_a0d5caeb._.js} +1 -1
  106. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_7b7dd4c7._.js → 2374f_c87abaf4._.js} +1 -1
  107. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_5ee1ee50._.js → 2374f_d8122230._.js} +1 -1
  108. package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__6097da17._.js +1 -1
  109. package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__be5e2967._.js +1 -1
  110. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_c2c47039._.js → web_3b9a2423._.js} +2 -2
  111. package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
  112. package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
  113. package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
  114. package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
  115. package/web/.next/standalone/web/.next/static/chunks/4239395558fab3ef.js +1 -0
  116. package/web/.next/standalone/web/.next/static/chunks/{f50a66c24c564585.js → ae4bb24474ff1ed0.js} +1 -1
  117. package/web/.next/standalone/web/.next/static/chunks/{545725e4c1237026.js → fbdcbd65f9a38f4b.js} +1 -1
  118. package/web/.next/standalone/web/.next/static/static/chunks/4239395558fab3ef.js +1 -0
  119. package/web/.next/standalone/web/.next/static/static/chunks/{f50a66c24c564585.js → ae4bb24474ff1ed0.js} +1 -1
  120. package/web/.next/standalone/web/.next/static/static/chunks/{545725e4c1237026.js → fbdcbd65f9a38f4b.js} +1 -1
  121. package/web/.next/standalone/web/package-lock.json +7 -7
  122. package/web/.next/standalone/web/src/components/ai-elements/mention-input.tsx +125 -17
  123. package/web/.next/static/chunks/4239395558fab3ef.js +1 -0
  124. package/web/.next/static/chunks/{f50a66c24c564585.js → ae4bb24474ff1ed0.js} +1 -1
  125. package/web/.next/static/chunks/{545725e4c1237026.js → fbdcbd65f9a38f4b.js} +1 -1
  126. package/web/.next/standalone/web/.next/static/chunks/9fce2ce79c4c834e.js +0 -1
  127. package/web/.next/standalone/web/.next/static/static/chunks/9fce2ce79c4c834e.js +0 -1
  128. package/web/.next/static/chunks/9fce2ce79c4c834e.js +0 -1
  129. /package/web/.next/standalone/web/.next/static/{static/yyzMTo2RYusiXE0e1_kdc → eyxBRyMA8Zq36Pfen3Ylj}/_buildManifest.js +0 -0
  130. /package/web/.next/standalone/web/.next/static/{static/yyzMTo2RYusiXE0e1_kdc → eyxBRyMA8Zq36Pfen3Ylj}/_clientMiddlewareManifest.json +0 -0
  131. /package/web/.next/standalone/web/.next/static/{static/yyzMTo2RYusiXE0e1_kdc → eyxBRyMA8Zq36Pfen3Ylj}/_ssgManifest.js +0 -0
  132. /package/web/.next/standalone/web/.next/static/{yyzMTo2RYusiXE0e1_kdc → static/eyxBRyMA8Zq36Pfen3Ylj}/_buildManifest.js +0 -0
  133. /package/web/.next/standalone/web/.next/static/{yyzMTo2RYusiXE0e1_kdc → static/eyxBRyMA8Zq36Pfen3Ylj}/_clientMiddlewareManifest.json +0 -0
  134. /package/web/.next/standalone/web/.next/static/{yyzMTo2RYusiXE0e1_kdc → static/eyxBRyMA8Zq36Pfen3Ylj}/_ssgManifest.js +0 -0
  135. /package/web/.next/static/{yyzMTo2RYusiXE0e1_kdc → eyxBRyMA8Zq36Pfen3Ylj}/_buildManifest.js +0 -0
  136. /package/web/.next/static/{yyzMTo2RYusiXE0e1_kdc → eyxBRyMA8Zq36Pfen3Ylj}/_clientMiddlewareManifest.json +0 -0
  137. /package/web/.next/static/{yyzMTo2RYusiXE0e1_kdc → eyxBRyMA8Zq36Pfen3Ylj}/_ssgManifest.js +0 -0
@@ -59,8 +59,15 @@ export interface SlashCommand {
59
59
  action?: () => void;
60
60
  }
61
61
 
62
+ interface McpServer {
63
+ id: string;
64
+ name: string;
65
+ enabled: boolean;
66
+ transport: string;
67
+ }
68
+
62
69
  interface TriggerState {
63
- type: "file" | "command";
70
+ type: "file" | "command" | "mcp";
64
71
  query: string;
65
72
  startIndex: number; // Where the trigger character is
66
73
  endIndex: number; // Current cursor position
@@ -87,8 +94,9 @@ export function useMentionInput() {
87
94
  return ctx;
88
95
  }
89
96
 
90
- // Regex to match @mentions in text (matches @path/to/file or @folder/)
91
- const MENTION_REGEX = /@([\w./-]+\/?)/g;
97
+ // Regex to match @mentions in text. Captures both file-style (`@path/to/file`,
98
+ // `@folder/`) and MCP-style (`@mcp/<server-name>`).
99
+ const MENTION_REGEX = /@(mcp\/[\w-]+|[\w./-]+\/?)/g;
92
100
 
93
101
  // ============================================================================
94
102
  // Default Slash Commands - Each inserts a prompt template
@@ -311,6 +319,36 @@ export function MentionTextarea({
311
319
  limit: 15,
312
320
  });
313
321
 
322
+ // Fetch enabled MCP servers when either the dedicated @mcp trigger is
323
+ // active OR the user is typing a plain @<query> that might match a server
324
+ // name (e.g. `@gmail`, `@github`). Server names appear alongside files
325
+ // in the popover.
326
+ const [mcpServers, setMcpServers] = useState<McpServer[]>([]);
327
+ useEffect(() => {
328
+ if (trigger?.type !== "mcp" && trigger?.type !== "file") {
329
+ setMcpServers([]);
330
+ return;
331
+ }
332
+ let cancelled = false;
333
+ (async () => {
334
+ try {
335
+ const { getApiUrl } = await import("@/lib/config");
336
+ const res = await fetch(`${getApiUrl()}/api/mcp`);
337
+ if (!res.ok) return;
338
+ const data = await res.json();
339
+ if (cancelled) return;
340
+ const q = (trigger.query || "").toLowerCase();
341
+ const filtered: McpServer[] = (data.servers || [])
342
+ .filter((s: any) => s.enabled)
343
+ .filter((s: any) => !q || s.name.toLowerCase().includes(q));
344
+ setMcpServers(filtered);
345
+ } catch {
346
+ if (!cancelled) setMcpServers([]);
347
+ }
348
+ })();
349
+ return () => { cancelled = true; };
350
+ }, [trigger]);
351
+
314
352
  // Filter slash commands based on query
315
353
  const filteredCommands = useMemo(() => {
316
354
  if (trigger?.type !== "command") return [];
@@ -322,8 +360,14 @@ export function MentionTextarea({
322
360
  );
323
361
  }, [trigger, slashCommands]);
324
362
 
325
- // Current items to display
326
- const items = trigger?.type === "file" ? files : filteredCommands;
363
+ // Current items to display. For file mode we prepend any matching MCP
364
+ // servers so the same @-popover surfaces both. MCP names render in their
365
+ // own group above files (see CommandList below); we keep them sequenced
366
+ // first here so arrow-key navigation matches the visual order.
367
+ const items: Array<(typeof files)[0] | SlashCommand | McpServer> =
368
+ trigger?.type === "file" ? [...mcpServers, ...files]
369
+ : trigger?.type === "mcp" ? mcpServers
370
+ : filteredCommands;
327
371
  const showPopover = trigger !== null && (items.length > 0 || isLoading);
328
372
 
329
373
  // Calculate popover position based on textarea caret
@@ -408,6 +452,20 @@ export function MentionTextarea({
408
452
 
409
453
  const beforeCursor = text.slice(0, cursorPos);
410
454
 
455
+ // Check for @mcp trigger (MCP server mention). Supports `@mcp/<query>`,
456
+ // `@mcp:<query>`, and bare `@mcp` (no separator yet).
457
+ const mcpMatch = beforeCursor.match(/@mcp(?:[\/:]([^\s@]*))?$/i);
458
+ if (mcpMatch) {
459
+ setTrigger({
460
+ type: "mcp",
461
+ query: mcpMatch[1] ?? "",
462
+ startIndex: cursorPos - mcpMatch[0].length,
463
+ endIndex: cursorPos,
464
+ });
465
+ setSelectedIndex(0);
466
+ return;
467
+ }
468
+
411
469
  // Check for @ trigger (file mention)
412
470
  const atMatch = beforeCursor.match(/@([^\s@]*)$/);
413
471
  if (atMatch) {
@@ -453,9 +511,31 @@ export function MentionTextarea({
453
511
 
454
512
  // Handle selection from popover
455
513
  const handleSelect = useCallback(
456
- (item: (typeof files)[0] | SlashCommand) => {
514
+ (item: (typeof files)[0] | SlashCommand | McpServer) => {
457
515
  if (!trigger || !textareaRef.current) return;
458
516
 
517
+ // MCP server selection. Works under either the dedicated `@mcp/` trigger
518
+ // OR a plain `@<name>` file-trigger when the query happens to match a
519
+ // configured server (so `@gmail` works the same as `@mcp/gmail`).
520
+ if ("name" in item && "transport" in item) {
521
+ const mcp = item as McpServer;
522
+ const before = value.slice(0, trigger.startIndex);
523
+ const after = value.slice(trigger.endIndex);
524
+ const mentionText = `@mcp/${mcp.name} `;
525
+ const newValue = before + mentionText + after;
526
+ onChange(newValue);
527
+ setTimeout(() => {
528
+ if (textareaRef.current) {
529
+ const newPos = trigger.startIndex + mentionText.length;
530
+ textareaRef.current.selectionStart = newPos;
531
+ textareaRef.current.selectionEnd = newPos;
532
+ textareaRef.current.focus();
533
+ }
534
+ }, 0);
535
+ setTrigger(null);
536
+ return;
537
+ }
538
+
459
539
  if (trigger.type === "file" && "path" in item) {
460
540
  // Insert @path inline (replacing @query with @fullpath)
461
541
  const before = value.slice(0, trigger.startIndex);
@@ -711,30 +791,58 @@ export function MentionTextarea({
711
791
  <CommandEmpty>
712
792
  {trigger?.type === "file"
713
793
  ? "No files found"
794
+ : trigger?.type === "mcp"
795
+ ? "No MCP servers configured. Add one in Settings → MCP."
714
796
  : "No commands found"}
715
797
  </CommandEmpty>
716
798
  )}
717
- {trigger?.type === "file" && files.length > 0 && (
718
- <CommandGroup heading="Files & Folders">
719
- {files.map((file, index) => (
799
+ {(trigger?.type === "mcp" || trigger?.type === "file") && mcpServers.length > 0 && (
800
+ <CommandGroup heading="MCP servers">
801
+ {mcpServers.map((s, index) => (
720
802
  <CommandItem
721
- key={file.path}
722
- onSelect={() => handleSelect(file)}
803
+ key={s.id}
804
+ onSelect={() => handleSelect(s)}
723
805
  className={cn(
724
806
  "cursor-pointer",
725
807
  index === selectedIndex && "bg-accent"
726
808
  )}
727
809
  >
728
- {file.type === "folder" ? (
729
- <FolderIcon className="mr-2 size-4 text-blue-500" />
730
- ) : (
731
- <FileIcon className="mr-2 size-4 text-muted-foreground" />
732
- )}
733
- <span className="truncate">{file.path}</span>
810
+ <HashIcon className="mr-2 size-4 text-emerald-500" />
811
+ <div className="flex flex-col">
812
+ <span className="font-medium">{s.name}</span>
813
+ <span className="text-xs text-muted-foreground">{s.transport} · tools: mcp_{s.name}_*</span>
814
+ </div>
734
815
  </CommandItem>
735
816
  ))}
736
817
  </CommandGroup>
737
818
  )}
819
+ {trigger?.type === "file" && files.length > 0 && (
820
+ <CommandGroup heading="Files & Folders">
821
+ {files.map((file, fileIdx) => {
822
+ // In file mode the items array is [mcpServers, ...files],
823
+ // so the per-file selection index is offset by the number
824
+ // of MCP rows rendered above.
825
+ const idx = mcpServers.length + fileIdx;
826
+ return (
827
+ <CommandItem
828
+ key={file.path}
829
+ onSelect={() => handleSelect(file)}
830
+ className={cn(
831
+ "cursor-pointer",
832
+ idx === selectedIndex && "bg-accent"
833
+ )}
834
+ >
835
+ {file.type === "folder" ? (
836
+ <FolderIcon className="mr-2 size-4 text-blue-500" />
837
+ ) : (
838
+ <FileIcon className="mr-2 size-4 text-muted-foreground" />
839
+ )}
840
+ <span className="truncate">{file.path}</span>
841
+ </CommandItem>
842
+ );
843
+ })}
844
+ </CommandGroup>
845
+ )}
738
846
  {trigger?.type === "command" && filteredCommands.length > 0 && (
739
847
  <CommandGroup heading="Commands">
740
848
  {filteredCommands.map((cmd, index) => (
@@ -0,0 +1 @@
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,739963,e=>{"use strict";let o="sparkecoder_api_url",i="http://localhost:3141",a=!1;function t(){if(a)return;a=!0;let e=new URLSearchParams(window.location.search),i=e.get("apiUrl");if(i){localStorage.setItem(o,i),e.delete("apiUrl");let a=e.toString()?`${window.location.pathname}?${e.toString()}`:window.location.pathname;window.history.replaceState({},"",a),console.log(`[SparkECoder] API URL set to: ${i}`)}}function r(){return a||t(),localStorage.getItem(o)||i}function n(e){localStorage.setItem(o,e)}function l(){localStorage.removeItem(o)}let d={availableModels:[{id:"anthropic/claude-opus-4.7",name:"Claude Opus 4.7",provider:"Anthropic"},{id:"anthropic/claude-opus-4-6",name:"Claude Opus 4.6",provider:"Anthropic"},{id:"anthropic/claude-opus-4-5",name:"Claude Opus 4.5",provider:"Anthropic"},{id:"anthropic/claude-sonnet-4",name:"Claude Sonnet 4",provider:"Anthropic"},{id:"anthropic/claude-haiku-4-5",name:"Claude Haiku 4.5",provider:"Anthropic"},{id:"openai/gpt-5-2-codex",name:"GPT-5.2 Codex",provider:"OpenAI"},{id:"google/gemini-3-flash",name:"Gemini 3 Flash",provider:"Google"},{id:"xai/grok-code-fast-1",name:"Grok Code Fast",provider:"xAI"}],availableTools:[{id:"bash",name:"Bash",description:"Execute shell commands",dangerous:!0},{id:"write_file",name:"Write File",description:"Create or edit files",dangerous:!0},{id:"read_file",name:"Read File",description:"Read file contents",dangerous:!1}],defaultModel:"anthropic/claude-opus-4.7",defaultToolApprovals:{},serverConnected:!1,apiKeyConfigured:!1,apiBaseUrl:i};async function c(){let e=r();try{let o=new AbortController,i=setTimeout(()=>o.abort(),3e3),a=await fetch(`${e}/health`,{signal:o.signal});if(clearTimeout(i),!a.ok)return{...d,apiBaseUrl:e};let t=await a.json();return{...d,defaultModel:t.config?.defaultModel||d.defaultModel,defaultToolApprovals:t.config?.defaultToolApprovals||{},serverConnected:!0,apiKeyConfigured:t.apiKeyConfigured??!1,apiBaseUrl:e}}catch{return{...d,apiBaseUrl:e}}}async function p(){return r()}function s(){}e.s(["clearApiUrl",()=>l,"getApiBaseUrl",()=>p,"getApiUrl",()=>r,"getConfig",()=>c,"initApiUrl",()=>t,"resetConfigCache",()=>s,"setApiUrl",()=>n])},760800,e=>{"use strict";var o=e.i(430878),i=e.i(739963);function a(){return(0,o.useEffect)(()=>{(0,i.initApiUrl)()},[]),null}e.s(["ApiInit",()=>a])}]);