sparkecoder 0.1.59 → 0.1.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/index.js +74 -27
- package/dist/agent/index.js.map +1 -1
- package/dist/cli.js +88 -34
- package/dist/cli.js.map +1 -1
- package/dist/index.js +87 -33
- package/dist/index.js.map +1 -1
- package/dist/server/index.js +87 -33
- package/dist/server/index.js.map +1 -1
- package/dist/skills/default/browser.md +143 -0
- package/dist/skills/default/code-review.md +122 -0
- package/dist/skills/default/debugging.md +105 -0
- package/dist/skills/default/refactoring.md +197 -0
- package/dist/tools/index.d.ts +16 -1
- package/dist/tools/index.js +74 -27
- package/dist/tools/index.js.map +1 -1
- package/package.json +4 -1
- package/src/skills/default/browser.md +143 -0
- package/src/skills/default/code-review.md +122 -0
- package/src/skills/default/debugging.md +105 -0
- package/src/skills/default/refactoring.md +197 -0
- package/web/.next/BUILD_ID +1 -1
- 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/u5qqIWWrYpWW_mZUgKKjg → R5xiWSOp_Nqqe_js-LROo}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{static/u5qqIWWrYpWW_mZUgKKjg → R5xiWSOp_Nqqe_js-LROo}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{static/u5qqIWWrYpWW_mZUgKKjg → R5xiWSOp_Nqqe_js-LROo}/_ssgManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{u5qqIWWrYpWW_mZUgKKjg → static/R5xiWSOp_Nqqe_js-LROo}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{u5qqIWWrYpWW_mZUgKKjg → static/R5xiWSOp_Nqqe_js-LROo}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{u5qqIWWrYpWW_mZUgKKjg → static/R5xiWSOp_Nqqe_js-LROo}/_ssgManifest.js +0 -0
- /package/web/.next/static/{u5qqIWWrYpWW_mZUgKKjg → R5xiWSOp_Nqqe_js-LROo}/_buildManifest.js +0 -0
- /package/web/.next/static/{u5qqIWWrYpWW_mZUgKKjg → R5xiWSOp_Nqqe_js-LROo}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{u5qqIWWrYpWW_mZUgKKjg → R5xiWSOp_Nqqe_js-LROo}/_ssgManifest.js +0 -0
package/dist/cli.js
CHANGED
|
@@ -558,8 +558,15 @@ function discoverSkillDirectories(workingDir) {
|
|
|
558
558
|
if (existsSync(agentsMd)) {
|
|
559
559
|
agentsMdPath = agentsMd;
|
|
560
560
|
}
|
|
561
|
-
const
|
|
562
|
-
|
|
561
|
+
const baseDir = dirname(import.meta.url.replace("file://", ""));
|
|
562
|
+
const builtInCandidates = [
|
|
563
|
+
resolve(baseDir, "../skills/default"),
|
|
564
|
+
// dev: src/config → src/skills/default
|
|
565
|
+
resolve(baseDir, "./skills/default")
|
|
566
|
+
// prod: dist/ → dist/skills/default
|
|
567
|
+
];
|
|
568
|
+
const builtInSkillsDir = builtInCandidates.find((p) => existsSync(p));
|
|
569
|
+
if (builtInSkillsDir) {
|
|
563
570
|
onDemandDirs.push({ path: builtInSkillsDir, priority: 100 });
|
|
564
571
|
allDirectories.push(builtInSkillsDir);
|
|
565
572
|
}
|
|
@@ -938,7 +945,7 @@ __export(skills_exports, {
|
|
|
938
945
|
loadSkillsFromDirectory: () => loadSkillsFromDirectory
|
|
939
946
|
});
|
|
940
947
|
import { readFile as readFile6, readdir } from "fs/promises";
|
|
941
|
-
import { resolve as resolve6, basename, extname as
|
|
948
|
+
import { resolve as resolve6, basename, extname as extname4, relative as relative4 } from "path";
|
|
942
949
|
import { existsSync as existsSync8 } from "fs";
|
|
943
950
|
import { minimatch } from "minimatch";
|
|
944
951
|
function parseSkillFrontmatter(content) {
|
|
@@ -1009,7 +1016,7 @@ function parseSkillFrontmatter(content) {
|
|
|
1009
1016
|
}
|
|
1010
1017
|
}
|
|
1011
1018
|
function getSkillNameFromPath(filePath) {
|
|
1012
|
-
return basename(filePath,
|
|
1019
|
+
return basename(filePath, extname4(filePath)).replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
1013
1020
|
}
|
|
1014
1021
|
async function loadSkillsFromDirectory(directory, options = {}) {
|
|
1015
1022
|
const {
|
|
@@ -1334,9 +1341,9 @@ var init_hasher = __esm({
|
|
|
1334
1341
|
});
|
|
1335
1342
|
|
|
1336
1343
|
// src/semantic/chunker.ts
|
|
1337
|
-
import { extname as
|
|
1344
|
+
import { extname as extname6, basename as basename2 } from "path";
|
|
1338
1345
|
function detectLanguage(filePath) {
|
|
1339
|
-
const ext =
|
|
1346
|
+
const ext = extname6(filePath).toLowerCase();
|
|
1340
1347
|
return LANGUAGE_MAP[ext] || "unknown";
|
|
1341
1348
|
}
|
|
1342
1349
|
function supportsSemanticChunking(language) {
|
|
@@ -2428,7 +2435,7 @@ import { zValidator } from "@hono/zod-validator";
|
|
|
2428
2435
|
import { z as z13 } from "zod";
|
|
2429
2436
|
import { existsSync as existsSync13, mkdirSync as mkdirSync3, writeFileSync as writeFileSync2, readdirSync, statSync as statSync2, unlinkSync } from "fs";
|
|
2430
2437
|
import { readdir as readdir5 } from "fs/promises";
|
|
2431
|
-
import { join as join5, basename as basename4, extname as
|
|
2438
|
+
import { join as join5, basename as basename4, extname as extname7, relative as relative9 } from "path";
|
|
2432
2439
|
import { nanoid as nanoid4 } from "nanoid";
|
|
2433
2440
|
|
|
2434
2441
|
// src/agent/index.ts
|
|
@@ -3039,26 +3046,41 @@ Terminal output is stored in the global SparkECoder data directory. Use the \`ta
|
|
|
3039
3046
|
import { tool as tool2 } from "ai";
|
|
3040
3047
|
import { z as z3 } from "zod";
|
|
3041
3048
|
import { readFile as readFile2, stat } from "fs/promises";
|
|
3042
|
-
import { resolve as resolve2, relative, isAbsolute } from "path";
|
|
3049
|
+
import { resolve as resolve2, relative, isAbsolute, extname } from "path";
|
|
3043
3050
|
import { existsSync as existsSync3 } from "fs";
|
|
3044
3051
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
3052
|
+
var MAX_IMAGE_SIZE = 20 * 1024 * 1024;
|
|
3045
3053
|
var MAX_OUTPUT_CHARS3 = 5e4;
|
|
3054
|
+
var IMAGE_EXTENSIONS = {
|
|
3055
|
+
".png": "image/png",
|
|
3056
|
+
".jpg": "image/jpeg",
|
|
3057
|
+
".jpeg": "image/jpeg",
|
|
3058
|
+
".gif": "image/gif",
|
|
3059
|
+
".webp": "image/webp"
|
|
3060
|
+
};
|
|
3061
|
+
function isImageFile(filePath) {
|
|
3062
|
+
return extname(filePath).toLowerCase() in IMAGE_EXTENSIONS;
|
|
3063
|
+
}
|
|
3064
|
+
function getImageMediaType(filePath) {
|
|
3065
|
+
return IMAGE_EXTENSIONS[extname(filePath).toLowerCase()] || "image/png";
|
|
3066
|
+
}
|
|
3046
3067
|
var readFileInputSchema = z3.object({
|
|
3047
|
-
path: z3.string().describe("The path to the file to read. Can be relative to working directory or absolute."),
|
|
3048
|
-
startLine: z3.number().optional().describe("Optional: Start reading from this line number (1-indexed)"),
|
|
3049
|
-
endLine: z3.number().optional().describe("Optional: Stop reading at this line number (1-indexed, inclusive)")
|
|
3068
|
+
path: z3.string().describe("The path to the file to read. Can be relative to working directory or absolute. Supports text files and images (png, jpg, jpeg, gif, webp)."),
|
|
3069
|
+
startLine: z3.number().optional().describe("Optional: Start reading from this line number (1-indexed). Only for text files."),
|
|
3070
|
+
endLine: z3.number().optional().describe("Optional: Stop reading at this line number (1-indexed, inclusive). Only for text files.")
|
|
3050
3071
|
});
|
|
3051
3072
|
function createReadFileTool(options) {
|
|
3052
3073
|
return tool2({
|
|
3053
3074
|
description: `Read the contents of a file. Provide a path relative to the working directory (${options.workingDirectory}) or an absolute path.
|
|
3054
|
-
|
|
3055
|
-
|
|
3075
|
+
Supports text files (automatically truncated if large) and image files (png, jpg, jpeg, gif, webp).
|
|
3076
|
+
For images, the file contents are returned as visual data you can see and analyze.
|
|
3077
|
+
Use this to understand existing code, check file contents, view screenshots, or gather context.`,
|
|
3056
3078
|
inputSchema: readFileInputSchema,
|
|
3057
|
-
execute: async ({ path, startLine, endLine }) => {
|
|
3079
|
+
execute: async ({ path: filePath, startLine, endLine }) => {
|
|
3058
3080
|
try {
|
|
3059
|
-
const absolutePath = isAbsolute(
|
|
3081
|
+
const absolutePath = isAbsolute(filePath) ? filePath : resolve2(options.workingDirectory, filePath);
|
|
3060
3082
|
const relativePath = relative(options.workingDirectory, absolutePath);
|
|
3061
|
-
if (relativePath.startsWith("..") && !isAbsolute(
|
|
3083
|
+
if (relativePath.startsWith("..") && !isAbsolute(filePath)) {
|
|
3062
3084
|
return {
|
|
3063
3085
|
success: false,
|
|
3064
3086
|
error: "Path escapes the working directory. Use an absolute path if intentional.",
|
|
@@ -3068,22 +3090,43 @@ Use this to understand existing code, check file contents, or gather context.`,
|
|
|
3068
3090
|
if (!existsSync3(absolutePath)) {
|
|
3069
3091
|
return {
|
|
3070
3092
|
success: false,
|
|
3071
|
-
error: `File not found: ${
|
|
3093
|
+
error: `File not found: ${filePath}`,
|
|
3072
3094
|
content: null
|
|
3073
3095
|
};
|
|
3074
3096
|
}
|
|
3075
3097
|
const stats = await stat(absolutePath);
|
|
3076
|
-
if (stats.
|
|
3098
|
+
if (stats.isDirectory()) {
|
|
3077
3099
|
return {
|
|
3078
3100
|
success: false,
|
|
3079
|
-
error:
|
|
3101
|
+
error: 'Path is a directory, not a file. Use bash with "ls" to list directory contents.',
|
|
3080
3102
|
content: null
|
|
3081
3103
|
};
|
|
3082
3104
|
}
|
|
3083
|
-
if (
|
|
3105
|
+
if (isImageFile(absolutePath)) {
|
|
3106
|
+
if (stats.size > MAX_IMAGE_SIZE) {
|
|
3107
|
+
return {
|
|
3108
|
+
success: false,
|
|
3109
|
+
error: `Image is too large (${(stats.size / 1024 / 1024).toFixed(2)}MB). Maximum size is ${MAX_IMAGE_SIZE / 1024 / 1024}MB.`,
|
|
3110
|
+
content: null
|
|
3111
|
+
};
|
|
3112
|
+
}
|
|
3113
|
+
const buffer = await readFile2(absolutePath);
|
|
3114
|
+
const base64 = buffer.toString("base64");
|
|
3115
|
+
const mediaType = getImageMediaType(absolutePath);
|
|
3116
|
+
return {
|
|
3117
|
+
success: true,
|
|
3118
|
+
path: absolutePath,
|
|
3119
|
+
relativePath: relative(options.workingDirectory, absolutePath),
|
|
3120
|
+
content: `[Image: ${relativePath} (${mediaType}, ${(stats.size / 1024).toFixed(1)}KB)]`,
|
|
3121
|
+
mediaType,
|
|
3122
|
+
imageData: base64,
|
|
3123
|
+
sizeBytes: stats.size
|
|
3124
|
+
};
|
|
3125
|
+
}
|
|
3126
|
+
if (stats.size > MAX_FILE_SIZE) {
|
|
3084
3127
|
return {
|
|
3085
3128
|
success: false,
|
|
3086
|
-
error:
|
|
3129
|
+
error: `File is too large (${(stats.size / 1024 / 1024).toFixed(2)}MB). Maximum size is ${MAX_FILE_SIZE / 1024 / 1024}MB.`,
|
|
3087
3130
|
content: null
|
|
3088
3131
|
};
|
|
3089
3132
|
}
|
|
@@ -3099,9 +3142,7 @@ Use this to understand existing code, check file contents, or gather context.`,
|
|
|
3099
3142
|
content: null
|
|
3100
3143
|
};
|
|
3101
3144
|
}
|
|
3102
|
-
content = lines.slice(start, end).join("\n");
|
|
3103
|
-
const lineNumbers = lines.slice(start, end).map((line, idx) => `${(start + idx + 1).toString().padStart(4)}: ${line}`).join("\n");
|
|
3104
|
-
content = lineNumbers;
|
|
3145
|
+
content = lines.slice(start, end).map((line, idx) => `${(start + idx + 1).toString().padStart(4)}: ${line}`).join("\n");
|
|
3105
3146
|
}
|
|
3106
3147
|
const truncatedContent = truncateOutput(content, MAX_OUTPUT_CHARS3);
|
|
3107
3148
|
const wasTruncated = truncatedContent.length < content.length;
|
|
@@ -3128,6 +3169,19 @@ Use this to understand existing code, check file contents, or gather context.`,
|
|
|
3128
3169
|
content: null
|
|
3129
3170
|
};
|
|
3130
3171
|
}
|
|
3172
|
+
},
|
|
3173
|
+
toModelOutput: ({ output }) => {
|
|
3174
|
+
if (output && typeof output === "object" && "imageData" in output && output.imageData) {
|
|
3175
|
+
const result = output;
|
|
3176
|
+
return {
|
|
3177
|
+
type: "content",
|
|
3178
|
+
value: [
|
|
3179
|
+
{ type: "text", text: result.content },
|
|
3180
|
+
{ type: "image-data", data: result.imageData, mediaType: result.mediaType }
|
|
3181
|
+
]
|
|
3182
|
+
};
|
|
3183
|
+
}
|
|
3184
|
+
return typeof output === "string" ? { type: "text", value: output } : { type: "json", value: output };
|
|
3131
3185
|
}
|
|
3132
3186
|
});
|
|
3133
3187
|
}
|
|
@@ -3328,7 +3382,7 @@ function clearCheckpointManager(sessionId) {
|
|
|
3328
3382
|
}
|
|
3329
3383
|
|
|
3330
3384
|
// src/lsp/index.ts
|
|
3331
|
-
import { extname as
|
|
3385
|
+
import { extname as extname3, dirname as dirname4 } from "path";
|
|
3332
3386
|
|
|
3333
3387
|
// src/lsp/servers.ts
|
|
3334
3388
|
import { spawn } from "child_process";
|
|
@@ -3451,9 +3505,9 @@ import {
|
|
|
3451
3505
|
import { pathToFileURL, fileURLToPath } from "url";
|
|
3452
3506
|
import { readFile as readFile4 } from "fs/promises";
|
|
3453
3507
|
import { existsSync as existsSync6 } from "fs";
|
|
3454
|
-
import { extname, normalize } from "path";
|
|
3508
|
+
import { extname as extname2, normalize } from "path";
|
|
3455
3509
|
function getLanguageId(filePath) {
|
|
3456
|
-
const ext =
|
|
3510
|
+
const ext = extname2(filePath).toLowerCase();
|
|
3457
3511
|
const map = {
|
|
3458
3512
|
".ts": "typescript",
|
|
3459
3513
|
".tsx": "typescriptreact",
|
|
@@ -3841,7 +3895,7 @@ var state = {
|
|
|
3841
3895
|
};
|
|
3842
3896
|
async function getClientForFile(filePath) {
|
|
3843
3897
|
const normalized = normalizePath(filePath);
|
|
3844
|
-
const ext =
|
|
3898
|
+
const ext = extname3(normalized);
|
|
3845
3899
|
const serverDef = getServerForExtension(ext);
|
|
3846
3900
|
if (!serverDef) {
|
|
3847
3901
|
return null;
|
|
@@ -3934,7 +3988,7 @@ async function formatDiagnosticsOutput(filePath, options = {}) {
|
|
|
3934
3988
|
return formatDiagnosticsForAgent(filePath, diagnostics, options);
|
|
3935
3989
|
}
|
|
3936
3990
|
function isSupported(filePath) {
|
|
3937
|
-
const ext =
|
|
3991
|
+
const ext = extname3(filePath);
|
|
3938
3992
|
return getServerForExtension(ext) !== null;
|
|
3939
3993
|
}
|
|
3940
3994
|
|
|
@@ -4361,7 +4415,7 @@ Once loaded, a skill's content will be available in the conversation context.`,
|
|
|
4361
4415
|
// src/tools/linter.ts
|
|
4362
4416
|
import { tool as tool6 } from "ai";
|
|
4363
4417
|
import { z as z7 } from "zod";
|
|
4364
|
-
import { resolve as resolve7, relative as relative5, isAbsolute as isAbsolute3, extname as
|
|
4418
|
+
import { resolve as resolve7, relative as relative5, isAbsolute as isAbsolute3, extname as extname5 } from "path";
|
|
4365
4419
|
import { existsSync as existsSync9 } from "fs";
|
|
4366
4420
|
import { readdir as readdir2, stat as stat2 } from "fs/promises";
|
|
4367
4421
|
var linterInputSchema = z7.object({
|
|
@@ -4384,7 +4438,7 @@ async function findSupportedFiles(dir, workingDirectory, maxFiles = 50) {
|
|
|
4384
4438
|
}
|
|
4385
4439
|
await walk(fullPath);
|
|
4386
4440
|
} else if (entry.isFile()) {
|
|
4387
|
-
const ext =
|
|
4441
|
+
const ext = extname5(entry.name);
|
|
4388
4442
|
if (supportedExtensions.includes(ext)) {
|
|
4389
4443
|
files.push(fullPath);
|
|
4390
4444
|
}
|
|
@@ -7208,7 +7262,7 @@ sessions.post("/:id/attachments", async (c) => {
|
|
|
7208
7262
|
}
|
|
7209
7263
|
const dir = ensureAttachmentsDir(sessionId);
|
|
7210
7264
|
const id = nanoid4(10);
|
|
7211
|
-
const ext =
|
|
7265
|
+
const ext = extname7(file.name) || "";
|
|
7212
7266
|
const safeFilename = `${id}_${basename4(file.name).replace(/[^a-zA-Z0-9._-]/g, "_")}`;
|
|
7213
7267
|
const filePath = join5(dir, safeFilename);
|
|
7214
7268
|
const arrayBuffer = await file.arrayBuffer();
|
|
@@ -7234,7 +7288,7 @@ sessions.post("/:id/attachments", async (c) => {
|
|
|
7234
7288
|
}
|
|
7235
7289
|
const dir = ensureAttachmentsDir(sessionId);
|
|
7236
7290
|
const id = nanoid4(10);
|
|
7237
|
-
const ext =
|
|
7291
|
+
const ext = extname7(body.filename) || "";
|
|
7238
7292
|
const safeFilename = `${id}_${basename4(body.filename).replace(/[^a-zA-Z0-9._-]/g, "_")}`;
|
|
7239
7293
|
const filePath = join5(dir, safeFilename);
|
|
7240
7294
|
let base64Data = body.data;
|
|
@@ -7364,7 +7418,7 @@ async function listWorkspaceFiles(baseDir, currentDir, query, limit, results = [
|
|
|
7364
7418
|
if (entry.name.startsWith(".")) {
|
|
7365
7419
|
continue;
|
|
7366
7420
|
}
|
|
7367
|
-
const ext =
|
|
7421
|
+
const ext = extname7(entry.name).toLowerCase();
|
|
7368
7422
|
if (IGNORED_EXTENSIONS.has(ext)) {
|
|
7369
7423
|
continue;
|
|
7370
7424
|
}
|