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/server/index.js
CHANGED
|
@@ -1024,7 +1024,7 @@ __export(skills_exports, {
|
|
|
1024
1024
|
});
|
|
1025
1025
|
import { readFile as readFile6, readdir } from "fs/promises";
|
|
1026
1026
|
import { resolve as resolve6, basename, extname as extname4, relative as relative4 } from "path";
|
|
1027
|
-
import { existsSync as
|
|
1027
|
+
import { existsSync as existsSync9 } from "fs";
|
|
1028
1028
|
import { minimatch } from "minimatch";
|
|
1029
1029
|
function parseSkillFrontmatter(content) {
|
|
1030
1030
|
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
@@ -1102,7 +1102,7 @@ async function loadSkillsFromDirectory(directory, options = {}) {
|
|
|
1102
1102
|
defaultLoadType = "on_demand",
|
|
1103
1103
|
forceAlwaysApply = false
|
|
1104
1104
|
} = options;
|
|
1105
|
-
if (!
|
|
1105
|
+
if (!existsSync9(directory)) {
|
|
1106
1106
|
return [];
|
|
1107
1107
|
}
|
|
1108
1108
|
const skills = [];
|
|
@@ -1112,7 +1112,7 @@ async function loadSkillsFromDirectory(directory, options = {}) {
|
|
|
1112
1112
|
let fileName;
|
|
1113
1113
|
if (entry.isDirectory()) {
|
|
1114
1114
|
const skillMdPath = resolve6(directory, entry.name, "SKILL.md");
|
|
1115
|
-
if (
|
|
1115
|
+
if (existsSync9(skillMdPath)) {
|
|
1116
1116
|
filePath = skillMdPath;
|
|
1117
1117
|
fileName = entry.name;
|
|
1118
1118
|
} else {
|
|
@@ -1252,7 +1252,7 @@ async function getGlobMatchedSkills(skills, activeFiles, workingDirectory) {
|
|
|
1252
1252
|
return matchedWithContent;
|
|
1253
1253
|
}
|
|
1254
1254
|
async function loadAgentsMd(agentsMdPath) {
|
|
1255
|
-
if (!agentsMdPath || !
|
|
1255
|
+
if (!agentsMdPath || !existsSync9(agentsMdPath)) {
|
|
1256
1256
|
return null;
|
|
1257
1257
|
}
|
|
1258
1258
|
const content = await readFile6(agentsMdPath, "utf-8");
|
|
@@ -1391,7 +1391,7 @@ var init_namespace = __esm({
|
|
|
1391
1391
|
});
|
|
1392
1392
|
|
|
1393
1393
|
// src/semantic/hasher.ts
|
|
1394
|
-
import { createHash } from "crypto";
|
|
1394
|
+
import { createHash as createHash2 } from "crypto";
|
|
1395
1395
|
var init_hasher = __esm({
|
|
1396
1396
|
"src/semantic/hasher.ts"() {
|
|
1397
1397
|
"use strict";
|
|
@@ -1527,7 +1527,7 @@ var init_client = __esm({
|
|
|
1527
1527
|
});
|
|
1528
1528
|
|
|
1529
1529
|
// src/semantic/indexer.ts
|
|
1530
|
-
import { readFileSync as
|
|
1530
|
+
import { readFileSync as readFileSync4, statSync } from "fs";
|
|
1531
1531
|
import { relative as relative6 } from "path";
|
|
1532
1532
|
import { minimatch as minimatch2 } from "minimatch";
|
|
1533
1533
|
async function getIndexStatus(workingDirectory) {
|
|
@@ -1612,8 +1612,8 @@ __export(semantic_search_exports, {
|
|
|
1612
1612
|
});
|
|
1613
1613
|
import { tool as tool8 } from "ai";
|
|
1614
1614
|
import { z as z9 } from "zod";
|
|
1615
|
-
import { existsSync as
|
|
1616
|
-
import { join as
|
|
1615
|
+
import { existsSync as existsSync12, readFileSync as readFileSync5 } from "fs";
|
|
1616
|
+
import { join as join5 } from "path";
|
|
1617
1617
|
import { minimatch as minimatch3 } from "minimatch";
|
|
1618
1618
|
function createSemanticSearchTool(options) {
|
|
1619
1619
|
return tool8({
|
|
@@ -1680,13 +1680,13 @@ Returns matching code snippets with file paths, line numbers, and relevance scor
|
|
|
1680
1680
|
if (language && matchLanguage !== language.toLowerCase()) {
|
|
1681
1681
|
continue;
|
|
1682
1682
|
}
|
|
1683
|
-
const fullPath =
|
|
1684
|
-
if (!
|
|
1683
|
+
const fullPath = join5(options.workingDirectory, filePath);
|
|
1684
|
+
if (!existsSync12(fullPath)) {
|
|
1685
1685
|
continue;
|
|
1686
1686
|
}
|
|
1687
1687
|
let snippet = "";
|
|
1688
1688
|
try {
|
|
1689
|
-
const content =
|
|
1689
|
+
const content = readFileSync5(fullPath, "utf-8");
|
|
1690
1690
|
const lines = content.split("\n");
|
|
1691
1691
|
const snippetLines = lines.slice(
|
|
1692
1692
|
Math.max(0, startLine - 1),
|
|
@@ -1982,7 +1982,7 @@ __export(recorder_exports, {
|
|
|
1982
1982
|
import { exec as exec5 } from "child_process";
|
|
1983
1983
|
import { promisify as promisify5 } from "util";
|
|
1984
1984
|
import { writeFile as writeFile4, mkdir as mkdir4, readFile as readFile10, unlink as unlink2, readdir as readdir5, rm } from "fs/promises";
|
|
1985
|
-
import { join as
|
|
1985
|
+
import { join as join7 } from "path";
|
|
1986
1986
|
import { tmpdir } from "os";
|
|
1987
1987
|
import { nanoid as nanoid3 } from "nanoid";
|
|
1988
1988
|
async function checkFfmpeg() {
|
|
@@ -2039,21 +2039,21 @@ var init_recorder = __esm({
|
|
|
2039
2039
|
*/
|
|
2040
2040
|
async encode() {
|
|
2041
2041
|
if (this.frames.length === 0) return null;
|
|
2042
|
-
const workDir =
|
|
2042
|
+
const workDir = join7(tmpdir(), `sparkecoder-recording-${nanoid3(8)}`);
|
|
2043
2043
|
await mkdir4(workDir, { recursive: true });
|
|
2044
2044
|
try {
|
|
2045
2045
|
for (let i = 0; i < this.frames.length; i++) {
|
|
2046
|
-
const framePath =
|
|
2046
|
+
const framePath = join7(workDir, `frame_${String(i).padStart(6, "0")}.jpg`);
|
|
2047
2047
|
await writeFile4(framePath, this.frames[i].data);
|
|
2048
2048
|
}
|
|
2049
2049
|
const duration = (this.frames[this.frames.length - 1].timestamp - this.frames[0].timestamp) / 1e3;
|
|
2050
2050
|
const fps = duration > 0 ? Math.round(this.frames.length / duration) : 10;
|
|
2051
2051
|
const clampedFps = Math.max(1, Math.min(fps, 30));
|
|
2052
|
-
const outputPath =
|
|
2052
|
+
const outputPath = join7(workDir, `recording_${this.sessionId}.mp4`);
|
|
2053
2053
|
const hasFfmpeg = await checkFfmpeg();
|
|
2054
2054
|
if (hasFfmpeg) {
|
|
2055
2055
|
await execAsync5(
|
|
2056
|
-
`ffmpeg -y -framerate ${clampedFps} -i "${
|
|
2056
|
+
`ffmpeg -y -framerate ${clampedFps} -i "${join7(workDir, "frame_%06d.jpg")}" -c:v libx264 -pix_fmt yuv420p -preset fast -crf 23 "${outputPath}"`,
|
|
2057
2057
|
{ timeout: 12e4 }
|
|
2058
2058
|
);
|
|
2059
2059
|
} else {
|
|
@@ -2065,7 +2065,7 @@ var init_recorder = __esm({
|
|
|
2065
2065
|
const files = await readdir5(workDir);
|
|
2066
2066
|
for (const f of files) {
|
|
2067
2067
|
if (f.startsWith("frame_")) {
|
|
2068
|
-
await unlink2(
|
|
2068
|
+
await unlink2(join7(workDir, f)).catch(() => {
|
|
2069
2069
|
});
|
|
2070
2070
|
}
|
|
2071
2071
|
}
|
|
@@ -2092,8 +2092,8 @@ import { Hono as Hono6 } from "hono";
|
|
|
2092
2092
|
import { serve } from "@hono/node-server";
|
|
2093
2093
|
import { cors } from "hono/cors";
|
|
2094
2094
|
import { logger } from "hono/logger";
|
|
2095
|
-
import { existsSync as
|
|
2096
|
-
import { resolve as resolve10, dirname as dirname7, join as
|
|
2095
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
2096
|
+
import { resolve as resolve10, dirname as dirname7, join as join11 } from "path";
|
|
2097
2097
|
import { spawn as spawn2 } from "child_process";
|
|
2098
2098
|
import { createServer as createNetServer } from "net";
|
|
2099
2099
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
@@ -2103,9 +2103,9 @@ init_db();
|
|
|
2103
2103
|
import { Hono } from "hono";
|
|
2104
2104
|
import { zValidator } from "@hono/zod-validator";
|
|
2105
2105
|
import { z as z15 } from "zod";
|
|
2106
|
-
import { existsSync as
|
|
2106
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync4, writeFileSync as writeFileSync3, readdirSync, statSync as statSync2, unlinkSync } from "fs";
|
|
2107
2107
|
import { readdir as readdir6 } from "fs/promises";
|
|
2108
|
-
import { join as
|
|
2108
|
+
import { join as join8, basename as basename5, extname as extname8, relative as relative9 } from "path";
|
|
2109
2109
|
import { nanoid as nanoid5 } from "nanoid";
|
|
2110
2110
|
|
|
2111
2111
|
// src/agent/index.ts
|
|
@@ -2937,7 +2937,77 @@ import { tool as tool2 } from "ai";
|
|
|
2937
2937
|
import { z as z3 } from "zod";
|
|
2938
2938
|
import { readFile as readFile2, stat } from "fs/promises";
|
|
2939
2939
|
import { resolve as resolve2, relative, isAbsolute, extname } from "path";
|
|
2940
|
-
import { existsSync as
|
|
2940
|
+
import { existsSync as existsSync4 } from "fs";
|
|
2941
|
+
|
|
2942
|
+
// src/utils/resize-image.ts
|
|
2943
|
+
init_config();
|
|
2944
|
+
import sharp from "sharp";
|
|
2945
|
+
import { createHash } from "crypto";
|
|
2946
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
2947
|
+
import { join as join3 } from "path";
|
|
2948
|
+
var MAX_LONG_EDGE = 1568;
|
|
2949
|
+
var MAX_FILE_BYTES = 5 * 1024 * 1024;
|
|
2950
|
+
var CACHE_DIR_NAME = "image-cache";
|
|
2951
|
+
function getCacheDir() {
|
|
2952
|
+
const dir = join3(getAppDataDirectory(), CACHE_DIR_NAME);
|
|
2953
|
+
if (!existsSync3(dir)) mkdirSync3(dir, { recursive: true });
|
|
2954
|
+
return dir;
|
|
2955
|
+
}
|
|
2956
|
+
function cacheKey(buffer) {
|
|
2957
|
+
return createHash("sha256").update(buffer).digest("hex");
|
|
2958
|
+
}
|
|
2959
|
+
async function resizeImageIfNeeded(buffer, mediaType) {
|
|
2960
|
+
let metadata;
|
|
2961
|
+
try {
|
|
2962
|
+
metadata = await sharp(buffer).metadata();
|
|
2963
|
+
} catch {
|
|
2964
|
+
return buffer;
|
|
2965
|
+
}
|
|
2966
|
+
const { width, height } = metadata;
|
|
2967
|
+
if (!width || !height) return buffer;
|
|
2968
|
+
const longEdge = Math.max(width, height);
|
|
2969
|
+
const needsResize = longEdge > MAX_LONG_EDGE;
|
|
2970
|
+
const needsShrink = buffer.length > MAX_FILE_BYTES;
|
|
2971
|
+
if (!needsResize && !needsShrink) return buffer;
|
|
2972
|
+
const key = cacheKey(buffer);
|
|
2973
|
+
const cacheDir = getCacheDir();
|
|
2974
|
+
const isPng = mediaType?.includes("png");
|
|
2975
|
+
const ext = isPng ? ".png" : ".jpg";
|
|
2976
|
+
const cachePath = join3(cacheDir, key + ext);
|
|
2977
|
+
if (existsSync3(cachePath)) {
|
|
2978
|
+
console.log(`[image-resize] Cache hit for ${width}x${height} image`);
|
|
2979
|
+
return readFileSync2(cachePath);
|
|
2980
|
+
}
|
|
2981
|
+
let pipeline = sharp(buffer);
|
|
2982
|
+
if (needsResize) {
|
|
2983
|
+
pipeline = pipeline.resize(MAX_LONG_EDGE, MAX_LONG_EDGE, {
|
|
2984
|
+
fit: "inside",
|
|
2985
|
+
withoutEnlargement: true
|
|
2986
|
+
});
|
|
2987
|
+
}
|
|
2988
|
+
let result;
|
|
2989
|
+
if (isPng && (needsShrink || buffer.length > 2 * 1024 * 1024)) {
|
|
2990
|
+
result = await pipeline.jpeg({ quality: 85 }).toBuffer();
|
|
2991
|
+
} else if (isPng) {
|
|
2992
|
+
result = await pipeline.png().toBuffer();
|
|
2993
|
+
} else {
|
|
2994
|
+
result = await pipeline.jpeg({ quality: 85 }).toBuffer();
|
|
2995
|
+
}
|
|
2996
|
+
if (result.length > MAX_FILE_BYTES) {
|
|
2997
|
+
for (const quality of [70, 50, 30]) {
|
|
2998
|
+
result = await sharp(buffer).resize(MAX_LONG_EDGE, MAX_LONG_EDGE, { fit: "inside", withoutEnlargement: true }).jpeg({ quality }).toBuffer();
|
|
2999
|
+
if (result.length <= MAX_FILE_BYTES) break;
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
writeFileSync2(cachePath, result);
|
|
3003
|
+
const resultMeta = await sharp(result).metadata();
|
|
3004
|
+
console.log(
|
|
3005
|
+
`[image-resize] ${width}x${height} -> ${resultMeta.width}x${resultMeta.height} (${(buffer.length / 1024).toFixed(0)}KB -> ${(result.length / 1024).toFixed(0)}KB)`
|
|
3006
|
+
);
|
|
3007
|
+
return result;
|
|
3008
|
+
}
|
|
3009
|
+
|
|
3010
|
+
// src/tools/read-file.ts
|
|
2941
3011
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
2942
3012
|
var MAX_IMAGE_SIZE = 20 * 1024 * 1024;
|
|
2943
3013
|
var MAX_OUTPUT_CHARS3 = 5e4;
|
|
@@ -2977,7 +3047,7 @@ Use this to understand existing code, check file contents, view screenshots, or
|
|
|
2977
3047
|
content: null
|
|
2978
3048
|
};
|
|
2979
3049
|
}
|
|
2980
|
-
if (!
|
|
3050
|
+
if (!existsSync4(absolutePath)) {
|
|
2981
3051
|
return {
|
|
2982
3052
|
success: false,
|
|
2983
3053
|
error: `File not found: ${filePath}`,
|
|
@@ -3000,9 +3070,10 @@ Use this to understand existing code, check file contents, view screenshots, or
|
|
|
3000
3070
|
content: null
|
|
3001
3071
|
};
|
|
3002
3072
|
}
|
|
3003
|
-
const
|
|
3004
|
-
const base64 = buffer.toString("base64");
|
|
3073
|
+
const rawBuffer = await readFile2(absolutePath);
|
|
3005
3074
|
const mediaType = getImageMediaType(absolutePath);
|
|
3075
|
+
const buffer = await resizeImageIfNeeded(rawBuffer, mediaType);
|
|
3076
|
+
const base64 = buffer.toString("base64");
|
|
3006
3077
|
return {
|
|
3007
3078
|
success: true,
|
|
3008
3079
|
path: absolutePath,
|
|
@@ -3081,12 +3152,12 @@ import { tool as tool3 } from "ai";
|
|
|
3081
3152
|
import { z as z4 } from "zod";
|
|
3082
3153
|
import { readFile as readFile5, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
3083
3154
|
import { resolve as resolve5, relative as relative3, isAbsolute as isAbsolute2, dirname as dirname5 } from "path";
|
|
3084
|
-
import { existsSync as
|
|
3155
|
+
import { existsSync as existsSync8 } from "fs";
|
|
3085
3156
|
|
|
3086
3157
|
// src/checkpoints/index.ts
|
|
3087
3158
|
init_db();
|
|
3088
3159
|
import { readFile as readFile3, writeFile as writeFile2, unlink, mkdir as mkdir2 } from "fs/promises";
|
|
3089
|
-
import { existsSync as
|
|
3160
|
+
import { existsSync as existsSync5 } from "fs";
|
|
3090
3161
|
import { resolve as resolve3, relative as relative2, dirname as dirname2 } from "path";
|
|
3091
3162
|
import { exec as exec3 } from "child_process";
|
|
3092
3163
|
import { promisify as promisify3 } from "util";
|
|
@@ -3139,7 +3210,7 @@ async function backupFile(sessionId, workingDirectory, filePath) {
|
|
|
3139
3210
|
}
|
|
3140
3211
|
let originalContent = null;
|
|
3141
3212
|
let existed = false;
|
|
3142
|
-
if (
|
|
3213
|
+
if (existsSync5(absolutePath)) {
|
|
3143
3214
|
try {
|
|
3144
3215
|
originalContent = await readFile3(absolutePath, "utf-8");
|
|
3145
3216
|
existed = true;
|
|
@@ -3194,13 +3265,13 @@ async function revertToCheckpoint(sessionId, checkpointId) {
|
|
|
3194
3265
|
try {
|
|
3195
3266
|
if (backup.existed && backup.originalContent !== null) {
|
|
3196
3267
|
const dir = dirname2(absolutePath);
|
|
3197
|
-
if (!
|
|
3268
|
+
if (!existsSync5(dir)) {
|
|
3198
3269
|
await mkdir2(dir, { recursive: true });
|
|
3199
3270
|
}
|
|
3200
3271
|
await writeFile2(absolutePath, backup.originalContent, "utf-8");
|
|
3201
3272
|
filesRestored++;
|
|
3202
3273
|
} else if (!backup.existed) {
|
|
3203
|
-
if (
|
|
3274
|
+
if (existsSync5(absolutePath)) {
|
|
3204
3275
|
await unlink(absolutePath);
|
|
3205
3276
|
filesDeleted++;
|
|
3206
3277
|
}
|
|
@@ -3243,7 +3314,7 @@ async function getSessionDiff(sessionId) {
|
|
|
3243
3314
|
const absolutePath = resolve3(workingDirectory, filePath);
|
|
3244
3315
|
let currentContent = null;
|
|
3245
3316
|
let currentExists = false;
|
|
3246
|
-
if (
|
|
3317
|
+
if (existsSync5(absolutePath)) {
|
|
3247
3318
|
try {
|
|
3248
3319
|
currentContent = await readFile3(absolutePath, "utf-8");
|
|
3249
3320
|
currentExists = true;
|
|
@@ -3276,14 +3347,14 @@ import { extname as extname3, dirname as dirname4 } from "path";
|
|
|
3276
3347
|
|
|
3277
3348
|
// src/lsp/servers.ts
|
|
3278
3349
|
import { spawn } from "child_process";
|
|
3279
|
-
import { existsSync as
|
|
3350
|
+
import { existsSync as existsSync6 } from "fs";
|
|
3280
3351
|
import { resolve as resolve4, dirname as dirname3 } from "path";
|
|
3281
3352
|
function findNearestRoot(startDir, markers) {
|
|
3282
3353
|
let dir = startDir;
|
|
3283
3354
|
const root = "/";
|
|
3284
3355
|
while (dir !== root) {
|
|
3285
3356
|
for (const marker of markers) {
|
|
3286
|
-
if (
|
|
3357
|
+
if (existsSync6(resolve4(dir, marker))) {
|
|
3287
3358
|
return dir;
|
|
3288
3359
|
}
|
|
3289
3360
|
}
|
|
@@ -3394,7 +3465,7 @@ import {
|
|
|
3394
3465
|
} from "vscode-jsonrpc/node.js";
|
|
3395
3466
|
import { pathToFileURL, fileURLToPath } from "url";
|
|
3396
3467
|
import { readFile as readFile4 } from "fs/promises";
|
|
3397
|
-
import { existsSync as
|
|
3468
|
+
import { existsSync as existsSync7 } from "fs";
|
|
3398
3469
|
import { extname as extname2, normalize } from "path";
|
|
3399
3470
|
function getLanguageId(filePath) {
|
|
3400
3471
|
const ext = extname2(filePath).toLowerCase();
|
|
@@ -3520,7 +3591,7 @@ async function createClient(serverId, handle, root) {
|
|
|
3520
3591
|
diagnostics,
|
|
3521
3592
|
async notifyOpen(filePath) {
|
|
3522
3593
|
const normalized = normalizePath(filePath);
|
|
3523
|
-
if (!
|
|
3594
|
+
if (!existsSync7(normalized)) {
|
|
3524
3595
|
return;
|
|
3525
3596
|
}
|
|
3526
3597
|
try {
|
|
@@ -3551,7 +3622,7 @@ async function createClient(serverId, handle, root) {
|
|
|
3551
3622
|
},
|
|
3552
3623
|
async notifyChange(filePath) {
|
|
3553
3624
|
const normalized = normalizePath(filePath);
|
|
3554
|
-
if (!
|
|
3625
|
+
if (!existsSync7(normalized)) {
|
|
3555
3626
|
return;
|
|
3556
3627
|
}
|
|
3557
3628
|
try {
|
|
@@ -3927,7 +3998,7 @@ Working directory: ${options.workingDirectory}`,
|
|
|
3927
3998
|
error: 'Content is required for "full" mode'
|
|
3928
3999
|
};
|
|
3929
4000
|
}
|
|
3930
|
-
const existed =
|
|
4001
|
+
const existed = existsSync8(absolutePath);
|
|
3931
4002
|
const action = existed ? "replaced" : "created";
|
|
3932
4003
|
console.log("[WRITE-FILE] onProgress callback exists:", !!options.onProgress);
|
|
3933
4004
|
console.log("[WRITE-FILE] Emitting started event for:", relativePath);
|
|
@@ -3974,7 +4045,7 @@ Working directory: ${options.workingDirectory}`,
|
|
|
3974
4045
|
}
|
|
3975
4046
|
await backupFile(options.sessionId, options.workingDirectory, absolutePath);
|
|
3976
4047
|
const dir = dirname5(absolutePath);
|
|
3977
|
-
if (!
|
|
4048
|
+
if (!existsSync8(dir)) {
|
|
3978
4049
|
await mkdir3(dir, { recursive: true });
|
|
3979
4050
|
}
|
|
3980
4051
|
await writeFile3(absolutePath, content, "utf-8");
|
|
@@ -4008,7 +4079,7 @@ Working directory: ${options.workingDirectory}`,
|
|
|
4008
4079
|
error: 'Both old_string and new_string are required for "str_replace" mode'
|
|
4009
4080
|
};
|
|
4010
4081
|
}
|
|
4011
|
-
if (!
|
|
4082
|
+
if (!existsSync8(absolutePath)) {
|
|
4012
4083
|
return {
|
|
4013
4084
|
success: false,
|
|
4014
4085
|
error: `File not found: ${path}. Use "full" mode to create new files.`
|
|
@@ -4306,7 +4377,7 @@ Once loaded, a skill's content will be available in the conversation context.`,
|
|
|
4306
4377
|
import { tool as tool6 } from "ai";
|
|
4307
4378
|
import { z as z7 } from "zod";
|
|
4308
4379
|
import { resolve as resolve7, relative as relative5, isAbsolute as isAbsolute3, extname as extname5 } from "path";
|
|
4309
|
-
import { existsSync as
|
|
4380
|
+
import { existsSync as existsSync10 } from "fs";
|
|
4310
4381
|
import { readdir as readdir2, stat as stat2 } from "fs/promises";
|
|
4311
4382
|
var linterInputSchema = z7.object({
|
|
4312
4383
|
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."),
|
|
@@ -4374,7 +4445,7 @@ Working directory: ${options.workingDirectory}`,
|
|
|
4374
4445
|
const filesToCheck = [];
|
|
4375
4446
|
for (const path of paths) {
|
|
4376
4447
|
const absolutePath = isAbsolute3(path) ? path : resolve7(options.workingDirectory, path);
|
|
4377
|
-
if (!
|
|
4448
|
+
if (!existsSync10(absolutePath)) {
|
|
4378
4449
|
continue;
|
|
4379
4450
|
}
|
|
4380
4451
|
const stats = await stat2(absolutePath);
|
|
@@ -4688,7 +4759,7 @@ import { exec as exec4 } from "child_process";
|
|
|
4688
4759
|
import { promisify as promisify4 } from "util";
|
|
4689
4760
|
import { readFile as readFile8, stat as stat3, readdir as readdir4 } from "fs/promises";
|
|
4690
4761
|
import { resolve as resolve9, relative as relative8, isAbsolute as isAbsolute5 } from "path";
|
|
4691
|
-
import { existsSync as
|
|
4762
|
+
import { existsSync as existsSync13 } from "fs";
|
|
4692
4763
|
init_semantic();
|
|
4693
4764
|
|
|
4694
4765
|
// src/tools/code-graph.ts
|
|
@@ -4696,7 +4767,7 @@ import { tool as tool7 } from "ai";
|
|
|
4696
4767
|
import { z as z8 } from "zod";
|
|
4697
4768
|
import { resolve as resolve8, relative as relative7, isAbsolute as isAbsolute4, basename as basename3 } from "path";
|
|
4698
4769
|
import { readFile as readFile7, readdir as readdir3 } from "fs/promises";
|
|
4699
|
-
import { existsSync as
|
|
4770
|
+
import { existsSync as existsSync11 } from "fs";
|
|
4700
4771
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
4701
4772
|
import { execFileSync } from "child_process";
|
|
4702
4773
|
var codeGraphInputSchema = z8.object({
|
|
@@ -4882,7 +4953,7 @@ Working directory: ${options.workingDirectory}`,
|
|
|
4882
4953
|
let defSymbol = null;
|
|
4883
4954
|
if (filePath) {
|
|
4884
4955
|
const absPath = isAbsolute4(filePath) ? filePath : resolve8(options.workingDirectory, filePath);
|
|
4885
|
-
if (!
|
|
4956
|
+
if (!existsSync11(absPath)) {
|
|
4886
4957
|
return { success: false, error: `File not found: ${filePath}` };
|
|
4887
4958
|
}
|
|
4888
4959
|
if (!isSupported(absPath)) {
|
|
@@ -5309,7 +5380,7 @@ Keep it concise but INCLUDE THE ACTUAL DATA.`;
|
|
|
5309
5380
|
execute: async ({ path, startLine, endLine }) => {
|
|
5310
5381
|
try {
|
|
5311
5382
|
const absolutePath = isAbsolute5(path) ? path : resolve9(workingDirectory, path);
|
|
5312
|
-
if (!
|
|
5383
|
+
if (!existsSync13(absolutePath)) {
|
|
5313
5384
|
return {
|
|
5314
5385
|
success: false,
|
|
5315
5386
|
error: `File not found: ${path}`
|
|
@@ -5353,7 +5424,7 @@ Keep it concise but INCLUDE THE ACTUAL DATA.`;
|
|
|
5353
5424
|
execute: async ({ path, recursive, maxDepth }) => {
|
|
5354
5425
|
try {
|
|
5355
5426
|
const absolutePath = isAbsolute5(path) ? path : resolve9(workingDirectory, path);
|
|
5356
|
-
if (!
|
|
5427
|
+
if (!existsSync13(absolutePath)) {
|
|
5357
5428
|
return {
|
|
5358
5429
|
success: false,
|
|
5359
5430
|
error: `Directory not found: ${path}`
|
|
@@ -5721,7 +5792,7 @@ function createTaskFailedTool(options) {
|
|
|
5721
5792
|
import { tool as tool12 } from "ai";
|
|
5722
5793
|
import { z as z13 } from "zod";
|
|
5723
5794
|
import { readFile as readFile9, stat as stat4 } from "fs/promises";
|
|
5724
|
-
import { join as
|
|
5795
|
+
import { join as join6, basename as basename4, extname as extname7 } from "path";
|
|
5725
5796
|
var MIME_TYPES = {
|
|
5726
5797
|
".txt": "text/plain",
|
|
5727
5798
|
".md": "text/markdown",
|
|
@@ -5763,7 +5834,7 @@ function createUploadFileTool(options) {
|
|
|
5763
5834
|
error: "File upload is not available \u2014 remote server with GCS is not configured."
|
|
5764
5835
|
};
|
|
5765
5836
|
}
|
|
5766
|
-
const fullPath = input.path.startsWith("/") ? input.path :
|
|
5837
|
+
const fullPath = input.path.startsWith("/") ? input.path : join6(options.workingDirectory, input.path);
|
|
5767
5838
|
try {
|
|
5768
5839
|
await stat4(fullPath);
|
|
5769
5840
|
} catch {
|
|
@@ -7328,11 +7399,11 @@ ${taskAddendum}`;
|
|
|
7328
7399
|
const { isRemoteConfigured: isRemoteConfigured2, storageQueries: storageQueries2 } = await Promise.resolve().then(() => (init_remote(), remote_exports));
|
|
7329
7400
|
if (!isRemoteConfigured2()) return [];
|
|
7330
7401
|
const { readFile: readFile11 } = await import("fs/promises");
|
|
7331
|
-
const { join:
|
|
7402
|
+
const { join: join12, basename: basename6 } = await import("path");
|
|
7332
7403
|
const urls = [];
|
|
7333
7404
|
for (const filePath of filePaths) {
|
|
7334
7405
|
try {
|
|
7335
|
-
const fullPath = filePath.startsWith("/") ? filePath :
|
|
7406
|
+
const fullPath = filePath.startsWith("/") ? filePath : join12(this.session.workingDirectory, filePath);
|
|
7336
7407
|
const fileName = basename6(fullPath);
|
|
7337
7408
|
const ext = fileName.split(".").pop()?.toLowerCase() || "";
|
|
7338
7409
|
const mimeMap = {
|
|
@@ -7962,12 +8033,12 @@ sessions.get("/:id/diff/:filePath", async (c) => {
|
|
|
7962
8033
|
});
|
|
7963
8034
|
function getAttachmentsDir(sessionId) {
|
|
7964
8035
|
const appDataDir = getAppDataDirectory();
|
|
7965
|
-
return
|
|
8036
|
+
return join8(appDataDir, "attachments", sessionId);
|
|
7966
8037
|
}
|
|
7967
8038
|
function ensureAttachmentsDir(sessionId) {
|
|
7968
8039
|
const dir = getAttachmentsDir(sessionId);
|
|
7969
|
-
if (!
|
|
7970
|
-
|
|
8040
|
+
if (!existsSync14(dir)) {
|
|
8041
|
+
mkdirSync4(dir, { recursive: true });
|
|
7971
8042
|
}
|
|
7972
8043
|
return dir;
|
|
7973
8044
|
}
|
|
@@ -7978,12 +8049,12 @@ sessions.get("/:id/attachments", async (c) => {
|
|
|
7978
8049
|
return c.json({ error: "Session not found" }, 404);
|
|
7979
8050
|
}
|
|
7980
8051
|
const dir = getAttachmentsDir(sessionId);
|
|
7981
|
-
if (!
|
|
8052
|
+
if (!existsSync14(dir)) {
|
|
7982
8053
|
return c.json({ sessionId, attachments: [], count: 0 });
|
|
7983
8054
|
}
|
|
7984
8055
|
const files = readdirSync(dir);
|
|
7985
8056
|
const attachments = files.map((filename) => {
|
|
7986
|
-
const filePath =
|
|
8057
|
+
const filePath = join8(dir, filename);
|
|
7987
8058
|
const stats = statSync2(filePath);
|
|
7988
8059
|
return {
|
|
7989
8060
|
id: filename.split("_")[0],
|
|
@@ -8018,9 +8089,9 @@ sessions.post("/:id/attachments", async (c) => {
|
|
|
8018
8089
|
const id = nanoid5(10);
|
|
8019
8090
|
const ext = extname8(file.name) || "";
|
|
8020
8091
|
const safeFilename = `${id}_${basename5(file.name).replace(/[^a-zA-Z0-9._-]/g, "_")}`;
|
|
8021
|
-
const filePath =
|
|
8092
|
+
const filePath = join8(dir, safeFilename);
|
|
8022
8093
|
const arrayBuffer = await file.arrayBuffer();
|
|
8023
|
-
|
|
8094
|
+
writeFileSync3(filePath, Buffer.from(arrayBuffer));
|
|
8024
8095
|
return c.json({
|
|
8025
8096
|
id,
|
|
8026
8097
|
filename: file.name,
|
|
@@ -8044,13 +8115,13 @@ sessions.post("/:id/attachments", async (c) => {
|
|
|
8044
8115
|
const id = nanoid5(10);
|
|
8045
8116
|
const ext = extname8(body.filename) || "";
|
|
8046
8117
|
const safeFilename = `${id}_${basename5(body.filename).replace(/[^a-zA-Z0-9._-]/g, "_")}`;
|
|
8047
|
-
const filePath =
|
|
8118
|
+
const filePath = join8(dir, safeFilename);
|
|
8048
8119
|
let base64Data = body.data;
|
|
8049
8120
|
if (base64Data.includes(",")) {
|
|
8050
8121
|
base64Data = base64Data.split(",")[1];
|
|
8051
8122
|
}
|
|
8052
8123
|
const buffer = Buffer.from(base64Data, "base64");
|
|
8053
|
-
|
|
8124
|
+
writeFileSync3(filePath, buffer);
|
|
8054
8125
|
return c.json({
|
|
8055
8126
|
id,
|
|
8056
8127
|
filename: body.filename,
|
|
@@ -8073,7 +8144,7 @@ sessions.delete("/:id/attachments/:attachmentId", async (c) => {
|
|
|
8073
8144
|
return c.json({ error: "Session not found" }, 404);
|
|
8074
8145
|
}
|
|
8075
8146
|
const dir = getAttachmentsDir(sessionId);
|
|
8076
|
-
if (!
|
|
8147
|
+
if (!existsSync14(dir)) {
|
|
8077
8148
|
return c.json({ error: "Attachment not found" }, 404);
|
|
8078
8149
|
}
|
|
8079
8150
|
const files = readdirSync(dir);
|
|
@@ -8081,7 +8152,7 @@ sessions.delete("/:id/attachments/:attachmentId", async (c) => {
|
|
|
8081
8152
|
if (!file) {
|
|
8082
8153
|
return c.json({ error: "Attachment not found" }, 404);
|
|
8083
8154
|
}
|
|
8084
|
-
const filePath =
|
|
8155
|
+
const filePath = join8(dir, file);
|
|
8085
8156
|
unlinkSync(filePath);
|
|
8086
8157
|
return c.json({ success: true, id: attachmentId });
|
|
8087
8158
|
});
|
|
@@ -8164,7 +8235,7 @@ async function listWorkspaceFiles(baseDir, currentDir, query, limit, results = [
|
|
|
8164
8235
|
const entries = await readdir6(currentDir, { withFileTypes: true });
|
|
8165
8236
|
for (const entry of entries) {
|
|
8166
8237
|
if (results.length >= limit * 2) break;
|
|
8167
|
-
const fullPath =
|
|
8238
|
+
const fullPath = join8(currentDir, entry.name);
|
|
8168
8239
|
const relativePath = relative9(baseDir, fullPath);
|
|
8169
8240
|
if (entry.isDirectory() && IGNORED_DIRECTORIES.has(entry.name)) {
|
|
8170
8241
|
continue;
|
|
@@ -8212,7 +8283,7 @@ sessions.get(
|
|
|
8212
8283
|
return c.json({ error: "Session not found" }, 404);
|
|
8213
8284
|
}
|
|
8214
8285
|
const workingDirectory = session.workingDirectory;
|
|
8215
|
-
if (!
|
|
8286
|
+
if (!existsSync14(workingDirectory)) {
|
|
8216
8287
|
return c.json({
|
|
8217
8288
|
sessionId,
|
|
8218
8289
|
workingDirectory,
|
|
@@ -8323,8 +8394,8 @@ init_db();
|
|
|
8323
8394
|
import { Hono as Hono2 } from "hono";
|
|
8324
8395
|
import { zValidator as zValidator2 } from "@hono/zod-validator";
|
|
8325
8396
|
import { z as z16 } from "zod";
|
|
8326
|
-
import { existsSync as
|
|
8327
|
-
import { join as
|
|
8397
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
8398
|
+
import { join as join9 } from "path";
|
|
8328
8399
|
init_config();
|
|
8329
8400
|
|
|
8330
8401
|
// src/server/resumable-stream.ts
|
|
@@ -8530,12 +8601,12 @@ var rejectSchema = z16.object({
|
|
|
8530
8601
|
var streamAbortControllers = /* @__PURE__ */ new Map();
|
|
8531
8602
|
function getAttachmentsDirectory(sessionId) {
|
|
8532
8603
|
const appDataDir = getAppDataDirectory();
|
|
8533
|
-
return
|
|
8604
|
+
return join9(appDataDir, "attachments", sessionId);
|
|
8534
8605
|
}
|
|
8535
|
-
function saveAttachmentToDisk(sessionId, attachment, index) {
|
|
8606
|
+
async function saveAttachmentToDisk(sessionId, attachment, index) {
|
|
8536
8607
|
const attachmentsDir = getAttachmentsDirectory(sessionId);
|
|
8537
|
-
if (!
|
|
8538
|
-
|
|
8608
|
+
if (!existsSync15(attachmentsDir)) {
|
|
8609
|
+
mkdirSync5(attachmentsDir, { recursive: true });
|
|
8539
8610
|
}
|
|
8540
8611
|
let filename = attachment.filename;
|
|
8541
8612
|
if (!filename) {
|
|
@@ -8546,9 +8617,14 @@ function saveAttachmentToDisk(sessionId, attachment, index) {
|
|
|
8546
8617
|
if (base64Data.includes(",")) {
|
|
8547
8618
|
base64Data = base64Data.split(",")[1];
|
|
8548
8619
|
}
|
|
8549
|
-
|
|
8550
|
-
|
|
8551
|
-
|
|
8620
|
+
let buffer = Buffer.from(base64Data, "base64");
|
|
8621
|
+
if (attachment.type === "image") {
|
|
8622
|
+
buffer = await resizeImageIfNeeded(buffer, attachment.mediaType);
|
|
8623
|
+
const prefix = attachment.data.includes(",") ? attachment.data.split(",")[0] + "," : "";
|
|
8624
|
+
attachment.data = prefix + buffer.toString("base64");
|
|
8625
|
+
}
|
|
8626
|
+
const filePath = join9(attachmentsDir, filename);
|
|
8627
|
+
writeFileSync4(filePath, buffer);
|
|
8552
8628
|
return filePath;
|
|
8553
8629
|
}
|
|
8554
8630
|
function getExtensionFromMediaType(mediaType, type) {
|
|
@@ -8908,7 +8984,7 @@ agents.post(
|
|
|
8908
8984
|
for (let i = 0; i < streamAttachments.length; i++) {
|
|
8909
8985
|
const attachment = streamAttachments[i];
|
|
8910
8986
|
try {
|
|
8911
|
-
const savedPath = saveAttachmentToDisk(id, attachment, i);
|
|
8987
|
+
const savedPath = await saveAttachmentToDisk(id, attachment, i);
|
|
8912
8988
|
attachment.savedPath = savedPath;
|
|
8913
8989
|
} catch (err) {
|
|
8914
8990
|
console.error(`Failed to save attachment ${i}:`, err);
|
|
@@ -9482,26 +9558,26 @@ init_config();
|
|
|
9482
9558
|
import { Hono as Hono3 } from "hono";
|
|
9483
9559
|
import { zValidator as zValidator3 } from "@hono/zod-validator";
|
|
9484
9560
|
import { z as z17 } from "zod";
|
|
9485
|
-
import { readFileSync as
|
|
9561
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
9486
9562
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
9487
|
-
import { dirname as dirname6, join as
|
|
9563
|
+
import { dirname as dirname6, join as join10 } from "path";
|
|
9488
9564
|
var __filename = fileURLToPath3(import.meta.url);
|
|
9489
9565
|
var __dirname = dirname6(__filename);
|
|
9490
9566
|
var possiblePaths = [
|
|
9491
|
-
|
|
9567
|
+
join10(__dirname, "../package.json"),
|
|
9492
9568
|
// From dist/server -> dist/../package.json
|
|
9493
|
-
|
|
9569
|
+
join10(__dirname, "../../package.json"),
|
|
9494
9570
|
// From dist/server (if nested differently)
|
|
9495
|
-
|
|
9571
|
+
join10(__dirname, "../../../package.json"),
|
|
9496
9572
|
// From src/server/routes (development)
|
|
9497
|
-
|
|
9573
|
+
join10(process.cwd(), "package.json")
|
|
9498
9574
|
// From current working directory
|
|
9499
9575
|
];
|
|
9500
9576
|
var currentVersion = "0.0.0";
|
|
9501
9577
|
var packageName = "sparkecoder";
|
|
9502
9578
|
for (const packageJsonPath of possiblePaths) {
|
|
9503
9579
|
try {
|
|
9504
|
-
const packageJson = JSON.parse(
|
|
9580
|
+
const packageJson = JSON.parse(readFileSync6(packageJsonPath, "utf-8"));
|
|
9505
9581
|
if (packageJson.name === "sparkecoder") {
|
|
9506
9582
|
currentVersion = packageJson.version || "0.0.0";
|
|
9507
9583
|
packageName = packageJson.name || "sparkecoder";
|
|
@@ -10217,11 +10293,11 @@ function getWebDirectory() {
|
|
|
10217
10293
|
try {
|
|
10218
10294
|
const currentDir = dirname7(fileURLToPath4(import.meta.url));
|
|
10219
10295
|
const webDir = resolve10(currentDir, "..", "web");
|
|
10220
|
-
if (
|
|
10296
|
+
if (existsSync16(webDir) && existsSync16(join11(webDir, "package.json"))) {
|
|
10221
10297
|
return webDir;
|
|
10222
10298
|
}
|
|
10223
10299
|
const altWebDir = resolve10(currentDir, "..", "..", "web");
|
|
10224
|
-
if (
|
|
10300
|
+
if (existsSync16(altWebDir) && existsSync16(join11(altWebDir, "package.json"))) {
|
|
10225
10301
|
return altWebDir;
|
|
10226
10302
|
}
|
|
10227
10303
|
return null;
|
|
@@ -10279,23 +10355,23 @@ async function findWebPort(preferredPort) {
|
|
|
10279
10355
|
return { port: preferredPort, alreadyRunning: false };
|
|
10280
10356
|
}
|
|
10281
10357
|
function hasProductionBuild(webDir) {
|
|
10282
|
-
const buildIdPath =
|
|
10283
|
-
return
|
|
10358
|
+
const buildIdPath = join11(webDir, ".next", "BUILD_ID");
|
|
10359
|
+
return existsSync16(buildIdPath);
|
|
10284
10360
|
}
|
|
10285
10361
|
function hasSourceFiles(webDir) {
|
|
10286
|
-
const appDir =
|
|
10287
|
-
const pagesDir =
|
|
10288
|
-
const rootAppDir =
|
|
10289
|
-
const rootPagesDir =
|
|
10290
|
-
return
|
|
10362
|
+
const appDir = join11(webDir, "src", "app");
|
|
10363
|
+
const pagesDir = join11(webDir, "src", "pages");
|
|
10364
|
+
const rootAppDir = join11(webDir, "app");
|
|
10365
|
+
const rootPagesDir = join11(webDir, "pages");
|
|
10366
|
+
return existsSync16(appDir) || existsSync16(pagesDir) || existsSync16(rootAppDir) || existsSync16(rootPagesDir);
|
|
10291
10367
|
}
|
|
10292
10368
|
function getStandaloneServerPath(webDir) {
|
|
10293
10369
|
const possiblePaths2 = [
|
|
10294
|
-
|
|
10295
|
-
|
|
10370
|
+
join11(webDir, ".next", "standalone", "server.js"),
|
|
10371
|
+
join11(webDir, ".next", "standalone", "web", "server.js")
|
|
10296
10372
|
];
|
|
10297
10373
|
for (const serverPath of possiblePaths2) {
|
|
10298
|
-
if (
|
|
10374
|
+
if (existsSync16(serverPath)) {
|
|
10299
10375
|
return serverPath;
|
|
10300
10376
|
}
|
|
10301
10377
|
}
|
|
@@ -10335,15 +10411,15 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false, pu
|
|
|
10335
10411
|
if (!quiet) console.log(` \u2713 Web UI already running at http://localhost:${actualPort}`);
|
|
10336
10412
|
return { process: null, port: actualPort };
|
|
10337
10413
|
}
|
|
10338
|
-
const usePnpm =
|
|
10339
|
-
const useNpm = !usePnpm &&
|
|
10414
|
+
const usePnpm = existsSync16(join11(webDir, "pnpm-lock.yaml"));
|
|
10415
|
+
const useNpm = !usePnpm && existsSync16(join11(webDir, "package-lock.json"));
|
|
10340
10416
|
const pkgManager = usePnpm ? "pnpm" : useNpm ? "npm" : "npx";
|
|
10341
10417
|
const { NODE_OPTIONS, TSX_TSCONFIG_PATH, ...cleanEnv } = process.env;
|
|
10342
10418
|
const apiUrl = publicUrl || `http://127.0.0.1:${apiPort}`;
|
|
10343
10419
|
const runtimeConfig = { apiBaseUrl: apiUrl };
|
|
10344
|
-
const runtimeConfigPath =
|
|
10420
|
+
const runtimeConfigPath = join11(webDir, "runtime-config.json");
|
|
10345
10421
|
try {
|
|
10346
|
-
|
|
10422
|
+
writeFileSync5(runtimeConfigPath, JSON.stringify(runtimeConfig, null, 2));
|
|
10347
10423
|
if (!quiet) console.log(` \u{1F4DD} Runtime config written to ${runtimeConfigPath}`);
|
|
10348
10424
|
} catch (err) {
|
|
10349
10425
|
if (!quiet) console.warn(` \u26A0 Could not write runtime config: ${err}`);
|
|
@@ -10534,8 +10610,8 @@ async function startServer(options = {}) {
|
|
|
10534
10610
|
if (options.workingDirectory) {
|
|
10535
10611
|
config.resolvedWorkingDirectory = options.workingDirectory;
|
|
10536
10612
|
}
|
|
10537
|
-
if (!
|
|
10538
|
-
|
|
10613
|
+
if (!existsSync16(config.resolvedWorkingDirectory)) {
|
|
10614
|
+
mkdirSync6(config.resolvedWorkingDirectory, { recursive: true });
|
|
10539
10615
|
if (!options.quiet) console.log(`\u{1F4C1} Created agent workspace: ${config.resolvedWorkingDirectory}`);
|
|
10540
10616
|
}
|
|
10541
10617
|
if (!config.resolvedRemoteServer.url) {
|