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/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
|
}
|
|
@@ -2932,7 +2932,77 @@ import { tool as tool2 } from "ai";
|
|
|
2932
2932
|
import { z as z3 } from "zod";
|
|
2933
2933
|
import { readFile as readFile2, stat } from "fs/promises";
|
|
2934
2934
|
import { resolve as resolve2, relative, isAbsolute, extname } from "path";
|
|
2935
|
-
import { existsSync as
|
|
2935
|
+
import { existsSync as existsSync4 } from "fs";
|
|
2936
|
+
|
|
2937
|
+
// src/utils/resize-image.ts
|
|
2938
|
+
init_config();
|
|
2939
|
+
import sharp from "sharp";
|
|
2940
|
+
import { createHash } from "crypto";
|
|
2941
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
2942
|
+
import { join as join3 } from "path";
|
|
2943
|
+
var MAX_LONG_EDGE = 1568;
|
|
2944
|
+
var MAX_FILE_BYTES = 5 * 1024 * 1024;
|
|
2945
|
+
var CACHE_DIR_NAME = "image-cache";
|
|
2946
|
+
function getCacheDir() {
|
|
2947
|
+
const dir = join3(getAppDataDirectory(), CACHE_DIR_NAME);
|
|
2948
|
+
if (!existsSync3(dir)) mkdirSync3(dir, { recursive: true });
|
|
2949
|
+
return dir;
|
|
2950
|
+
}
|
|
2951
|
+
function cacheKey(buffer) {
|
|
2952
|
+
return createHash("sha256").update(buffer).digest("hex");
|
|
2953
|
+
}
|
|
2954
|
+
async function resizeImageIfNeeded(buffer, mediaType) {
|
|
2955
|
+
let metadata;
|
|
2956
|
+
try {
|
|
2957
|
+
metadata = await sharp(buffer).metadata();
|
|
2958
|
+
} catch {
|
|
2959
|
+
return buffer;
|
|
2960
|
+
}
|
|
2961
|
+
const { width, height } = metadata;
|
|
2962
|
+
if (!width || !height) return buffer;
|
|
2963
|
+
const longEdge = Math.max(width, height);
|
|
2964
|
+
const needsResize = longEdge > MAX_LONG_EDGE;
|
|
2965
|
+
const needsShrink = buffer.length > MAX_FILE_BYTES;
|
|
2966
|
+
if (!needsResize && !needsShrink) return buffer;
|
|
2967
|
+
const key = cacheKey(buffer);
|
|
2968
|
+
const cacheDir = getCacheDir();
|
|
2969
|
+
const isPng = mediaType?.includes("png");
|
|
2970
|
+
const ext = isPng ? ".png" : ".jpg";
|
|
2971
|
+
const cachePath = join3(cacheDir, key + ext);
|
|
2972
|
+
if (existsSync3(cachePath)) {
|
|
2973
|
+
console.log(`[image-resize] Cache hit for ${width}x${height} image`);
|
|
2974
|
+
return readFileSync2(cachePath);
|
|
2975
|
+
}
|
|
2976
|
+
let pipeline = sharp(buffer);
|
|
2977
|
+
if (needsResize) {
|
|
2978
|
+
pipeline = pipeline.resize(MAX_LONG_EDGE, MAX_LONG_EDGE, {
|
|
2979
|
+
fit: "inside",
|
|
2980
|
+
withoutEnlargement: true
|
|
2981
|
+
});
|
|
2982
|
+
}
|
|
2983
|
+
let result;
|
|
2984
|
+
if (isPng && (needsShrink || buffer.length > 2 * 1024 * 1024)) {
|
|
2985
|
+
result = await pipeline.jpeg({ quality: 85 }).toBuffer();
|
|
2986
|
+
} else if (isPng) {
|
|
2987
|
+
result = await pipeline.png().toBuffer();
|
|
2988
|
+
} else {
|
|
2989
|
+
result = await pipeline.jpeg({ quality: 85 }).toBuffer();
|
|
2990
|
+
}
|
|
2991
|
+
if (result.length > MAX_FILE_BYTES) {
|
|
2992
|
+
for (const quality of [70, 50, 30]) {
|
|
2993
|
+
result = await sharp(buffer).resize(MAX_LONG_EDGE, MAX_LONG_EDGE, { fit: "inside", withoutEnlargement: true }).jpeg({ quality }).toBuffer();
|
|
2994
|
+
if (result.length <= MAX_FILE_BYTES) break;
|
|
2995
|
+
}
|
|
2996
|
+
}
|
|
2997
|
+
writeFileSync2(cachePath, result);
|
|
2998
|
+
const resultMeta = await sharp(result).metadata();
|
|
2999
|
+
console.log(
|
|
3000
|
+
`[image-resize] ${width}x${height} -> ${resultMeta.width}x${resultMeta.height} (${(buffer.length / 1024).toFixed(0)}KB -> ${(result.length / 1024).toFixed(0)}KB)`
|
|
3001
|
+
);
|
|
3002
|
+
return result;
|
|
3003
|
+
}
|
|
3004
|
+
|
|
3005
|
+
// src/tools/read-file.ts
|
|
2936
3006
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
2937
3007
|
var MAX_IMAGE_SIZE = 20 * 1024 * 1024;
|
|
2938
3008
|
var MAX_OUTPUT_CHARS3 = 5e4;
|
|
@@ -2972,7 +3042,7 @@ Use this to understand existing code, check file contents, view screenshots, or
|
|
|
2972
3042
|
content: null
|
|
2973
3043
|
};
|
|
2974
3044
|
}
|
|
2975
|
-
if (!
|
|
3045
|
+
if (!existsSync4(absolutePath)) {
|
|
2976
3046
|
return {
|
|
2977
3047
|
success: false,
|
|
2978
3048
|
error: `File not found: ${filePath}`,
|
|
@@ -2995,9 +3065,10 @@ Use this to understand existing code, check file contents, view screenshots, or
|
|
|
2995
3065
|
content: null
|
|
2996
3066
|
};
|
|
2997
3067
|
}
|
|
2998
|
-
const
|
|
2999
|
-
const base64 = buffer.toString("base64");
|
|
3068
|
+
const rawBuffer = await readFile2(absolutePath);
|
|
3000
3069
|
const mediaType = getImageMediaType(absolutePath);
|
|
3070
|
+
const buffer = await resizeImageIfNeeded(rawBuffer, mediaType);
|
|
3071
|
+
const base64 = buffer.toString("base64");
|
|
3001
3072
|
return {
|
|
3002
3073
|
success: true,
|
|
3003
3074
|
path: absolutePath,
|
|
@@ -3076,12 +3147,12 @@ import { tool as tool3 } from "ai";
|
|
|
3076
3147
|
import { z as z4 } from "zod";
|
|
3077
3148
|
import { readFile as readFile5, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
3078
3149
|
import { resolve as resolve5, relative as relative3, isAbsolute as isAbsolute2, dirname as dirname5 } from "path";
|
|
3079
|
-
import { existsSync as
|
|
3150
|
+
import { existsSync as existsSync8 } from "fs";
|
|
3080
3151
|
|
|
3081
3152
|
// src/checkpoints/index.ts
|
|
3082
3153
|
init_db();
|
|
3083
3154
|
import { readFile as readFile3, writeFile as writeFile2, unlink, mkdir as mkdir2 } from "fs/promises";
|
|
3084
|
-
import { existsSync as
|
|
3155
|
+
import { existsSync as existsSync5 } from "fs";
|
|
3085
3156
|
import { resolve as resolve3, relative as relative2, dirname as dirname2 } from "path";
|
|
3086
3157
|
import { exec as exec3 } from "child_process";
|
|
3087
3158
|
import { promisify as promisify3 } from "util";
|
|
@@ -3134,7 +3205,7 @@ async function backupFile(sessionId, workingDirectory, filePath) {
|
|
|
3134
3205
|
}
|
|
3135
3206
|
let originalContent = null;
|
|
3136
3207
|
let existed = false;
|
|
3137
|
-
if (
|
|
3208
|
+
if (existsSync5(absolutePath)) {
|
|
3138
3209
|
try {
|
|
3139
3210
|
originalContent = await readFile3(absolutePath, "utf-8");
|
|
3140
3211
|
existed = true;
|
|
@@ -3189,13 +3260,13 @@ async function revertToCheckpoint(sessionId, checkpointId) {
|
|
|
3189
3260
|
try {
|
|
3190
3261
|
if (backup.existed && backup.originalContent !== null) {
|
|
3191
3262
|
const dir = dirname2(absolutePath);
|
|
3192
|
-
if (!
|
|
3263
|
+
if (!existsSync5(dir)) {
|
|
3193
3264
|
await mkdir2(dir, { recursive: true });
|
|
3194
3265
|
}
|
|
3195
3266
|
await writeFile2(absolutePath, backup.originalContent, "utf-8");
|
|
3196
3267
|
filesRestored++;
|
|
3197
3268
|
} else if (!backup.existed) {
|
|
3198
|
-
if (
|
|
3269
|
+
if (existsSync5(absolutePath)) {
|
|
3199
3270
|
await unlink(absolutePath);
|
|
3200
3271
|
filesDeleted++;
|
|
3201
3272
|
}
|
|
@@ -3238,7 +3309,7 @@ async function getSessionDiff(sessionId) {
|
|
|
3238
3309
|
const absolutePath = resolve3(workingDirectory, filePath);
|
|
3239
3310
|
let currentContent = null;
|
|
3240
3311
|
let currentExists = false;
|
|
3241
|
-
if (
|
|
3312
|
+
if (existsSync5(absolutePath)) {
|
|
3242
3313
|
try {
|
|
3243
3314
|
currentContent = await readFile3(absolutePath, "utf-8");
|
|
3244
3315
|
currentExists = true;
|
|
@@ -3271,14 +3342,14 @@ import { extname as extname3, dirname as dirname4 } from "path";
|
|
|
3271
3342
|
|
|
3272
3343
|
// src/lsp/servers.ts
|
|
3273
3344
|
import { spawn } from "child_process";
|
|
3274
|
-
import { existsSync as
|
|
3345
|
+
import { existsSync as existsSync6 } from "fs";
|
|
3275
3346
|
import { resolve as resolve4, dirname as dirname3 } from "path";
|
|
3276
3347
|
function findNearestRoot(startDir, markers) {
|
|
3277
3348
|
let dir = startDir;
|
|
3278
3349
|
const root = "/";
|
|
3279
3350
|
while (dir !== root) {
|
|
3280
3351
|
for (const marker of markers) {
|
|
3281
|
-
if (
|
|
3352
|
+
if (existsSync6(resolve4(dir, marker))) {
|
|
3282
3353
|
return dir;
|
|
3283
3354
|
}
|
|
3284
3355
|
}
|
|
@@ -3389,7 +3460,7 @@ import {
|
|
|
3389
3460
|
} from "vscode-jsonrpc/node.js";
|
|
3390
3461
|
import { pathToFileURL, fileURLToPath } from "url";
|
|
3391
3462
|
import { readFile as readFile4 } from "fs/promises";
|
|
3392
|
-
import { existsSync as
|
|
3463
|
+
import { existsSync as existsSync7 } from "fs";
|
|
3393
3464
|
import { extname as extname2, normalize } from "path";
|
|
3394
3465
|
function getLanguageId(filePath) {
|
|
3395
3466
|
const ext = extname2(filePath).toLowerCase();
|
|
@@ -3515,7 +3586,7 @@ async function createClient(serverId, handle, root) {
|
|
|
3515
3586
|
diagnostics,
|
|
3516
3587
|
async notifyOpen(filePath) {
|
|
3517
3588
|
const normalized = normalizePath(filePath);
|
|
3518
|
-
if (!
|
|
3589
|
+
if (!existsSync7(normalized)) {
|
|
3519
3590
|
return;
|
|
3520
3591
|
}
|
|
3521
3592
|
try {
|
|
@@ -3546,7 +3617,7 @@ async function createClient(serverId, handle, root) {
|
|
|
3546
3617
|
},
|
|
3547
3618
|
async notifyChange(filePath) {
|
|
3548
3619
|
const normalized = normalizePath(filePath);
|
|
3549
|
-
if (!
|
|
3620
|
+
if (!existsSync7(normalized)) {
|
|
3550
3621
|
return;
|
|
3551
3622
|
}
|
|
3552
3623
|
try {
|
|
@@ -3922,7 +3993,7 @@ Working directory: ${options.workingDirectory}`,
|
|
|
3922
3993
|
error: 'Content is required for "full" mode'
|
|
3923
3994
|
};
|
|
3924
3995
|
}
|
|
3925
|
-
const existed =
|
|
3996
|
+
const existed = existsSync8(absolutePath);
|
|
3926
3997
|
const action = existed ? "replaced" : "created";
|
|
3927
3998
|
console.log("[WRITE-FILE] onProgress callback exists:", !!options.onProgress);
|
|
3928
3999
|
console.log("[WRITE-FILE] Emitting started event for:", relativePath);
|
|
@@ -3969,7 +4040,7 @@ Working directory: ${options.workingDirectory}`,
|
|
|
3969
4040
|
}
|
|
3970
4041
|
await backupFile(options.sessionId, options.workingDirectory, absolutePath);
|
|
3971
4042
|
const dir = dirname5(absolutePath);
|
|
3972
|
-
if (!
|
|
4043
|
+
if (!existsSync8(dir)) {
|
|
3973
4044
|
await mkdir3(dir, { recursive: true });
|
|
3974
4045
|
}
|
|
3975
4046
|
await writeFile3(absolutePath, content, "utf-8");
|
|
@@ -4003,7 +4074,7 @@ Working directory: ${options.workingDirectory}`,
|
|
|
4003
4074
|
error: 'Both old_string and new_string are required for "str_replace" mode'
|
|
4004
4075
|
};
|
|
4005
4076
|
}
|
|
4006
|
-
if (!
|
|
4077
|
+
if (!existsSync8(absolutePath)) {
|
|
4007
4078
|
return {
|
|
4008
4079
|
success: false,
|
|
4009
4080
|
error: `File not found: ${path}. Use "full" mode to create new files.`
|
|
@@ -4301,7 +4372,7 @@ Once loaded, a skill's content will be available in the conversation context.`,
|
|
|
4301
4372
|
import { tool as tool6 } from "ai";
|
|
4302
4373
|
import { z as z7 } from "zod";
|
|
4303
4374
|
import { resolve as resolve7, relative as relative5, isAbsolute as isAbsolute3, extname as extname5 } from "path";
|
|
4304
|
-
import { existsSync as
|
|
4375
|
+
import { existsSync as existsSync10 } from "fs";
|
|
4305
4376
|
import { readdir as readdir2, stat as stat2 } from "fs/promises";
|
|
4306
4377
|
var linterInputSchema = z7.object({
|
|
4307
4378
|
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."),
|
|
@@ -4369,7 +4440,7 @@ Working directory: ${options.workingDirectory}`,
|
|
|
4369
4440
|
const filesToCheck = [];
|
|
4370
4441
|
for (const path of paths) {
|
|
4371
4442
|
const absolutePath = isAbsolute3(path) ? path : resolve7(options.workingDirectory, path);
|
|
4372
|
-
if (!
|
|
4443
|
+
if (!existsSync10(absolutePath)) {
|
|
4373
4444
|
continue;
|
|
4374
4445
|
}
|
|
4375
4446
|
const stats = await stat2(absolutePath);
|
|
@@ -4683,7 +4754,7 @@ import { exec as exec4 } from "child_process";
|
|
|
4683
4754
|
import { promisify as promisify4 } from "util";
|
|
4684
4755
|
import { readFile as readFile8, stat as stat3, readdir as readdir4 } from "fs/promises";
|
|
4685
4756
|
import { resolve as resolve9, relative as relative8, isAbsolute as isAbsolute5 } from "path";
|
|
4686
|
-
import { existsSync as
|
|
4757
|
+
import { existsSync as existsSync13 } from "fs";
|
|
4687
4758
|
init_semantic();
|
|
4688
4759
|
|
|
4689
4760
|
// src/tools/code-graph.ts
|
|
@@ -4691,7 +4762,7 @@ import { tool as tool7 } from "ai";
|
|
|
4691
4762
|
import { z as z8 } from "zod";
|
|
4692
4763
|
import { resolve as resolve8, relative as relative7, isAbsolute as isAbsolute4, basename as basename3 } from "path";
|
|
4693
4764
|
import { readFile as readFile7, readdir as readdir3 } from "fs/promises";
|
|
4694
|
-
import { existsSync as
|
|
4765
|
+
import { existsSync as existsSync11 } from "fs";
|
|
4695
4766
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
4696
4767
|
import { execFileSync } from "child_process";
|
|
4697
4768
|
var codeGraphInputSchema = z8.object({
|
|
@@ -4877,7 +4948,7 @@ Working directory: ${options.workingDirectory}`,
|
|
|
4877
4948
|
let defSymbol = null;
|
|
4878
4949
|
if (filePath) {
|
|
4879
4950
|
const absPath = isAbsolute4(filePath) ? filePath : resolve8(options.workingDirectory, filePath);
|
|
4880
|
-
if (!
|
|
4951
|
+
if (!existsSync11(absPath)) {
|
|
4881
4952
|
return { success: false, error: `File not found: ${filePath}` };
|
|
4882
4953
|
}
|
|
4883
4954
|
if (!isSupported(absPath)) {
|
|
@@ -5304,7 +5375,7 @@ Keep it concise but INCLUDE THE ACTUAL DATA.`;
|
|
|
5304
5375
|
execute: async ({ path, startLine, endLine }) => {
|
|
5305
5376
|
try {
|
|
5306
5377
|
const absolutePath = isAbsolute5(path) ? path : resolve9(workingDirectory, path);
|
|
5307
|
-
if (!
|
|
5378
|
+
if (!existsSync13(absolutePath)) {
|
|
5308
5379
|
return {
|
|
5309
5380
|
success: false,
|
|
5310
5381
|
error: `File not found: ${path}`
|
|
@@ -5348,7 +5419,7 @@ Keep it concise but INCLUDE THE ACTUAL DATA.`;
|
|
|
5348
5419
|
execute: async ({ path, recursive, maxDepth }) => {
|
|
5349
5420
|
try {
|
|
5350
5421
|
const absolutePath = isAbsolute5(path) ? path : resolve9(workingDirectory, path);
|
|
5351
|
-
if (!
|
|
5422
|
+
if (!existsSync13(absolutePath)) {
|
|
5352
5423
|
return {
|
|
5353
5424
|
success: false,
|
|
5354
5425
|
error: `Directory not found: ${path}`
|
|
@@ -5716,7 +5787,7 @@ function createTaskFailedTool(options) {
|
|
|
5716
5787
|
import { tool as tool12 } from "ai";
|
|
5717
5788
|
import { z as z13 } from "zod";
|
|
5718
5789
|
import { readFile as readFile9, stat as stat4 } from "fs/promises";
|
|
5719
|
-
import { join as
|
|
5790
|
+
import { join as join6, basename as basename4, extname as extname7 } from "path";
|
|
5720
5791
|
var MIME_TYPES = {
|
|
5721
5792
|
".txt": "text/plain",
|
|
5722
5793
|
".md": "text/markdown",
|
|
@@ -5758,7 +5829,7 @@ function createUploadFileTool(options) {
|
|
|
5758
5829
|
error: "File upload is not available \u2014 remote server with GCS is not configured."
|
|
5759
5830
|
};
|
|
5760
5831
|
}
|
|
5761
|
-
const fullPath = input.path.startsWith("/") ? input.path :
|
|
5832
|
+
const fullPath = input.path.startsWith("/") ? input.path : join6(options.workingDirectory, input.path);
|
|
5762
5833
|
try {
|
|
5763
5834
|
await stat4(fullPath);
|
|
5764
5835
|
} catch {
|
|
@@ -7323,11 +7394,11 @@ ${taskAddendum}`;
|
|
|
7323
7394
|
const { isRemoteConfigured: isRemoteConfigured2, storageQueries: storageQueries2 } = await Promise.resolve().then(() => (init_remote(), remote_exports));
|
|
7324
7395
|
if (!isRemoteConfigured2()) return [];
|
|
7325
7396
|
const { readFile: readFile11 } = await import("fs/promises");
|
|
7326
|
-
const { join:
|
|
7397
|
+
const { join: join12, basename: basename6 } = await import("path");
|
|
7327
7398
|
const urls = [];
|
|
7328
7399
|
for (const filePath of filePaths) {
|
|
7329
7400
|
try {
|
|
7330
|
-
const fullPath = filePath.startsWith("/") ? filePath :
|
|
7401
|
+
const fullPath = filePath.startsWith("/") ? filePath : join12(this.session.workingDirectory, filePath);
|
|
7331
7402
|
const fileName = basename6(fullPath);
|
|
7332
7403
|
const ext = fileName.split(".").pop()?.toLowerCase() || "";
|
|
7333
7404
|
const mimeMap = {
|
|
@@ -7502,8 +7573,8 @@ import { Hono as Hono6 } from "hono";
|
|
|
7502
7573
|
import { serve } from "@hono/node-server";
|
|
7503
7574
|
import { cors } from "hono/cors";
|
|
7504
7575
|
import { logger } from "hono/logger";
|
|
7505
|
-
import { existsSync as
|
|
7506
|
-
import { resolve as resolve10, dirname as dirname7, join as
|
|
7576
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
7577
|
+
import { resolve as resolve10, dirname as dirname7, join as join11 } from "path";
|
|
7507
7578
|
import { spawn as spawn2 } from "child_process";
|
|
7508
7579
|
import { createServer as createNetServer } from "net";
|
|
7509
7580
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
@@ -7513,9 +7584,9 @@ init_db();
|
|
|
7513
7584
|
import { Hono } from "hono";
|
|
7514
7585
|
import { zValidator } from "@hono/zod-validator";
|
|
7515
7586
|
import { z as z15 } from "zod";
|
|
7516
|
-
import { existsSync as
|
|
7587
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync4, writeFileSync as writeFileSync3, readdirSync, statSync as statSync2, unlinkSync } from "fs";
|
|
7517
7588
|
import { readdir as readdir6 } from "fs/promises";
|
|
7518
|
-
import { join as
|
|
7589
|
+
import { join as join8, basename as basename5, extname as extname8, relative as relative9 } from "path";
|
|
7519
7590
|
import { nanoid as nanoid5 } from "nanoid";
|
|
7520
7591
|
init_config();
|
|
7521
7592
|
|
|
@@ -7977,12 +8048,12 @@ sessions.get("/:id/diff/:filePath", async (c) => {
|
|
|
7977
8048
|
});
|
|
7978
8049
|
function getAttachmentsDir(sessionId) {
|
|
7979
8050
|
const appDataDir = getAppDataDirectory();
|
|
7980
|
-
return
|
|
8051
|
+
return join8(appDataDir, "attachments", sessionId);
|
|
7981
8052
|
}
|
|
7982
8053
|
function ensureAttachmentsDir(sessionId) {
|
|
7983
8054
|
const dir = getAttachmentsDir(sessionId);
|
|
7984
|
-
if (!
|
|
7985
|
-
|
|
8055
|
+
if (!existsSync14(dir)) {
|
|
8056
|
+
mkdirSync4(dir, { recursive: true });
|
|
7986
8057
|
}
|
|
7987
8058
|
return dir;
|
|
7988
8059
|
}
|
|
@@ -7993,12 +8064,12 @@ sessions.get("/:id/attachments", async (c) => {
|
|
|
7993
8064
|
return c.json({ error: "Session not found" }, 404);
|
|
7994
8065
|
}
|
|
7995
8066
|
const dir = getAttachmentsDir(sessionId);
|
|
7996
|
-
if (!
|
|
8067
|
+
if (!existsSync14(dir)) {
|
|
7997
8068
|
return c.json({ sessionId, attachments: [], count: 0 });
|
|
7998
8069
|
}
|
|
7999
8070
|
const files = readdirSync(dir);
|
|
8000
8071
|
const attachments = files.map((filename) => {
|
|
8001
|
-
const filePath =
|
|
8072
|
+
const filePath = join8(dir, filename);
|
|
8002
8073
|
const stats = statSync2(filePath);
|
|
8003
8074
|
return {
|
|
8004
8075
|
id: filename.split("_")[0],
|
|
@@ -8033,9 +8104,9 @@ sessions.post("/:id/attachments", async (c) => {
|
|
|
8033
8104
|
const id = nanoid5(10);
|
|
8034
8105
|
const ext = extname8(file.name) || "";
|
|
8035
8106
|
const safeFilename = `${id}_${basename5(file.name).replace(/[^a-zA-Z0-9._-]/g, "_")}`;
|
|
8036
|
-
const filePath =
|
|
8107
|
+
const filePath = join8(dir, safeFilename);
|
|
8037
8108
|
const arrayBuffer = await file.arrayBuffer();
|
|
8038
|
-
|
|
8109
|
+
writeFileSync3(filePath, Buffer.from(arrayBuffer));
|
|
8039
8110
|
return c.json({
|
|
8040
8111
|
id,
|
|
8041
8112
|
filename: file.name,
|
|
@@ -8059,13 +8130,13 @@ sessions.post("/:id/attachments", async (c) => {
|
|
|
8059
8130
|
const id = nanoid5(10);
|
|
8060
8131
|
const ext = extname8(body.filename) || "";
|
|
8061
8132
|
const safeFilename = `${id}_${basename5(body.filename).replace(/[^a-zA-Z0-9._-]/g, "_")}`;
|
|
8062
|
-
const filePath =
|
|
8133
|
+
const filePath = join8(dir, safeFilename);
|
|
8063
8134
|
let base64Data = body.data;
|
|
8064
8135
|
if (base64Data.includes(",")) {
|
|
8065
8136
|
base64Data = base64Data.split(",")[1];
|
|
8066
8137
|
}
|
|
8067
8138
|
const buffer = Buffer.from(base64Data, "base64");
|
|
8068
|
-
|
|
8139
|
+
writeFileSync3(filePath, buffer);
|
|
8069
8140
|
return c.json({
|
|
8070
8141
|
id,
|
|
8071
8142
|
filename: body.filename,
|
|
@@ -8088,7 +8159,7 @@ sessions.delete("/:id/attachments/:attachmentId", async (c) => {
|
|
|
8088
8159
|
return c.json({ error: "Session not found" }, 404);
|
|
8089
8160
|
}
|
|
8090
8161
|
const dir = getAttachmentsDir(sessionId);
|
|
8091
|
-
if (!
|
|
8162
|
+
if (!existsSync14(dir)) {
|
|
8092
8163
|
return c.json({ error: "Attachment not found" }, 404);
|
|
8093
8164
|
}
|
|
8094
8165
|
const files = readdirSync(dir);
|
|
@@ -8096,7 +8167,7 @@ sessions.delete("/:id/attachments/:attachmentId", async (c) => {
|
|
|
8096
8167
|
if (!file) {
|
|
8097
8168
|
return c.json({ error: "Attachment not found" }, 404);
|
|
8098
8169
|
}
|
|
8099
|
-
const filePath =
|
|
8170
|
+
const filePath = join8(dir, file);
|
|
8100
8171
|
unlinkSync(filePath);
|
|
8101
8172
|
return c.json({ success: true, id: attachmentId });
|
|
8102
8173
|
});
|
|
@@ -8179,7 +8250,7 @@ async function listWorkspaceFiles(baseDir, currentDir, query, limit, results = [
|
|
|
8179
8250
|
const entries = await readdir6(currentDir, { withFileTypes: true });
|
|
8180
8251
|
for (const entry of entries) {
|
|
8181
8252
|
if (results.length >= limit * 2) break;
|
|
8182
|
-
const fullPath =
|
|
8253
|
+
const fullPath = join8(currentDir, entry.name);
|
|
8183
8254
|
const relativePath = relative9(baseDir, fullPath);
|
|
8184
8255
|
if (entry.isDirectory() && IGNORED_DIRECTORIES.has(entry.name)) {
|
|
8185
8256
|
continue;
|
|
@@ -8227,7 +8298,7 @@ sessions.get(
|
|
|
8227
8298
|
return c.json({ error: "Session not found" }, 404);
|
|
8228
8299
|
}
|
|
8229
8300
|
const workingDirectory = session.workingDirectory;
|
|
8230
|
-
if (!
|
|
8301
|
+
if (!existsSync14(workingDirectory)) {
|
|
8231
8302
|
return c.json({
|
|
8232
8303
|
sessionId,
|
|
8233
8304
|
workingDirectory,
|
|
@@ -8338,8 +8409,8 @@ init_db();
|
|
|
8338
8409
|
import { Hono as Hono2 } from "hono";
|
|
8339
8410
|
import { zValidator as zValidator2 } from "@hono/zod-validator";
|
|
8340
8411
|
import { z as z16 } from "zod";
|
|
8341
|
-
import { existsSync as
|
|
8342
|
-
import { join as
|
|
8412
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
8413
|
+
import { join as join9 } from "path";
|
|
8343
8414
|
init_config();
|
|
8344
8415
|
|
|
8345
8416
|
// src/server/resumable-stream.ts
|
|
@@ -8545,12 +8616,12 @@ var rejectSchema = z16.object({
|
|
|
8545
8616
|
var streamAbortControllers = /* @__PURE__ */ new Map();
|
|
8546
8617
|
function getAttachmentsDirectory(sessionId) {
|
|
8547
8618
|
const appDataDir = getAppDataDirectory();
|
|
8548
|
-
return
|
|
8619
|
+
return join9(appDataDir, "attachments", sessionId);
|
|
8549
8620
|
}
|
|
8550
|
-
function saveAttachmentToDisk(sessionId, attachment, index) {
|
|
8621
|
+
async function saveAttachmentToDisk(sessionId, attachment, index) {
|
|
8551
8622
|
const attachmentsDir = getAttachmentsDirectory(sessionId);
|
|
8552
|
-
if (!
|
|
8553
|
-
|
|
8623
|
+
if (!existsSync15(attachmentsDir)) {
|
|
8624
|
+
mkdirSync5(attachmentsDir, { recursive: true });
|
|
8554
8625
|
}
|
|
8555
8626
|
let filename = attachment.filename;
|
|
8556
8627
|
if (!filename) {
|
|
@@ -8561,9 +8632,14 @@ function saveAttachmentToDisk(sessionId, attachment, index) {
|
|
|
8561
8632
|
if (base64Data.includes(",")) {
|
|
8562
8633
|
base64Data = base64Data.split(",")[1];
|
|
8563
8634
|
}
|
|
8564
|
-
|
|
8565
|
-
|
|
8566
|
-
|
|
8635
|
+
let buffer = Buffer.from(base64Data, "base64");
|
|
8636
|
+
if (attachment.type === "image") {
|
|
8637
|
+
buffer = await resizeImageIfNeeded(buffer, attachment.mediaType);
|
|
8638
|
+
const prefix = attachment.data.includes(",") ? attachment.data.split(",")[0] + "," : "";
|
|
8639
|
+
attachment.data = prefix + buffer.toString("base64");
|
|
8640
|
+
}
|
|
8641
|
+
const filePath = join9(attachmentsDir, filename);
|
|
8642
|
+
writeFileSync4(filePath, buffer);
|
|
8567
8643
|
return filePath;
|
|
8568
8644
|
}
|
|
8569
8645
|
function getExtensionFromMediaType(mediaType, type) {
|
|
@@ -8923,7 +8999,7 @@ agents.post(
|
|
|
8923
8999
|
for (let i = 0; i < streamAttachments.length; i++) {
|
|
8924
9000
|
const attachment = streamAttachments[i];
|
|
8925
9001
|
try {
|
|
8926
|
-
const savedPath = saveAttachmentToDisk(id, attachment, i);
|
|
9002
|
+
const savedPath = await saveAttachmentToDisk(id, attachment, i);
|
|
8927
9003
|
attachment.savedPath = savedPath;
|
|
8928
9004
|
} catch (err) {
|
|
8929
9005
|
console.error(`Failed to save attachment ${i}:`, err);
|
|
@@ -9497,26 +9573,26 @@ init_config();
|
|
|
9497
9573
|
import { Hono as Hono3 } from "hono";
|
|
9498
9574
|
import { zValidator as zValidator3 } from "@hono/zod-validator";
|
|
9499
9575
|
import { z as z17 } from "zod";
|
|
9500
|
-
import { readFileSync as
|
|
9576
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
9501
9577
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
9502
|
-
import { dirname as dirname6, join as
|
|
9578
|
+
import { dirname as dirname6, join as join10 } from "path";
|
|
9503
9579
|
var __filename = fileURLToPath3(import.meta.url);
|
|
9504
9580
|
var __dirname = dirname6(__filename);
|
|
9505
9581
|
var possiblePaths = [
|
|
9506
|
-
|
|
9582
|
+
join10(__dirname, "../package.json"),
|
|
9507
9583
|
// From dist/server -> dist/../package.json
|
|
9508
|
-
|
|
9584
|
+
join10(__dirname, "../../package.json"),
|
|
9509
9585
|
// From dist/server (if nested differently)
|
|
9510
|
-
|
|
9586
|
+
join10(__dirname, "../../../package.json"),
|
|
9511
9587
|
// From src/server/routes (development)
|
|
9512
|
-
|
|
9588
|
+
join10(process.cwd(), "package.json")
|
|
9513
9589
|
// From current working directory
|
|
9514
9590
|
];
|
|
9515
9591
|
var currentVersion = "0.0.0";
|
|
9516
9592
|
var packageName = "sparkecoder";
|
|
9517
9593
|
for (const packageJsonPath of possiblePaths) {
|
|
9518
9594
|
try {
|
|
9519
|
-
const packageJson = JSON.parse(
|
|
9595
|
+
const packageJson = JSON.parse(readFileSync6(packageJsonPath, "utf-8"));
|
|
9520
9596
|
if (packageJson.name === "sparkecoder") {
|
|
9521
9597
|
currentVersion = packageJson.version || "0.0.0";
|
|
9522
9598
|
packageName = packageJson.name || "sparkecoder";
|
|
@@ -10232,11 +10308,11 @@ function getWebDirectory() {
|
|
|
10232
10308
|
try {
|
|
10233
10309
|
const currentDir = dirname7(fileURLToPath4(import.meta.url));
|
|
10234
10310
|
const webDir = resolve10(currentDir, "..", "web");
|
|
10235
|
-
if (
|
|
10311
|
+
if (existsSync16(webDir) && existsSync16(join11(webDir, "package.json"))) {
|
|
10236
10312
|
return webDir;
|
|
10237
10313
|
}
|
|
10238
10314
|
const altWebDir = resolve10(currentDir, "..", "..", "web");
|
|
10239
|
-
if (
|
|
10315
|
+
if (existsSync16(altWebDir) && existsSync16(join11(altWebDir, "package.json"))) {
|
|
10240
10316
|
return altWebDir;
|
|
10241
10317
|
}
|
|
10242
10318
|
return null;
|
|
@@ -10294,23 +10370,23 @@ async function findWebPort(preferredPort) {
|
|
|
10294
10370
|
return { port: preferredPort, alreadyRunning: false };
|
|
10295
10371
|
}
|
|
10296
10372
|
function hasProductionBuild(webDir) {
|
|
10297
|
-
const buildIdPath =
|
|
10298
|
-
return
|
|
10373
|
+
const buildIdPath = join11(webDir, ".next", "BUILD_ID");
|
|
10374
|
+
return existsSync16(buildIdPath);
|
|
10299
10375
|
}
|
|
10300
10376
|
function hasSourceFiles(webDir) {
|
|
10301
|
-
const appDir =
|
|
10302
|
-
const pagesDir =
|
|
10303
|
-
const rootAppDir =
|
|
10304
|
-
const rootPagesDir =
|
|
10305
|
-
return
|
|
10377
|
+
const appDir = join11(webDir, "src", "app");
|
|
10378
|
+
const pagesDir = join11(webDir, "src", "pages");
|
|
10379
|
+
const rootAppDir = join11(webDir, "app");
|
|
10380
|
+
const rootPagesDir = join11(webDir, "pages");
|
|
10381
|
+
return existsSync16(appDir) || existsSync16(pagesDir) || existsSync16(rootAppDir) || existsSync16(rootPagesDir);
|
|
10306
10382
|
}
|
|
10307
10383
|
function getStandaloneServerPath(webDir) {
|
|
10308
10384
|
const possiblePaths2 = [
|
|
10309
|
-
|
|
10310
|
-
|
|
10385
|
+
join11(webDir, ".next", "standalone", "server.js"),
|
|
10386
|
+
join11(webDir, ".next", "standalone", "web", "server.js")
|
|
10311
10387
|
];
|
|
10312
10388
|
for (const serverPath of possiblePaths2) {
|
|
10313
|
-
if (
|
|
10389
|
+
if (existsSync16(serverPath)) {
|
|
10314
10390
|
return serverPath;
|
|
10315
10391
|
}
|
|
10316
10392
|
}
|
|
@@ -10350,15 +10426,15 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false, pu
|
|
|
10350
10426
|
if (!quiet) console.log(` \u2713 Web UI already running at http://localhost:${actualPort}`);
|
|
10351
10427
|
return { process: null, port: actualPort };
|
|
10352
10428
|
}
|
|
10353
|
-
const usePnpm =
|
|
10354
|
-
const useNpm = !usePnpm &&
|
|
10429
|
+
const usePnpm = existsSync16(join11(webDir, "pnpm-lock.yaml"));
|
|
10430
|
+
const useNpm = !usePnpm && existsSync16(join11(webDir, "package-lock.json"));
|
|
10355
10431
|
const pkgManager = usePnpm ? "pnpm" : useNpm ? "npm" : "npx";
|
|
10356
10432
|
const { NODE_OPTIONS, TSX_TSCONFIG_PATH, ...cleanEnv } = process.env;
|
|
10357
10433
|
const apiUrl = publicUrl || `http://127.0.0.1:${apiPort}`;
|
|
10358
10434
|
const runtimeConfig = { apiBaseUrl: apiUrl };
|
|
10359
|
-
const runtimeConfigPath =
|
|
10435
|
+
const runtimeConfigPath = join11(webDir, "runtime-config.json");
|
|
10360
10436
|
try {
|
|
10361
|
-
|
|
10437
|
+
writeFileSync5(runtimeConfigPath, JSON.stringify(runtimeConfig, null, 2));
|
|
10362
10438
|
if (!quiet) console.log(` \u{1F4DD} Runtime config written to ${runtimeConfigPath}`);
|
|
10363
10439
|
} catch (err) {
|
|
10364
10440
|
if (!quiet) console.warn(` \u26A0 Could not write runtime config: ${err}`);
|
|
@@ -10549,8 +10625,8 @@ async function startServer(options = {}) {
|
|
|
10549
10625
|
if (options.workingDirectory) {
|
|
10550
10626
|
config.resolvedWorkingDirectory = options.workingDirectory;
|
|
10551
10627
|
}
|
|
10552
|
-
if (!
|
|
10553
|
-
|
|
10628
|
+
if (!existsSync16(config.resolvedWorkingDirectory)) {
|
|
10629
|
+
mkdirSync6(config.resolvedWorkingDirectory, { recursive: true });
|
|
10554
10630
|
if (!options.quiet) console.log(`\u{1F4C1} Created agent workspace: ${config.resolvedWorkingDirectory}`);
|
|
10555
10631
|
}
|
|
10556
10632
|
if (!config.resolvedRemoteServer.url) {
|