sparkecoder 0.1.58 → 0.1.60

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 (99) hide show
  1. package/dist/agent/index.d.ts +2 -2
  2. package/dist/agent/index.js +74 -27
  3. package/dist/agent/index.js.map +1 -1
  4. package/dist/cli.js +88 -34
  5. package/dist/cli.js.map +1 -1
  6. package/dist/{index-DqLDYWhb.d.ts → index-Csad1Nx4.d.ts} +5 -5
  7. package/dist/index.d.ts +3 -3
  8. package/dist/index.js +87 -33
  9. package/dist/index.js.map +1 -1
  10. package/dist/{search-DINnDTgj.d.ts → search-BETuS1vh.d.ts} +1 -1
  11. package/dist/server/index.js +87 -33
  12. package/dist/server/index.js.map +1 -1
  13. package/dist/skills/default/browser.md +143 -0
  14. package/dist/skills/default/code-review.md +122 -0
  15. package/dist/skills/default/debugging.md +105 -0
  16. package/dist/skills/default/refactoring.md +197 -0
  17. package/dist/tools/index.d.ts +18 -3
  18. package/dist/tools/index.js +74 -27
  19. package/dist/tools/index.js.map +1 -1
  20. package/package.json +4 -1
  21. package/src/skills/default/browser.md +143 -0
  22. package/src/skills/default/code-review.md +122 -0
  23. package/src/skills/default/debugging.md +105 -0
  24. package/src/skills/default/refactoring.md +197 -0
  25. package/web/.next/BUILD_ID +1 -1
  26. package/web/.next/standalone/web/.next/BUILD_ID +1 -1
  27. package/web/.next/standalone/web/.next/build-manifest.json +2 -2
  28. package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
  29. package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
  30. package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
  31. package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  32. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  33. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  34. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  35. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  36. package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
  37. package/web/.next/standalone/web/.next/server/app/_not-found.rsc +1 -1
  38. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  39. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  40. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  41. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  42. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  43. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  44. package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
  45. package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +1 -1
  46. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +1 -1
  47. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
  48. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +1 -1
  49. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
  50. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
  51. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
  52. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
  53. package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
  54. package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +1 -1
  55. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +1 -1
  56. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
  57. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +1 -1
  58. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
  59. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
  60. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
  61. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
  62. package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
  63. package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +1 -1
  64. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +1 -1
  65. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
  66. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +1 -1
  67. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
  68. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
  69. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
  70. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
  71. package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
  72. package/web/.next/standalone/web/.next/server/app/docs.rsc +1 -1
  73. package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +1 -1
  74. package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
  75. package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +1 -1
  76. package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
  77. package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
  78. package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
  79. package/web/.next/standalone/web/.next/server/app/index.html +1 -1
  80. package/web/.next/standalone/web/.next/server/app/index.rsc +1 -1
  81. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +1 -1
  82. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +1 -1
  83. package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
  84. package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  85. package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
  86. package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  87. package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
  88. package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
  89. package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
  90. package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
  91. /package/web/.next/standalone/web/.next/static/{TuFKgULSvgTGHxXzZoeMo → R5xiWSOp_Nqqe_js-LROo}/_buildManifest.js +0 -0
  92. /package/web/.next/standalone/web/.next/static/{TuFKgULSvgTGHxXzZoeMo → R5xiWSOp_Nqqe_js-LROo}/_clientMiddlewareManifest.json +0 -0
  93. /package/web/.next/standalone/web/.next/static/{TuFKgULSvgTGHxXzZoeMo → R5xiWSOp_Nqqe_js-LROo}/_ssgManifest.js +0 -0
  94. /package/web/.next/standalone/web/.next/static/static/{TuFKgULSvgTGHxXzZoeMo → R5xiWSOp_Nqqe_js-LROo}/_buildManifest.js +0 -0
  95. /package/web/.next/standalone/web/.next/static/static/{TuFKgULSvgTGHxXzZoeMo → R5xiWSOp_Nqqe_js-LROo}/_clientMiddlewareManifest.json +0 -0
  96. /package/web/.next/standalone/web/.next/static/static/{TuFKgULSvgTGHxXzZoeMo → R5xiWSOp_Nqqe_js-LROo}/_ssgManifest.js +0 -0
  97. /package/web/.next/static/{TuFKgULSvgTGHxXzZoeMo → R5xiWSOp_Nqqe_js-LROo}/_buildManifest.js +0 -0
  98. /package/web/.next/static/{TuFKgULSvgTGHxXzZoeMo → R5xiWSOp_Nqqe_js-LROo}/_clientMiddlewareManifest.json +0 -0
  99. /package/web/.next/static/{TuFKgULSvgTGHxXzZoeMo → R5xiWSOp_Nqqe_js-LROo}/_ssgManifest.js +0 -0
@@ -1,5 +1,5 @@
1
1
  import 'ai';
2
2
  import '../schema-NcQknWCg.js';
3
- export { A as Agent, a as AgentOptions, b as AgentRunOptions, c as AgentStreamResult, C as ContextManager, M as MessageAttachment, d as buildSystemPrompt } from '../index-DqLDYWhb.js';
4
- import '../search-DINnDTgj.js';
3
+ export { A as Agent, a as AgentOptions, b as AgentRunOptions, c as AgentStreamResult, C as ContextManager, M as MessageAttachment, d as buildSystemPrompt } from '../index-Csad1Nx4.js';
4
+ import '../search-BETuS1vh.js';
5
5
  import 'zod';
@@ -484,7 +484,7 @@ __export(skills_exports, {
484
484
  loadSkillsFromDirectory: () => loadSkillsFromDirectory
485
485
  });
486
486
  import { readFile as readFile6, readdir } from "fs/promises";
487
- import { resolve as resolve6, basename, extname as extname3, relative as relative4 } from "path";
487
+ import { resolve as resolve6, basename, extname as extname4, relative as relative4 } from "path";
488
488
  import { existsSync as existsSync8 } from "fs";
489
489
  import { minimatch } from "minimatch";
490
490
  function parseSkillFrontmatter(content) {
@@ -555,7 +555,7 @@ function parseSkillFrontmatter(content) {
555
555
  }
556
556
  }
557
557
  function getSkillNameFromPath(filePath) {
558
- return basename(filePath, extname3(filePath)).replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
558
+ return basename(filePath, extname4(filePath)).replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
559
559
  }
560
560
  async function loadSkillsFromDirectory(directory, options = {}) {
561
561
  const {
@@ -860,7 +860,7 @@ var init_hasher = __esm({
860
860
  });
861
861
 
862
862
  // src/semantic/chunker.ts
863
- import { extname as extname5, basename as basename2 } from "path";
863
+ import { extname as extname6, basename as basename2 } from "path";
864
864
  var init_chunker = __esm({
865
865
  "src/semantic/chunker.ts"() {
866
866
  "use strict";
@@ -1766,26 +1766,41 @@ Terminal output is stored in the global SparkECoder data directory. Use the \`ta
1766
1766
  import { tool as tool2 } from "ai";
1767
1767
  import { z as z3 } from "zod";
1768
1768
  import { readFile as readFile2, stat } from "fs/promises";
1769
- import { resolve as resolve2, relative, isAbsolute } from "path";
1769
+ import { resolve as resolve2, relative, isAbsolute, extname } from "path";
1770
1770
  import { existsSync as existsSync3 } from "fs";
1771
1771
  var MAX_FILE_SIZE = 5 * 1024 * 1024;
1772
+ var MAX_IMAGE_SIZE = 20 * 1024 * 1024;
1772
1773
  var MAX_OUTPUT_CHARS3 = 5e4;
1774
+ var IMAGE_EXTENSIONS = {
1775
+ ".png": "image/png",
1776
+ ".jpg": "image/jpeg",
1777
+ ".jpeg": "image/jpeg",
1778
+ ".gif": "image/gif",
1779
+ ".webp": "image/webp"
1780
+ };
1781
+ function isImageFile(filePath) {
1782
+ return extname(filePath).toLowerCase() in IMAGE_EXTENSIONS;
1783
+ }
1784
+ function getImageMediaType(filePath) {
1785
+ return IMAGE_EXTENSIONS[extname(filePath).toLowerCase()] || "image/png";
1786
+ }
1773
1787
  var readFileInputSchema = z3.object({
1774
- path: z3.string().describe("The path to the file to read. Can be relative to working directory or absolute."),
1775
- startLine: z3.number().optional().describe("Optional: Start reading from this line number (1-indexed)"),
1776
- endLine: z3.number().optional().describe("Optional: Stop reading at this line number (1-indexed, inclusive)")
1788
+ path: z3.string().describe("The path to the file to read. Can be relative to working directory or absolute. Supports text files and images (png, jpg, jpeg, gif, webp)."),
1789
+ startLine: z3.number().optional().describe("Optional: Start reading from this line number (1-indexed). Only for text files."),
1790
+ endLine: z3.number().optional().describe("Optional: Stop reading at this line number (1-indexed, inclusive). Only for text files.")
1777
1791
  });
1778
1792
  function createReadFileTool(options) {
1779
1793
  return tool2({
1780
1794
  description: `Read the contents of a file. Provide a path relative to the working directory (${options.workingDirectory}) or an absolute path.
1781
- Large files will be automatically truncated. Binary files are not supported.
1782
- Use this to understand existing code, check file contents, or gather context.`,
1795
+ Supports text files (automatically truncated if large) and image files (png, jpg, jpeg, gif, webp).
1796
+ For images, the file contents are returned as visual data you can see and analyze.
1797
+ Use this to understand existing code, check file contents, view screenshots, or gather context.`,
1783
1798
  inputSchema: readFileInputSchema,
1784
- execute: async ({ path, startLine, endLine }) => {
1799
+ execute: async ({ path: filePath, startLine, endLine }) => {
1785
1800
  try {
1786
- const absolutePath = isAbsolute(path) ? path : resolve2(options.workingDirectory, path);
1801
+ const absolutePath = isAbsolute(filePath) ? filePath : resolve2(options.workingDirectory, filePath);
1787
1802
  const relativePath = relative(options.workingDirectory, absolutePath);
1788
- if (relativePath.startsWith("..") && !isAbsolute(path)) {
1803
+ if (relativePath.startsWith("..") && !isAbsolute(filePath)) {
1789
1804
  return {
1790
1805
  success: false,
1791
1806
  error: "Path escapes the working directory. Use an absolute path if intentional.",
@@ -1795,22 +1810,43 @@ Use this to understand existing code, check file contents, or gather context.`,
1795
1810
  if (!existsSync3(absolutePath)) {
1796
1811
  return {
1797
1812
  success: false,
1798
- error: `File not found: ${path}`,
1813
+ error: `File not found: ${filePath}`,
1799
1814
  content: null
1800
1815
  };
1801
1816
  }
1802
1817
  const stats = await stat(absolutePath);
1803
- if (stats.size > MAX_FILE_SIZE) {
1818
+ if (stats.isDirectory()) {
1804
1819
  return {
1805
1820
  success: false,
1806
- error: `File is too large (${(stats.size / 1024 / 1024).toFixed(2)}MB). Maximum size is ${MAX_FILE_SIZE / 1024 / 1024}MB.`,
1821
+ error: 'Path is a directory, not a file. Use bash with "ls" to list directory contents.',
1807
1822
  content: null
1808
1823
  };
1809
1824
  }
1810
- if (stats.isDirectory()) {
1825
+ if (isImageFile(absolutePath)) {
1826
+ if (stats.size > MAX_IMAGE_SIZE) {
1827
+ return {
1828
+ success: false,
1829
+ error: `Image is too large (${(stats.size / 1024 / 1024).toFixed(2)}MB). Maximum size is ${MAX_IMAGE_SIZE / 1024 / 1024}MB.`,
1830
+ content: null
1831
+ };
1832
+ }
1833
+ const buffer = await readFile2(absolutePath);
1834
+ const base64 = buffer.toString("base64");
1835
+ const mediaType = getImageMediaType(absolutePath);
1836
+ return {
1837
+ success: true,
1838
+ path: absolutePath,
1839
+ relativePath: relative(options.workingDirectory, absolutePath),
1840
+ content: `[Image: ${relativePath} (${mediaType}, ${(stats.size / 1024).toFixed(1)}KB)]`,
1841
+ mediaType,
1842
+ imageData: base64,
1843
+ sizeBytes: stats.size
1844
+ };
1845
+ }
1846
+ if (stats.size > MAX_FILE_SIZE) {
1811
1847
  return {
1812
1848
  success: false,
1813
- error: 'Path is a directory, not a file. Use bash with "ls" to list directory contents.',
1849
+ error: `File is too large (${(stats.size / 1024 / 1024).toFixed(2)}MB). Maximum size is ${MAX_FILE_SIZE / 1024 / 1024}MB.`,
1814
1850
  content: null
1815
1851
  };
1816
1852
  }
@@ -1826,9 +1862,7 @@ Use this to understand existing code, check file contents, or gather context.`,
1826
1862
  content: null
1827
1863
  };
1828
1864
  }
1829
- content = lines.slice(start, end).join("\n");
1830
- const lineNumbers = lines.slice(start, end).map((line, idx) => `${(start + idx + 1).toString().padStart(4)}: ${line}`).join("\n");
1831
- content = lineNumbers;
1865
+ content = lines.slice(start, end).map((line, idx) => `${(start + idx + 1).toString().padStart(4)}: ${line}`).join("\n");
1832
1866
  }
1833
1867
  const truncatedContent = truncateOutput(content, MAX_OUTPUT_CHARS3);
1834
1868
  const wasTruncated = truncatedContent.length < content.length;
@@ -1855,6 +1889,19 @@ Use this to understand existing code, check file contents, or gather context.`,
1855
1889
  content: null
1856
1890
  };
1857
1891
  }
1892
+ },
1893
+ toModelOutput: ({ output }) => {
1894
+ if (output && typeof output === "object" && "imageData" in output && output.imageData) {
1895
+ const result = output;
1896
+ return {
1897
+ type: "content",
1898
+ value: [
1899
+ { type: "text", text: result.content },
1900
+ { type: "image-data", data: result.imageData, mediaType: result.mediaType }
1901
+ ]
1902
+ };
1903
+ }
1904
+ return typeof output === "string" ? { type: "text", value: output } : { type: "json", value: output };
1858
1905
  }
1859
1906
  });
1860
1907
  }
@@ -1919,7 +1966,7 @@ async function backupFile(sessionId, workingDirectory, filePath) {
1919
1966
  }
1920
1967
 
1921
1968
  // src/lsp/index.ts
1922
- import { extname as extname2, dirname as dirname4 } from "path";
1969
+ import { extname as extname3, dirname as dirname4 } from "path";
1923
1970
 
1924
1971
  // src/lsp/servers.ts
1925
1972
  import { spawn } from "child_process";
@@ -2042,9 +2089,9 @@ import {
2042
2089
  import { pathToFileURL, fileURLToPath } from "url";
2043
2090
  import { readFile as readFile4 } from "fs/promises";
2044
2091
  import { existsSync as existsSync6 } from "fs";
2045
- import { extname, normalize } from "path";
2092
+ import { extname as extname2, normalize } from "path";
2046
2093
  function getLanguageId(filePath) {
2047
- const ext = extname(filePath).toLowerCase();
2094
+ const ext = extname2(filePath).toLowerCase();
2048
2095
  const map = {
2049
2096
  ".ts": "typescript",
2050
2097
  ".tsx": "typescriptreact",
@@ -2432,7 +2479,7 @@ var state = {
2432
2479
  };
2433
2480
  async function getClientForFile(filePath) {
2434
2481
  const normalized = normalizePath(filePath);
2435
- const ext = extname2(normalized);
2482
+ const ext = extname3(normalized);
2436
2483
  const serverDef = getServerForExtension(ext);
2437
2484
  if (!serverDef) {
2438
2485
  return null;
@@ -2525,7 +2572,7 @@ async function formatDiagnosticsOutput(filePath, options = {}) {
2525
2572
  return formatDiagnosticsForAgent(filePath, diagnostics, options);
2526
2573
  }
2527
2574
  function isSupported(filePath) {
2528
- const ext = extname2(filePath);
2575
+ const ext = extname3(filePath);
2529
2576
  return getServerForExtension(ext) !== null;
2530
2577
  }
2531
2578
 
@@ -2952,7 +2999,7 @@ Once loaded, a skill's content will be available in the conversation context.`,
2952
2999
  // src/tools/linter.ts
2953
3000
  import { tool as tool6 } from "ai";
2954
3001
  import { z as z7 } from "zod";
2955
- import { resolve as resolve7, relative as relative5, isAbsolute as isAbsolute3, extname as extname4 } from "path";
3002
+ import { resolve as resolve7, relative as relative5, isAbsolute as isAbsolute3, extname as extname5 } from "path";
2956
3003
  import { existsSync as existsSync9 } from "fs";
2957
3004
  import { readdir as readdir2, stat as stat2 } from "fs/promises";
2958
3005
  var linterInputSchema = z7.object({
@@ -2975,7 +3022,7 @@ async function findSupportedFiles(dir, workingDirectory, maxFiles = 50) {
2975
3022
  }
2976
3023
  await walk(fullPath);
2977
3024
  } else if (entry.isFile()) {
2978
- const ext = extname4(entry.name);
3025
+ const ext = extname5(entry.name);
2979
3026
  if (supportedExtensions.includes(ext)) {
2980
3027
  files.push(fullPath);
2981
3028
  }