sparkecoder 0.1.75 → 0.1.76

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 (87) hide show
  1. package/dist/agent/index.js +114 -43
  2. package/dist/agent/index.js.map +1 -1
  3. package/dist/cli.js +186 -110
  4. package/dist/cli.js.map +1 -1
  5. package/dist/index.js +174 -98
  6. package/dist/index.js.map +1 -1
  7. package/dist/server/index.js +174 -98
  8. package/dist/server/index.js.map +1 -1
  9. package/dist/tools/index.js +105 -34
  10. package/dist/tools/index.js.map +1 -1
  11. package/package.json +2 -1
  12. package/web/.next/BUILD_ID +1 -1
  13. package/web/.next/standalone/node_modules/.pnpm/sharp@0.34.5/node_modules/sharp/package.json +202 -0
  14. package/web/.next/standalone/web/.next/BUILD_ID +1 -1
  15. package/web/.next/standalone/web/.next/build-manifest.json +2 -2
  16. package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
  17. package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
  18. package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
  19. package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  20. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  21. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  22. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  23. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  24. package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
  25. package/web/.next/standalone/web/.next/server/app/_not-found.rsc +1 -1
  26. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  27. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  28. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  29. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  30. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  31. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  32. package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
  33. package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +1 -1
  34. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +1 -1
  35. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
  36. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +1 -1
  37. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
  38. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
  39. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
  40. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
  41. package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
  42. package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +1 -1
  43. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +1 -1
  44. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
  45. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +1 -1
  46. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
  47. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
  48. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
  49. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
  50. package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
  51. package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +1 -1
  52. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +1 -1
  53. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
  54. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +1 -1
  55. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
  56. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
  57. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
  58. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
  59. package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
  60. package/web/.next/standalone/web/.next/server/app/docs.rsc +1 -1
  61. package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +1 -1
  62. package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
  63. package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +1 -1
  64. package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
  65. package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
  66. package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
  67. package/web/.next/standalone/web/.next/server/app/index.html +1 -1
  68. package/web/.next/standalone/web/.next/server/app/index.rsc +1 -1
  69. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +1 -1
  70. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +1 -1
  71. package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
  72. package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  73. package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
  74. package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  75. package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
  76. package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
  77. package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
  78. package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
  79. /package/web/.next/standalone/web/.next/static/{static/xfMAecV1v1MVUkZE1r3BT → nZpzcWd5nqIPZFd3PiefU}/_buildManifest.js +0 -0
  80. /package/web/.next/standalone/web/.next/static/{static/xfMAecV1v1MVUkZE1r3BT → nZpzcWd5nqIPZFd3PiefU}/_clientMiddlewareManifest.json +0 -0
  81. /package/web/.next/standalone/web/.next/static/{static/xfMAecV1v1MVUkZE1r3BT → nZpzcWd5nqIPZFd3PiefU}/_ssgManifest.js +0 -0
  82. /package/web/.next/standalone/web/.next/static/{xfMAecV1v1MVUkZE1r3BT → static/nZpzcWd5nqIPZFd3PiefU}/_buildManifest.js +0 -0
  83. /package/web/.next/standalone/web/.next/static/{xfMAecV1v1MVUkZE1r3BT → static/nZpzcWd5nqIPZFd3PiefU}/_clientMiddlewareManifest.json +0 -0
  84. /package/web/.next/standalone/web/.next/static/{xfMAecV1v1MVUkZE1r3BT → static/nZpzcWd5nqIPZFd3PiefU}/_ssgManifest.js +0 -0
  85. /package/web/.next/static/{xfMAecV1v1MVUkZE1r3BT → nZpzcWd5nqIPZFd3PiefU}/_buildManifest.js +0 -0
  86. /package/web/.next/static/{xfMAecV1v1MVUkZE1r3BT → nZpzcWd5nqIPZFd3PiefU}/_clientMiddlewareManifest.json +0 -0
  87. /package/web/.next/static/{xfMAecV1v1MVUkZE1r3BT → nZpzcWd5nqIPZFd3PiefU}/_ssgManifest.js +0 -0
package/dist/cli.js CHANGED
@@ -1053,7 +1053,7 @@ __export(skills_exports, {
1053
1053
  });
1054
1054
  import { readFile as readFile6, readdir } from "fs/promises";
1055
1055
  import { resolve as resolve6, basename, extname as extname4, relative as relative4 } from "path";
1056
- import { existsSync as existsSync8 } from "fs";
1056
+ import { existsSync as existsSync9 } from "fs";
1057
1057
  import { minimatch } from "minimatch";
1058
1058
  function parseSkillFrontmatter(content) {
1059
1059
  const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
@@ -1131,7 +1131,7 @@ async function loadSkillsFromDirectory(directory, options = {}) {
1131
1131
  defaultLoadType = "on_demand",
1132
1132
  forceAlwaysApply = false
1133
1133
  } = options;
1134
- if (!existsSync8(directory)) {
1134
+ if (!existsSync9(directory)) {
1135
1135
  return [];
1136
1136
  }
1137
1137
  const skills = [];
@@ -1141,7 +1141,7 @@ async function loadSkillsFromDirectory(directory, options = {}) {
1141
1141
  let fileName;
1142
1142
  if (entry.isDirectory()) {
1143
1143
  const skillMdPath = resolve6(directory, entry.name, "SKILL.md");
1144
- if (existsSync8(skillMdPath)) {
1144
+ if (existsSync9(skillMdPath)) {
1145
1145
  filePath = skillMdPath;
1146
1146
  fileName = entry.name;
1147
1147
  } else {
@@ -1281,7 +1281,7 @@ async function getGlobMatchedSkills(skills, activeFiles, workingDirectory) {
1281
1281
  return matchedWithContent;
1282
1282
  }
1283
1283
  async function loadAgentsMd(agentsMdPath) {
1284
- if (!agentsMdPath || !existsSync8(agentsMdPath)) {
1284
+ if (!agentsMdPath || !existsSync9(agentsMdPath)) {
1285
1285
  return null;
1286
1286
  }
1287
1287
  const content = await readFile6(agentsMdPath, "utf-8");
@@ -1432,9 +1432,9 @@ var init_namespace = __esm({
1432
1432
  });
1433
1433
 
1434
1434
  // src/semantic/hasher.ts
1435
- import { createHash } from "crypto";
1435
+ import { createHash as createHash2 } from "crypto";
1436
1436
  function computeContentHash(content) {
1437
- const hash = createHash("sha256");
1437
+ const hash = createHash2("sha256");
1438
1438
  hash.update(content, "utf-8");
1439
1439
  return hash.digest("hex").slice(0, 16);
1440
1440
  }
@@ -1962,7 +1962,7 @@ var init_client = __esm({
1962
1962
  });
1963
1963
 
1964
1964
  // src/semantic/indexer.ts
1965
- import { readFileSync as readFileSync3, statSync } from "fs";
1965
+ import { readFileSync as readFileSync4, statSync } from "fs";
1966
1966
  import { relative as relative6 } from "path";
1967
1967
  import { minimatch as minimatch2 } from "minimatch";
1968
1968
  function parsePositiveInt(value, fallback) {
@@ -2004,7 +2004,7 @@ function isPathExcluded(relativePath, exclude) {
2004
2004
  }
2005
2005
  async function walkDirectory(dir, include, exclude, baseDir) {
2006
2006
  const { readdirSync: readdirSync2 } = await import("fs");
2007
- const { join: join12, relative: relative10 } = await import("path");
2007
+ const { join: join13, relative: relative10 } = await import("path");
2008
2008
  const files = [];
2009
2009
  function walk(currentDir) {
2010
2010
  let entries;
@@ -2014,7 +2014,7 @@ async function walkDirectory(dir, include, exclude, baseDir) {
2014
2014
  return;
2015
2015
  }
2016
2016
  for (const entry of entries) {
2017
- const fullPath = join12(currentDir, entry.name);
2017
+ const fullPath = join13(currentDir, entry.name);
2018
2018
  const relativePath = relative10(baseDir, fullPath);
2019
2019
  if (isPathExcluded(relativePath, exclude)) {
2020
2020
  continue;
@@ -2044,7 +2044,7 @@ function shouldSkipFile(filePath) {
2044
2044
  return { skip: true, reason: "Empty file" };
2045
2045
  }
2046
2046
  try {
2047
- const content = readFileSync3(filePath, "utf-8");
2047
+ const content = readFileSync4(filePath, "utf-8");
2048
2048
  const sample = content.slice(0, 1e3);
2049
2049
  if (sample.includes("\0")) {
2050
2050
  return { skip: true, reason: "Binary file" };
@@ -2143,7 +2143,7 @@ async function indexRepository(options) {
2143
2143
  continue;
2144
2144
  }
2145
2145
  try {
2146
- const content = readFileSync3(filePath, "utf-8");
2146
+ const content = readFileSync4(filePath, "utf-8");
2147
2147
  const chunks = chunkFile(relativePath, content);
2148
2148
  allChunks.push(...chunks);
2149
2149
  progress.totalChunks += chunks.length;
@@ -2383,8 +2383,8 @@ __export(semantic_search_exports, {
2383
2383
  });
2384
2384
  import { tool as tool8 } from "ai";
2385
2385
  import { z as z9 } from "zod";
2386
- import { existsSync as existsSync11, readFileSync as readFileSync4 } from "fs";
2387
- import { join as join4 } from "path";
2386
+ import { existsSync as existsSync12, readFileSync as readFileSync5 } from "fs";
2387
+ import { join as join5 } from "path";
2388
2388
  import { minimatch as minimatch3 } from "minimatch";
2389
2389
  function createSemanticSearchTool(options) {
2390
2390
  return tool8({
@@ -2451,13 +2451,13 @@ Returns matching code snippets with file paths, line numbers, and relevance scor
2451
2451
  if (language && matchLanguage !== language.toLowerCase()) {
2452
2452
  continue;
2453
2453
  }
2454
- const fullPath = join4(options.workingDirectory, filePath);
2455
- if (!existsSync11(fullPath)) {
2454
+ const fullPath = join5(options.workingDirectory, filePath);
2455
+ if (!existsSync12(fullPath)) {
2456
2456
  continue;
2457
2457
  }
2458
2458
  let snippet = "";
2459
2459
  try {
2460
- const content = readFileSync4(fullPath, "utf-8");
2460
+ const content = readFileSync5(fullPath, "utf-8");
2461
2461
  const lines = content.split("\n");
2462
2462
  const snippetLines = lines.slice(
2463
2463
  Math.max(0, startLine - 1),
@@ -2753,7 +2753,7 @@ __export(recorder_exports, {
2753
2753
  import { exec as exec5 } from "child_process";
2754
2754
  import { promisify as promisify5 } from "util";
2755
2755
  import { writeFile as writeFile4, mkdir as mkdir4, readFile as readFile10, unlink as unlink2, readdir as readdir5, rm } from "fs/promises";
2756
- import { join as join6 } from "path";
2756
+ import { join as join7 } from "path";
2757
2757
  import { tmpdir } from "os";
2758
2758
  import { nanoid as nanoid3 } from "nanoid";
2759
2759
  async function checkFfmpeg() {
@@ -2810,21 +2810,21 @@ var init_recorder = __esm({
2810
2810
  */
2811
2811
  async encode() {
2812
2812
  if (this.frames.length === 0) return null;
2813
- const workDir = join6(tmpdir(), `sparkecoder-recording-${nanoid3(8)}`);
2813
+ const workDir = join7(tmpdir(), `sparkecoder-recording-${nanoid3(8)}`);
2814
2814
  await mkdir4(workDir, { recursive: true });
2815
2815
  try {
2816
2816
  for (let i = 0; i < this.frames.length; i++) {
2817
- const framePath = join6(workDir, `frame_${String(i).padStart(6, "0")}.jpg`);
2817
+ const framePath = join7(workDir, `frame_${String(i).padStart(6, "0")}.jpg`);
2818
2818
  await writeFile4(framePath, this.frames[i].data);
2819
2819
  }
2820
2820
  const duration = (this.frames[this.frames.length - 1].timestamp - this.frames[0].timestamp) / 1e3;
2821
2821
  const fps = duration > 0 ? Math.round(this.frames.length / duration) : 10;
2822
2822
  const clampedFps = Math.max(1, Math.min(fps, 30));
2823
- const outputPath = join6(workDir, `recording_${this.sessionId}.mp4`);
2823
+ const outputPath = join7(workDir, `recording_${this.sessionId}.mp4`);
2824
2824
  const hasFfmpeg = await checkFfmpeg();
2825
2825
  if (hasFfmpeg) {
2826
2826
  await execAsync5(
2827
- `ffmpeg -y -framerate ${clampedFps} -i "${join6(workDir, "frame_%06d.jpg")}" -c:v libx264 -pix_fmt yuv420p -preset fast -crf 23 "${outputPath}"`,
2827
+ `ffmpeg -y -framerate ${clampedFps} -i "${join7(workDir, "frame_%06d.jpg")}" -c:v libx264 -pix_fmt yuv420p -preset fast -crf 23 "${outputPath}"`,
2828
2828
  { timeout: 12e4 }
2829
2829
  );
2830
2830
  } else {
@@ -2836,7 +2836,7 @@ var init_recorder = __esm({
2836
2836
  const files = await readdir5(workDir);
2837
2837
  for (const f of files) {
2838
2838
  if (f.startsWith("frame_")) {
2839
- await unlink2(join6(workDir, f)).catch(() => {
2839
+ await unlink2(join7(workDir, f)).catch(() => {
2840
2840
  });
2841
2841
  }
2842
2842
  }
@@ -2870,8 +2870,8 @@ import { Hono as Hono6 } from "hono";
2870
2870
  import { serve } from "@hono/node-server";
2871
2871
  import { cors } from "hono/cors";
2872
2872
  import { logger } from "hono/logger";
2873
- import { existsSync as existsSync15, mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "fs";
2874
- import { resolve as resolve10, dirname as dirname7, join as join10 } from "path";
2873
+ import { existsSync as existsSync16, mkdirSync as mkdirSync6, writeFileSync as writeFileSync5 } from "fs";
2874
+ import { resolve as resolve10, dirname as dirname7, join as join11 } from "path";
2875
2875
  import { spawn as spawn2 } from "child_process";
2876
2876
  import { createServer as createNetServer } from "net";
2877
2877
  import { fileURLToPath as fileURLToPath4 } from "url";
@@ -2881,9 +2881,9 @@ init_db();
2881
2881
  import { Hono } from "hono";
2882
2882
  import { zValidator } from "@hono/zod-validator";
2883
2883
  import { z as z15 } from "zod";
2884
- import { existsSync as existsSync13, mkdirSync as mkdirSync3, writeFileSync as writeFileSync2, readdirSync, statSync as statSync2, unlinkSync } from "fs";
2884
+ import { existsSync as existsSync14, mkdirSync as mkdirSync4, writeFileSync as writeFileSync3, readdirSync, statSync as statSync2, unlinkSync } from "fs";
2885
2885
  import { readdir as readdir6 } from "fs/promises";
2886
- import { join as join7, basename as basename5, extname as extname8, relative as relative9 } from "path";
2886
+ import { join as join8, basename as basename5, extname as extname8, relative as relative9 } from "path";
2887
2887
  import { nanoid as nanoid5 } from "nanoid";
2888
2888
 
2889
2889
  // src/agent/index.ts
@@ -3715,7 +3715,77 @@ import { tool as tool2 } from "ai";
3715
3715
  import { z as z3 } from "zod";
3716
3716
  import { readFile as readFile2, stat } from "fs/promises";
3717
3717
  import { resolve as resolve2, relative, isAbsolute, extname } from "path";
3718
- import { existsSync as existsSync3 } from "fs";
3718
+ import { existsSync as existsSync4 } from "fs";
3719
+
3720
+ // src/utils/resize-image.ts
3721
+ init_config();
3722
+ import sharp from "sharp";
3723
+ import { createHash } from "crypto";
3724
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
3725
+ import { join as join3 } from "path";
3726
+ var MAX_LONG_EDGE = 1568;
3727
+ var MAX_FILE_BYTES = 5 * 1024 * 1024;
3728
+ var CACHE_DIR_NAME = "image-cache";
3729
+ function getCacheDir() {
3730
+ const dir = join3(getAppDataDirectory(), CACHE_DIR_NAME);
3731
+ if (!existsSync3(dir)) mkdirSync3(dir, { recursive: true });
3732
+ return dir;
3733
+ }
3734
+ function cacheKey(buffer) {
3735
+ return createHash("sha256").update(buffer).digest("hex");
3736
+ }
3737
+ async function resizeImageIfNeeded(buffer, mediaType) {
3738
+ let metadata;
3739
+ try {
3740
+ metadata = await sharp(buffer).metadata();
3741
+ } catch {
3742
+ return buffer;
3743
+ }
3744
+ const { width, height } = metadata;
3745
+ if (!width || !height) return buffer;
3746
+ const longEdge = Math.max(width, height);
3747
+ const needsResize = longEdge > MAX_LONG_EDGE;
3748
+ const needsShrink = buffer.length > MAX_FILE_BYTES;
3749
+ if (!needsResize && !needsShrink) return buffer;
3750
+ const key = cacheKey(buffer);
3751
+ const cacheDir = getCacheDir();
3752
+ const isPng = mediaType?.includes("png");
3753
+ const ext = isPng ? ".png" : ".jpg";
3754
+ const cachePath = join3(cacheDir, key + ext);
3755
+ if (existsSync3(cachePath)) {
3756
+ console.log(`[image-resize] Cache hit for ${width}x${height} image`);
3757
+ return readFileSync2(cachePath);
3758
+ }
3759
+ let pipeline = sharp(buffer);
3760
+ if (needsResize) {
3761
+ pipeline = pipeline.resize(MAX_LONG_EDGE, MAX_LONG_EDGE, {
3762
+ fit: "inside",
3763
+ withoutEnlargement: true
3764
+ });
3765
+ }
3766
+ let result;
3767
+ if (isPng && (needsShrink || buffer.length > 2 * 1024 * 1024)) {
3768
+ result = await pipeline.jpeg({ quality: 85 }).toBuffer();
3769
+ } else if (isPng) {
3770
+ result = await pipeline.png().toBuffer();
3771
+ } else {
3772
+ result = await pipeline.jpeg({ quality: 85 }).toBuffer();
3773
+ }
3774
+ if (result.length > MAX_FILE_BYTES) {
3775
+ for (const quality of [70, 50, 30]) {
3776
+ result = await sharp(buffer).resize(MAX_LONG_EDGE, MAX_LONG_EDGE, { fit: "inside", withoutEnlargement: true }).jpeg({ quality }).toBuffer();
3777
+ if (result.length <= MAX_FILE_BYTES) break;
3778
+ }
3779
+ }
3780
+ writeFileSync2(cachePath, result);
3781
+ const resultMeta = await sharp(result).metadata();
3782
+ console.log(
3783
+ `[image-resize] ${width}x${height} -> ${resultMeta.width}x${resultMeta.height} (${(buffer.length / 1024).toFixed(0)}KB -> ${(result.length / 1024).toFixed(0)}KB)`
3784
+ );
3785
+ return result;
3786
+ }
3787
+
3788
+ // src/tools/read-file.ts
3719
3789
  var MAX_FILE_SIZE = 5 * 1024 * 1024;
3720
3790
  var MAX_IMAGE_SIZE = 20 * 1024 * 1024;
3721
3791
  var MAX_OUTPUT_CHARS3 = 5e4;
@@ -3755,7 +3825,7 @@ Use this to understand existing code, check file contents, view screenshots, or
3755
3825
  content: null
3756
3826
  };
3757
3827
  }
3758
- if (!existsSync3(absolutePath)) {
3828
+ if (!existsSync4(absolutePath)) {
3759
3829
  return {
3760
3830
  success: false,
3761
3831
  error: `File not found: ${filePath}`,
@@ -3778,9 +3848,10 @@ Use this to understand existing code, check file contents, view screenshots, or
3778
3848
  content: null
3779
3849
  };
3780
3850
  }
3781
- const buffer = await readFile2(absolutePath);
3782
- const base64 = buffer.toString("base64");
3851
+ const rawBuffer = await readFile2(absolutePath);
3783
3852
  const mediaType = getImageMediaType(absolutePath);
3853
+ const buffer = await resizeImageIfNeeded(rawBuffer, mediaType);
3854
+ const base64 = buffer.toString("base64");
3784
3855
  return {
3785
3856
  success: true,
3786
3857
  path: absolutePath,
@@ -3859,12 +3930,12 @@ import { tool as tool3 } from "ai";
3859
3930
  import { z as z4 } from "zod";
3860
3931
  import { readFile as readFile5, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
3861
3932
  import { resolve as resolve5, relative as relative3, isAbsolute as isAbsolute2, dirname as dirname5 } from "path";
3862
- import { existsSync as existsSync7 } from "fs";
3933
+ import { existsSync as existsSync8 } from "fs";
3863
3934
 
3864
3935
  // src/checkpoints/index.ts
3865
3936
  init_db();
3866
3937
  import { readFile as readFile3, writeFile as writeFile2, unlink, mkdir as mkdir2 } from "fs/promises";
3867
- import { existsSync as existsSync4 } from "fs";
3938
+ import { existsSync as existsSync5 } from "fs";
3868
3939
  import { resolve as resolve3, relative as relative2, dirname as dirname2 } from "path";
3869
3940
  import { exec as exec3 } from "child_process";
3870
3941
  import { promisify as promisify3 } from "util";
@@ -3917,7 +3988,7 @@ async function backupFile(sessionId, workingDirectory, filePath) {
3917
3988
  }
3918
3989
  let originalContent = null;
3919
3990
  let existed = false;
3920
- if (existsSync4(absolutePath)) {
3991
+ if (existsSync5(absolutePath)) {
3921
3992
  try {
3922
3993
  originalContent = await readFile3(absolutePath, "utf-8");
3923
3994
  existed = true;
@@ -3972,13 +4043,13 @@ async function revertToCheckpoint(sessionId, checkpointId) {
3972
4043
  try {
3973
4044
  if (backup.existed && backup.originalContent !== null) {
3974
4045
  const dir = dirname2(absolutePath);
3975
- if (!existsSync4(dir)) {
4046
+ if (!existsSync5(dir)) {
3976
4047
  await mkdir2(dir, { recursive: true });
3977
4048
  }
3978
4049
  await writeFile2(absolutePath, backup.originalContent, "utf-8");
3979
4050
  filesRestored++;
3980
4051
  } else if (!backup.existed) {
3981
- if (existsSync4(absolutePath)) {
4052
+ if (existsSync5(absolutePath)) {
3982
4053
  await unlink(absolutePath);
3983
4054
  filesDeleted++;
3984
4055
  }
@@ -4021,7 +4092,7 @@ async function getSessionDiff(sessionId) {
4021
4092
  const absolutePath = resolve3(workingDirectory, filePath);
4022
4093
  let currentContent = null;
4023
4094
  let currentExists = false;
4024
- if (existsSync4(absolutePath)) {
4095
+ if (existsSync5(absolutePath)) {
4025
4096
  try {
4026
4097
  currentContent = await readFile3(absolutePath, "utf-8");
4027
4098
  currentExists = true;
@@ -4054,14 +4125,14 @@ import { extname as extname3, dirname as dirname4 } from "path";
4054
4125
 
4055
4126
  // src/lsp/servers.ts
4056
4127
  import { spawn } from "child_process";
4057
- import { existsSync as existsSync5 } from "fs";
4128
+ import { existsSync as existsSync6 } from "fs";
4058
4129
  import { resolve as resolve4, dirname as dirname3 } from "path";
4059
4130
  function findNearestRoot(startDir, markers) {
4060
4131
  let dir = startDir;
4061
4132
  const root = "/";
4062
4133
  while (dir !== root) {
4063
4134
  for (const marker of markers) {
4064
- if (existsSync5(resolve4(dir, marker))) {
4135
+ if (existsSync6(resolve4(dir, marker))) {
4065
4136
  return dir;
4066
4137
  }
4067
4138
  }
@@ -4172,7 +4243,7 @@ import {
4172
4243
  } from "vscode-jsonrpc/node.js";
4173
4244
  import { pathToFileURL, fileURLToPath } from "url";
4174
4245
  import { readFile as readFile4 } from "fs/promises";
4175
- import { existsSync as existsSync6 } from "fs";
4246
+ import { existsSync as existsSync7 } from "fs";
4176
4247
  import { extname as extname2, normalize } from "path";
4177
4248
  function getLanguageId(filePath) {
4178
4249
  const ext = extname2(filePath).toLowerCase();
@@ -4298,7 +4369,7 @@ async function createClient(serverId, handle, root) {
4298
4369
  diagnostics,
4299
4370
  async notifyOpen(filePath) {
4300
4371
  const normalized = normalizePath(filePath);
4301
- if (!existsSync6(normalized)) {
4372
+ if (!existsSync7(normalized)) {
4302
4373
  return;
4303
4374
  }
4304
4375
  try {
@@ -4329,7 +4400,7 @@ async function createClient(serverId, handle, root) {
4329
4400
  },
4330
4401
  async notifyChange(filePath) {
4331
4402
  const normalized = normalizePath(filePath);
4332
- if (!existsSync6(normalized)) {
4403
+ if (!existsSync7(normalized)) {
4333
4404
  return;
4334
4405
  }
4335
4406
  try {
@@ -4705,7 +4776,7 @@ Working directory: ${options.workingDirectory}`,
4705
4776
  error: 'Content is required for "full" mode'
4706
4777
  };
4707
4778
  }
4708
- const existed = existsSync7(absolutePath);
4779
+ const existed = existsSync8(absolutePath);
4709
4780
  const action = existed ? "replaced" : "created";
4710
4781
  console.log("[WRITE-FILE] onProgress callback exists:", !!options.onProgress);
4711
4782
  console.log("[WRITE-FILE] Emitting started event for:", relativePath);
@@ -4752,7 +4823,7 @@ Working directory: ${options.workingDirectory}`,
4752
4823
  }
4753
4824
  await backupFile(options.sessionId, options.workingDirectory, absolutePath);
4754
4825
  const dir = dirname5(absolutePath);
4755
- if (!existsSync7(dir)) {
4826
+ if (!existsSync8(dir)) {
4756
4827
  await mkdir3(dir, { recursive: true });
4757
4828
  }
4758
4829
  await writeFile3(absolutePath, content, "utf-8");
@@ -4786,7 +4857,7 @@ Working directory: ${options.workingDirectory}`,
4786
4857
  error: 'Both old_string and new_string are required for "str_replace" mode'
4787
4858
  };
4788
4859
  }
4789
- if (!existsSync7(absolutePath)) {
4860
+ if (!existsSync8(absolutePath)) {
4790
4861
  return {
4791
4862
  success: false,
4792
4863
  error: `File not found: ${path}. Use "full" mode to create new files.`
@@ -5084,7 +5155,7 @@ Once loaded, a skill's content will be available in the conversation context.`,
5084
5155
  import { tool as tool6 } from "ai";
5085
5156
  import { z as z7 } from "zod";
5086
5157
  import { resolve as resolve7, relative as relative5, isAbsolute as isAbsolute3, extname as extname5 } from "path";
5087
- import { existsSync as existsSync9 } from "fs";
5158
+ import { existsSync as existsSync10 } from "fs";
5088
5159
  import { readdir as readdir2, stat as stat2 } from "fs/promises";
5089
5160
  var linterInputSchema = z7.object({
5090
5161
  paths: z7.array(z7.string()).optional().describe("File or directory paths to check for lint errors. If not provided, returns diagnostics for all recently touched files."),
@@ -5152,7 +5223,7 @@ Working directory: ${options.workingDirectory}`,
5152
5223
  const filesToCheck = [];
5153
5224
  for (const path of paths) {
5154
5225
  const absolutePath = isAbsolute3(path) ? path : resolve7(options.workingDirectory, path);
5155
- if (!existsSync9(absolutePath)) {
5226
+ if (!existsSync10(absolutePath)) {
5156
5227
  continue;
5157
5228
  }
5158
5229
  const stats = await stat2(absolutePath);
@@ -5466,7 +5537,7 @@ import { exec as exec4 } from "child_process";
5466
5537
  import { promisify as promisify4 } from "util";
5467
5538
  import { readFile as readFile8, stat as stat3, readdir as readdir4 } from "fs/promises";
5468
5539
  import { resolve as resolve9, relative as relative8, isAbsolute as isAbsolute5 } from "path";
5469
- import { existsSync as existsSync12 } from "fs";
5540
+ import { existsSync as existsSync13 } from "fs";
5470
5541
  init_semantic();
5471
5542
 
5472
5543
  // src/tools/code-graph.ts
@@ -5474,7 +5545,7 @@ import { tool as tool7 } from "ai";
5474
5545
  import { z as z8 } from "zod";
5475
5546
  import { resolve as resolve8, relative as relative7, isAbsolute as isAbsolute4, basename as basename3 } from "path";
5476
5547
  import { readFile as readFile7, readdir as readdir3 } from "fs/promises";
5477
- import { existsSync as existsSync10 } from "fs";
5548
+ import { existsSync as existsSync11 } from "fs";
5478
5549
  import { fileURLToPath as fileURLToPath2 } from "url";
5479
5550
  import { execFileSync } from "child_process";
5480
5551
  var codeGraphInputSchema = z8.object({
@@ -5660,7 +5731,7 @@ Working directory: ${options.workingDirectory}`,
5660
5731
  let defSymbol = null;
5661
5732
  if (filePath) {
5662
5733
  const absPath = isAbsolute4(filePath) ? filePath : resolve8(options.workingDirectory, filePath);
5663
- if (!existsSync10(absPath)) {
5734
+ if (!existsSync11(absPath)) {
5664
5735
  return { success: false, error: `File not found: ${filePath}` };
5665
5736
  }
5666
5737
  if (!isSupported(absPath)) {
@@ -6087,7 +6158,7 @@ Keep it concise but INCLUDE THE ACTUAL DATA.`;
6087
6158
  execute: async ({ path, startLine, endLine }) => {
6088
6159
  try {
6089
6160
  const absolutePath = isAbsolute5(path) ? path : resolve9(workingDirectory, path);
6090
- if (!existsSync12(absolutePath)) {
6161
+ if (!existsSync13(absolutePath)) {
6091
6162
  return {
6092
6163
  success: false,
6093
6164
  error: `File not found: ${path}`
@@ -6131,7 +6202,7 @@ Keep it concise but INCLUDE THE ACTUAL DATA.`;
6131
6202
  execute: async ({ path, recursive, maxDepth }) => {
6132
6203
  try {
6133
6204
  const absolutePath = isAbsolute5(path) ? path : resolve9(workingDirectory, path);
6134
- if (!existsSync12(absolutePath)) {
6205
+ if (!existsSync13(absolutePath)) {
6135
6206
  return {
6136
6207
  success: false,
6137
6208
  error: `Directory not found: ${path}`
@@ -6499,7 +6570,7 @@ function createTaskFailedTool(options) {
6499
6570
  import { tool as tool12 } from "ai";
6500
6571
  import { z as z13 } from "zod";
6501
6572
  import { readFile as readFile9, stat as stat4 } from "fs/promises";
6502
- import { join as join5, basename as basename4, extname as extname7 } from "path";
6573
+ import { join as join6, basename as basename4, extname as extname7 } from "path";
6503
6574
  var MIME_TYPES = {
6504
6575
  ".txt": "text/plain",
6505
6576
  ".md": "text/markdown",
@@ -6541,7 +6612,7 @@ function createUploadFileTool(options) {
6541
6612
  error: "File upload is not available \u2014 remote server with GCS is not configured."
6542
6613
  };
6543
6614
  }
6544
- const fullPath = input.path.startsWith("/") ? input.path : join5(options.workingDirectory, input.path);
6615
+ const fullPath = input.path.startsWith("/") ? input.path : join6(options.workingDirectory, input.path);
6545
6616
  try {
6546
6617
  await stat4(fullPath);
6547
6618
  } catch {
@@ -8106,11 +8177,11 @@ ${taskAddendum}`;
8106
8177
  const { isRemoteConfigured: isRemoteConfigured2, storageQueries: storageQueries2 } = await Promise.resolve().then(() => (init_remote(), remote_exports));
8107
8178
  if (!isRemoteConfigured2()) return [];
8108
8179
  const { readFile: readFile11 } = await import("fs/promises");
8109
- const { join: join12, basename: basename6 } = await import("path");
8180
+ const { join: join13, basename: basename6 } = await import("path");
8110
8181
  const urls = [];
8111
8182
  for (const filePath of filePaths) {
8112
8183
  try {
8113
- const fullPath = filePath.startsWith("/") ? filePath : join12(this.session.workingDirectory, filePath);
8184
+ const fullPath = filePath.startsWith("/") ? filePath : join13(this.session.workingDirectory, filePath);
8114
8185
  const fileName = basename6(fullPath);
8115
8186
  const ext = fileName.split(".").pop()?.toLowerCase() || "";
8116
8187
  const mimeMap = {
@@ -8740,12 +8811,12 @@ sessions.get("/:id/diff/:filePath", async (c) => {
8740
8811
  });
8741
8812
  function getAttachmentsDir(sessionId) {
8742
8813
  const appDataDir = getAppDataDirectory();
8743
- return join7(appDataDir, "attachments", sessionId);
8814
+ return join8(appDataDir, "attachments", sessionId);
8744
8815
  }
8745
8816
  function ensureAttachmentsDir(sessionId) {
8746
8817
  const dir = getAttachmentsDir(sessionId);
8747
- if (!existsSync13(dir)) {
8748
- mkdirSync3(dir, { recursive: true });
8818
+ if (!existsSync14(dir)) {
8819
+ mkdirSync4(dir, { recursive: true });
8749
8820
  }
8750
8821
  return dir;
8751
8822
  }
@@ -8756,12 +8827,12 @@ sessions.get("/:id/attachments", async (c) => {
8756
8827
  return c.json({ error: "Session not found" }, 404);
8757
8828
  }
8758
8829
  const dir = getAttachmentsDir(sessionId);
8759
- if (!existsSync13(dir)) {
8830
+ if (!existsSync14(dir)) {
8760
8831
  return c.json({ sessionId, attachments: [], count: 0 });
8761
8832
  }
8762
8833
  const files = readdirSync(dir);
8763
8834
  const attachments = files.map((filename) => {
8764
- const filePath = join7(dir, filename);
8835
+ const filePath = join8(dir, filename);
8765
8836
  const stats = statSync2(filePath);
8766
8837
  return {
8767
8838
  id: filename.split("_")[0],
@@ -8796,9 +8867,9 @@ sessions.post("/:id/attachments", async (c) => {
8796
8867
  const id = nanoid5(10);
8797
8868
  const ext = extname8(file.name) || "";
8798
8869
  const safeFilename = `${id}_${basename5(file.name).replace(/[^a-zA-Z0-9._-]/g, "_")}`;
8799
- const filePath = join7(dir, safeFilename);
8870
+ const filePath = join8(dir, safeFilename);
8800
8871
  const arrayBuffer = await file.arrayBuffer();
8801
- writeFileSync2(filePath, Buffer.from(arrayBuffer));
8872
+ writeFileSync3(filePath, Buffer.from(arrayBuffer));
8802
8873
  return c.json({
8803
8874
  id,
8804
8875
  filename: file.name,
@@ -8822,13 +8893,13 @@ sessions.post("/:id/attachments", async (c) => {
8822
8893
  const id = nanoid5(10);
8823
8894
  const ext = extname8(body.filename) || "";
8824
8895
  const safeFilename = `${id}_${basename5(body.filename).replace(/[^a-zA-Z0-9._-]/g, "_")}`;
8825
- const filePath = join7(dir, safeFilename);
8896
+ const filePath = join8(dir, safeFilename);
8826
8897
  let base64Data = body.data;
8827
8898
  if (base64Data.includes(",")) {
8828
8899
  base64Data = base64Data.split(",")[1];
8829
8900
  }
8830
8901
  const buffer = Buffer.from(base64Data, "base64");
8831
- writeFileSync2(filePath, buffer);
8902
+ writeFileSync3(filePath, buffer);
8832
8903
  return c.json({
8833
8904
  id,
8834
8905
  filename: body.filename,
@@ -8851,7 +8922,7 @@ sessions.delete("/:id/attachments/:attachmentId", async (c) => {
8851
8922
  return c.json({ error: "Session not found" }, 404);
8852
8923
  }
8853
8924
  const dir = getAttachmentsDir(sessionId);
8854
- if (!existsSync13(dir)) {
8925
+ if (!existsSync14(dir)) {
8855
8926
  return c.json({ error: "Attachment not found" }, 404);
8856
8927
  }
8857
8928
  const files = readdirSync(dir);
@@ -8859,7 +8930,7 @@ sessions.delete("/:id/attachments/:attachmentId", async (c) => {
8859
8930
  if (!file) {
8860
8931
  return c.json({ error: "Attachment not found" }, 404);
8861
8932
  }
8862
- const filePath = join7(dir, file);
8933
+ const filePath = join8(dir, file);
8863
8934
  unlinkSync(filePath);
8864
8935
  return c.json({ success: true, id: attachmentId });
8865
8936
  });
@@ -8942,7 +9013,7 @@ async function listWorkspaceFiles(baseDir, currentDir, query, limit, results = [
8942
9013
  const entries = await readdir6(currentDir, { withFileTypes: true });
8943
9014
  for (const entry of entries) {
8944
9015
  if (results.length >= limit * 2) break;
8945
- const fullPath = join7(currentDir, entry.name);
9016
+ const fullPath = join8(currentDir, entry.name);
8946
9017
  const relativePath = relative9(baseDir, fullPath);
8947
9018
  if (entry.isDirectory() && IGNORED_DIRECTORIES.has(entry.name)) {
8948
9019
  continue;
@@ -8990,7 +9061,7 @@ sessions.get(
8990
9061
  return c.json({ error: "Session not found" }, 404);
8991
9062
  }
8992
9063
  const workingDirectory = session.workingDirectory;
8993
- if (!existsSync13(workingDirectory)) {
9064
+ if (!existsSync14(workingDirectory)) {
8994
9065
  return c.json({
8995
9066
  sessionId,
8996
9067
  workingDirectory,
@@ -9101,8 +9172,8 @@ init_db();
9101
9172
  import { Hono as Hono2 } from "hono";
9102
9173
  import { zValidator as zValidator2 } from "@hono/zod-validator";
9103
9174
  import { z as z16 } from "zod";
9104
- import { existsSync as existsSync14, mkdirSync as mkdirSync4, writeFileSync as writeFileSync3 } from "fs";
9105
- import { join as join8 } from "path";
9175
+ import { existsSync as existsSync15, mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "fs";
9176
+ import { join as join9 } from "path";
9106
9177
  init_config();
9107
9178
 
9108
9179
  // src/server/resumable-stream.ts
@@ -9308,12 +9379,12 @@ var rejectSchema = z16.object({
9308
9379
  var streamAbortControllers = /* @__PURE__ */ new Map();
9309
9380
  function getAttachmentsDirectory(sessionId) {
9310
9381
  const appDataDir = getAppDataDirectory();
9311
- return join8(appDataDir, "attachments", sessionId);
9382
+ return join9(appDataDir, "attachments", sessionId);
9312
9383
  }
9313
- function saveAttachmentToDisk(sessionId, attachment, index) {
9384
+ async function saveAttachmentToDisk(sessionId, attachment, index) {
9314
9385
  const attachmentsDir = getAttachmentsDirectory(sessionId);
9315
- if (!existsSync14(attachmentsDir)) {
9316
- mkdirSync4(attachmentsDir, { recursive: true });
9386
+ if (!existsSync15(attachmentsDir)) {
9387
+ mkdirSync5(attachmentsDir, { recursive: true });
9317
9388
  }
9318
9389
  let filename = attachment.filename;
9319
9390
  if (!filename) {
@@ -9324,9 +9395,14 @@ function saveAttachmentToDisk(sessionId, attachment, index) {
9324
9395
  if (base64Data.includes(",")) {
9325
9396
  base64Data = base64Data.split(",")[1];
9326
9397
  }
9327
- const filePath = join8(attachmentsDir, filename);
9328
- const buffer = Buffer.from(base64Data, "base64");
9329
- writeFileSync3(filePath, buffer);
9398
+ let buffer = Buffer.from(base64Data, "base64");
9399
+ if (attachment.type === "image") {
9400
+ buffer = await resizeImageIfNeeded(buffer, attachment.mediaType);
9401
+ const prefix = attachment.data.includes(",") ? attachment.data.split(",")[0] + "," : "";
9402
+ attachment.data = prefix + buffer.toString("base64");
9403
+ }
9404
+ const filePath = join9(attachmentsDir, filename);
9405
+ writeFileSync4(filePath, buffer);
9330
9406
  return filePath;
9331
9407
  }
9332
9408
  function getExtensionFromMediaType(mediaType, type) {
@@ -9686,7 +9762,7 @@ agents.post(
9686
9762
  for (let i = 0; i < streamAttachments.length; i++) {
9687
9763
  const attachment = streamAttachments[i];
9688
9764
  try {
9689
- const savedPath = saveAttachmentToDisk(id, attachment, i);
9765
+ const savedPath = await saveAttachmentToDisk(id, attachment, i);
9690
9766
  attachment.savedPath = savedPath;
9691
9767
  } catch (err) {
9692
9768
  console.error(`Failed to save attachment ${i}:`, err);
@@ -10260,26 +10336,26 @@ init_config();
10260
10336
  import { Hono as Hono3 } from "hono";
10261
10337
  import { zValidator as zValidator3 } from "@hono/zod-validator";
10262
10338
  import { z as z17 } from "zod";
10263
- import { readFileSync as readFileSync5 } from "fs";
10339
+ import { readFileSync as readFileSync6 } from "fs";
10264
10340
  import { fileURLToPath as fileURLToPath3 } from "url";
10265
- import { dirname as dirname6, join as join9 } from "path";
10341
+ import { dirname as dirname6, join as join10 } from "path";
10266
10342
  var __filename = fileURLToPath3(import.meta.url);
10267
10343
  var __dirname = dirname6(__filename);
10268
10344
  var possiblePaths = [
10269
- join9(__dirname, "../package.json"),
10345
+ join10(__dirname, "../package.json"),
10270
10346
  // From dist/server -> dist/../package.json
10271
- join9(__dirname, "../../package.json"),
10347
+ join10(__dirname, "../../package.json"),
10272
10348
  // From dist/server (if nested differently)
10273
- join9(__dirname, "../../../package.json"),
10349
+ join10(__dirname, "../../../package.json"),
10274
10350
  // From src/server/routes (development)
10275
- join9(process.cwd(), "package.json")
10351
+ join10(process.cwd(), "package.json")
10276
10352
  // From current working directory
10277
10353
  ];
10278
10354
  var currentVersion = "0.0.0";
10279
10355
  var packageName = "sparkecoder";
10280
10356
  for (const packageJsonPath of possiblePaths) {
10281
10357
  try {
10282
- const packageJson = JSON.parse(readFileSync5(packageJsonPath, "utf-8"));
10358
+ const packageJson = JSON.parse(readFileSync6(packageJsonPath, "utf-8"));
10283
10359
  if (packageJson.name === "sparkecoder") {
10284
10360
  currentVersion = packageJson.version || "0.0.0";
10285
10361
  packageName = packageJson.name || "sparkecoder";
@@ -11091,11 +11167,11 @@ function getWebDirectory() {
11091
11167
  try {
11092
11168
  const currentDir = dirname7(fileURLToPath4(import.meta.url));
11093
11169
  const webDir = resolve10(currentDir, "..", "web");
11094
- if (existsSync15(webDir) && existsSync15(join10(webDir, "package.json"))) {
11170
+ if (existsSync16(webDir) && existsSync16(join11(webDir, "package.json"))) {
11095
11171
  return webDir;
11096
11172
  }
11097
11173
  const altWebDir = resolve10(currentDir, "..", "..", "web");
11098
- if (existsSync15(altWebDir) && existsSync15(join10(altWebDir, "package.json"))) {
11174
+ if (existsSync16(altWebDir) && existsSync16(join11(altWebDir, "package.json"))) {
11099
11175
  return altWebDir;
11100
11176
  }
11101
11177
  return null;
@@ -11153,23 +11229,23 @@ async function findWebPort(preferredPort) {
11153
11229
  return { port: preferredPort, alreadyRunning: false };
11154
11230
  }
11155
11231
  function hasProductionBuild(webDir) {
11156
- const buildIdPath = join10(webDir, ".next", "BUILD_ID");
11157
- return existsSync15(buildIdPath);
11232
+ const buildIdPath = join11(webDir, ".next", "BUILD_ID");
11233
+ return existsSync16(buildIdPath);
11158
11234
  }
11159
11235
  function hasSourceFiles(webDir) {
11160
- const appDir = join10(webDir, "src", "app");
11161
- const pagesDir = join10(webDir, "src", "pages");
11162
- const rootAppDir = join10(webDir, "app");
11163
- const rootPagesDir = join10(webDir, "pages");
11164
- return existsSync15(appDir) || existsSync15(pagesDir) || existsSync15(rootAppDir) || existsSync15(rootPagesDir);
11236
+ const appDir = join11(webDir, "src", "app");
11237
+ const pagesDir = join11(webDir, "src", "pages");
11238
+ const rootAppDir = join11(webDir, "app");
11239
+ const rootPagesDir = join11(webDir, "pages");
11240
+ return existsSync16(appDir) || existsSync16(pagesDir) || existsSync16(rootAppDir) || existsSync16(rootPagesDir);
11165
11241
  }
11166
11242
  function getStandaloneServerPath(webDir) {
11167
11243
  const possiblePaths2 = [
11168
- join10(webDir, ".next", "standalone", "server.js"),
11169
- join10(webDir, ".next", "standalone", "web", "server.js")
11244
+ join11(webDir, ".next", "standalone", "server.js"),
11245
+ join11(webDir, ".next", "standalone", "web", "server.js")
11170
11246
  ];
11171
11247
  for (const serverPath of possiblePaths2) {
11172
- if (existsSync15(serverPath)) {
11248
+ if (existsSync16(serverPath)) {
11173
11249
  return serverPath;
11174
11250
  }
11175
11251
  }
@@ -11209,15 +11285,15 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false, pu
11209
11285
  if (!quiet) console.log(` \u2713 Web UI already running at http://localhost:${actualPort}`);
11210
11286
  return { process: null, port: actualPort };
11211
11287
  }
11212
- const usePnpm = existsSync15(join10(webDir, "pnpm-lock.yaml"));
11213
- const useNpm = !usePnpm && existsSync15(join10(webDir, "package-lock.json"));
11288
+ const usePnpm = existsSync16(join11(webDir, "pnpm-lock.yaml"));
11289
+ const useNpm = !usePnpm && existsSync16(join11(webDir, "package-lock.json"));
11214
11290
  const pkgManager = usePnpm ? "pnpm" : useNpm ? "npm" : "npx";
11215
11291
  const { NODE_OPTIONS, TSX_TSCONFIG_PATH, ...cleanEnv } = process.env;
11216
11292
  const apiUrl = publicUrl || `http://127.0.0.1:${apiPort}`;
11217
11293
  const runtimeConfig = { apiBaseUrl: apiUrl };
11218
- const runtimeConfigPath = join10(webDir, "runtime-config.json");
11294
+ const runtimeConfigPath = join11(webDir, "runtime-config.json");
11219
11295
  try {
11220
- writeFileSync4(runtimeConfigPath, JSON.stringify(runtimeConfig, null, 2));
11296
+ writeFileSync5(runtimeConfigPath, JSON.stringify(runtimeConfig, null, 2));
11221
11297
  if (!quiet) console.log(` \u{1F4DD} Runtime config written to ${runtimeConfigPath}`);
11222
11298
  } catch (err) {
11223
11299
  if (!quiet) console.warn(` \u26A0 Could not write runtime config: ${err}`);
@@ -11408,8 +11484,8 @@ async function startServer(options = {}) {
11408
11484
  if (options.workingDirectory) {
11409
11485
  config.resolvedWorkingDirectory = options.workingDirectory;
11410
11486
  }
11411
- if (!existsSync15(config.resolvedWorkingDirectory)) {
11412
- mkdirSync5(config.resolvedWorkingDirectory, { recursive: true });
11487
+ if (!existsSync16(config.resolvedWorkingDirectory)) {
11488
+ mkdirSync6(config.resolvedWorkingDirectory, { recursive: true });
11413
11489
  if (!options.quiet) console.log(`\u{1F4C1} Created agent workspace: ${config.resolvedWorkingDirectory}`);
11414
11490
  }
11415
11491
  if (!config.resolvedRemoteServer.url) {
@@ -11925,8 +12001,8 @@ function generateOpenAPISpec() {
11925
12001
  init_config();
11926
12002
  init_semantic();
11927
12003
  init_db();
11928
- import { writeFileSync as writeFileSync5, readFileSync as readFileSync6, existsSync as existsSync16 } from "fs";
11929
- import { resolve as resolve11, join as join11 } from "path";
12004
+ import { writeFileSync as writeFileSync6, readFileSync as readFileSync7, existsSync as existsSync17 } from "fs";
12005
+ import { resolve as resolve11, join as join12 } from "path";
11930
12006
  async function apiRequest(baseUrl, path, options = {}) {
11931
12007
  const url = `${baseUrl}${path}`;
11932
12008
  const init = {
@@ -12561,8 +12637,8 @@ program.command("task").description("Run an autonomous task that completes witho
12561
12637
  let outputSchema;
12562
12638
  try {
12563
12639
  const schemaStr = options.schema;
12564
- if (existsSync16(schemaStr)) {
12565
- outputSchema = JSON.parse(readFileSync6(schemaStr, "utf-8"));
12640
+ if (existsSync17(schemaStr)) {
12641
+ outputSchema = JSON.parse(readFileSync7(schemaStr, "utf-8"));
12566
12642
  } else {
12567
12643
  outputSchema = JSON.parse(schemaStr);
12568
12644
  }
@@ -12628,19 +12704,19 @@ program.command("init").description("Create a sparkecoder.config.json file").opt
12628
12704
  let configLocation;
12629
12705
  if (options.global) {
12630
12706
  const appDataDir = ensureAppDataDirectory();
12631
- configPath = join11(appDataDir, "sparkecoder.config.json");
12707
+ configPath = join12(appDataDir, "sparkecoder.config.json");
12632
12708
  configLocation = "global";
12633
12709
  } else {
12634
12710
  configPath = resolve11(process.cwd(), "sparkecoder.config.json");
12635
12711
  configLocation = "local";
12636
12712
  }
12637
- if (existsSync16(configPath) && !options.force) {
12713
+ if (existsSync17(configPath) && !options.force) {
12638
12714
  console.log(chalk.yellow("Config file already exists. Use --force to overwrite."));
12639
12715
  console.log(chalk.dim(` ${configPath}`));
12640
12716
  return;
12641
12717
  }
12642
12718
  const config = createDefaultConfig();
12643
- writeFileSync5(configPath, JSON.stringify(config, null, 2));
12719
+ writeFileSync6(configPath, JSON.stringify(config, null, 2));
12644
12720
  console.log(chalk.green(`\u2713 Created ${configLocation} config`));
12645
12721
  console.log(chalk.dim(` ${configPath}`));
12646
12722
  console.log(chalk.dim("Set AI_GATEWAY_API_KEY and run sparkecoder to start"));