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.
- package/dist/agent/index.js +114 -43
- package/dist/agent/index.js.map +1 -1
- package/dist/cli.js +186 -110
- package/dist/cli.js.map +1 -1
- package/dist/index.js +174 -98
- package/dist/index.js.map +1 -1
- package/dist/server/index.js +174 -98
- package/dist/server/index.js.map +1 -1
- package/dist/tools/index.js +105 -34
- package/dist/tools/index.js.map +1 -1
- package/package.json +2 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/node_modules/.pnpm/sharp@0.34.5/node_modules/sharp/package.json +202 -0
- package/web/.next/standalone/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.html +1 -1
- package/web/.next/standalone/web/.next/server/app/index.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
- package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
- /package/web/.next/standalone/web/.next/static/{static/xfMAecV1v1MVUkZE1r3BT → nZpzcWd5nqIPZFd3PiefU}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{static/xfMAecV1v1MVUkZE1r3BT → nZpzcWd5nqIPZFd3PiefU}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{static/xfMAecV1v1MVUkZE1r3BT → nZpzcWd5nqIPZFd3PiefU}/_ssgManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{xfMAecV1v1MVUkZE1r3BT → static/nZpzcWd5nqIPZFd3PiefU}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{xfMAecV1v1MVUkZE1r3BT → static/nZpzcWd5nqIPZFd3PiefU}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{xfMAecV1v1MVUkZE1r3BT → static/nZpzcWd5nqIPZFd3PiefU}/_ssgManifest.js +0 -0
- /package/web/.next/static/{xfMAecV1v1MVUkZE1r3BT → nZpzcWd5nqIPZFd3PiefU}/_buildManifest.js +0 -0
- /package/web/.next/static/{xfMAecV1v1MVUkZE1r3BT → nZpzcWd5nqIPZFd3PiefU}/_clientMiddlewareManifest.json +0 -0
- /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
|
|
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 (!
|
|
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 (
|
|
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 || !
|
|
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 =
|
|
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
|
|
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:
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
2387
|
-
import { join as
|
|
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 =
|
|
2455
|
-
if (!
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 "${
|
|
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(
|
|
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
|
|
2874
|
-
import { resolve as resolve10, dirname as dirname7, join as
|
|
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
|
|
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
|
|
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
|
|
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 (!
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
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 (!
|
|
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 (
|
|
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 (
|
|
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
|
|
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 (
|
|
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
|
|
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 (!
|
|
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 (!
|
|
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 =
|
|
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 (!
|
|
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 (!
|
|
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
|
|
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 (!
|
|
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
|
|
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
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
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
|
|
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 :
|
|
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:
|
|
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 :
|
|
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
|
|
8814
|
+
return join8(appDataDir, "attachments", sessionId);
|
|
8744
8815
|
}
|
|
8745
8816
|
function ensureAttachmentsDir(sessionId) {
|
|
8746
8817
|
const dir = getAttachmentsDir(sessionId);
|
|
8747
|
-
if (!
|
|
8748
|
-
|
|
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 (!
|
|
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 =
|
|
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 =
|
|
8870
|
+
const filePath = join8(dir, safeFilename);
|
|
8800
8871
|
const arrayBuffer = await file.arrayBuffer();
|
|
8801
|
-
|
|
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 =
|
|
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
|
-
|
|
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 (!
|
|
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 =
|
|
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 =
|
|
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 (!
|
|
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
|
|
9105
|
-
import { join as
|
|
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
|
|
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 (!
|
|
9316
|
-
|
|
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
|
-
|
|
9328
|
-
|
|
9329
|
-
|
|
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
|
|
10339
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
10264
10340
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
10265
|
-
import { dirname as dirname6, join as
|
|
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
|
-
|
|
10345
|
+
join10(__dirname, "../package.json"),
|
|
10270
10346
|
// From dist/server -> dist/../package.json
|
|
10271
|
-
|
|
10347
|
+
join10(__dirname, "../../package.json"),
|
|
10272
10348
|
// From dist/server (if nested differently)
|
|
10273
|
-
|
|
10349
|
+
join10(__dirname, "../../../package.json"),
|
|
10274
10350
|
// From src/server/routes (development)
|
|
10275
|
-
|
|
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(
|
|
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 (
|
|
11170
|
+
if (existsSync16(webDir) && existsSync16(join11(webDir, "package.json"))) {
|
|
11095
11171
|
return webDir;
|
|
11096
11172
|
}
|
|
11097
11173
|
const altWebDir = resolve10(currentDir, "..", "..", "web");
|
|
11098
|
-
if (
|
|
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 =
|
|
11157
|
-
return
|
|
11232
|
+
const buildIdPath = join11(webDir, ".next", "BUILD_ID");
|
|
11233
|
+
return existsSync16(buildIdPath);
|
|
11158
11234
|
}
|
|
11159
11235
|
function hasSourceFiles(webDir) {
|
|
11160
|
-
const appDir =
|
|
11161
|
-
const pagesDir =
|
|
11162
|
-
const rootAppDir =
|
|
11163
|
-
const rootPagesDir =
|
|
11164
|
-
return
|
|
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
|
-
|
|
11169
|
-
|
|
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 (
|
|
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 =
|
|
11213
|
-
const useNpm = !usePnpm &&
|
|
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 =
|
|
11294
|
+
const runtimeConfigPath = join11(webDir, "runtime-config.json");
|
|
11219
11295
|
try {
|
|
11220
|
-
|
|
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 (!
|
|
11412
|
-
|
|
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
|
|
11929
|
-
import { resolve as resolve11, join as
|
|
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 (
|
|
12565
|
-
outputSchema = JSON.parse(
|
|
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 =
|
|
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 (
|
|
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
|
-
|
|
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"));
|