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/server/index.js
CHANGED
|
@@ -521,8 +521,15 @@ function discoverSkillDirectories(workingDir) {
|
|
|
521
521
|
if (existsSync(agentsMd)) {
|
|
522
522
|
agentsMdPath = agentsMd;
|
|
523
523
|
}
|
|
524
|
-
const
|
|
525
|
-
|
|
524
|
+
const baseDir = dirname(import.meta.url.replace("file://", ""));
|
|
525
|
+
const builtInCandidates = [
|
|
526
|
+
resolve(baseDir, "../skills/default"),
|
|
527
|
+
// dev: src/config → src/skills/default
|
|
528
|
+
resolve(baseDir, "./skills/default")
|
|
529
|
+
// prod: dist/ → dist/skills/default
|
|
530
|
+
];
|
|
531
|
+
const builtInSkillsDir = builtInCandidates.find((p) => existsSync(p));
|
|
532
|
+
if (builtInSkillsDir) {
|
|
526
533
|
onDemandDirs.push({ path: builtInSkillsDir, priority: 100 });
|
|
527
534
|
allDirectories.push(builtInSkillsDir);
|
|
528
535
|
}
|
|
@@ -874,7 +881,7 @@ __export(skills_exports, {
|
|
|
874
881
|
loadSkillsFromDirectory: () => loadSkillsFromDirectory
|
|
875
882
|
});
|
|
876
883
|
import { readFile as readFile6, readdir } from "fs/promises";
|
|
877
|
-
import { resolve as resolve6, basename, extname as
|
|
884
|
+
import { resolve as resolve6, basename, extname as extname4, relative as relative4 } from "path";
|
|
878
885
|
import { existsSync as existsSync8 } from "fs";
|
|
879
886
|
import { minimatch } from "minimatch";
|
|
880
887
|
function parseSkillFrontmatter(content) {
|
|
@@ -945,7 +952,7 @@ function parseSkillFrontmatter(content) {
|
|
|
945
952
|
}
|
|
946
953
|
}
|
|
947
954
|
function getSkillNameFromPath(filePath) {
|
|
948
|
-
return basename(filePath,
|
|
955
|
+
return basename(filePath, extname4(filePath)).replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
949
956
|
}
|
|
950
957
|
async function loadSkillsFromDirectory(directory, options = {}) {
|
|
951
958
|
const {
|
|
@@ -1250,7 +1257,7 @@ var init_hasher = __esm({
|
|
|
1250
1257
|
});
|
|
1251
1258
|
|
|
1252
1259
|
// src/semantic/chunker.ts
|
|
1253
|
-
import { extname as
|
|
1260
|
+
import { extname as extname6, basename as basename2 } from "path";
|
|
1254
1261
|
var init_chunker = __esm({
|
|
1255
1262
|
"src/semantic/chunker.ts"() {
|
|
1256
1263
|
"use strict";
|
|
@@ -1615,7 +1622,7 @@ import { zValidator } from "@hono/zod-validator";
|
|
|
1615
1622
|
import { z as z13 } from "zod";
|
|
1616
1623
|
import { existsSync as existsSync13, mkdirSync as mkdirSync3, writeFileSync as writeFileSync2, readdirSync, statSync as statSync2, unlinkSync } from "fs";
|
|
1617
1624
|
import { readdir as readdir5 } from "fs/promises";
|
|
1618
|
-
import { join as join5, basename as basename4, extname as
|
|
1625
|
+
import { join as join5, basename as basename4, extname as extname7, relative as relative9 } from "path";
|
|
1619
1626
|
import { nanoid as nanoid4 } from "nanoid";
|
|
1620
1627
|
|
|
1621
1628
|
// src/agent/index.ts
|
|
@@ -2226,26 +2233,41 @@ Terminal output is stored in the global SparkECoder data directory. Use the \`ta
|
|
|
2226
2233
|
import { tool as tool2 } from "ai";
|
|
2227
2234
|
import { z as z3 } from "zod";
|
|
2228
2235
|
import { readFile as readFile2, stat } from "fs/promises";
|
|
2229
|
-
import { resolve as resolve2, relative, isAbsolute } from "path";
|
|
2236
|
+
import { resolve as resolve2, relative, isAbsolute, extname } from "path";
|
|
2230
2237
|
import { existsSync as existsSync3 } from "fs";
|
|
2231
2238
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
2239
|
+
var MAX_IMAGE_SIZE = 20 * 1024 * 1024;
|
|
2232
2240
|
var MAX_OUTPUT_CHARS3 = 5e4;
|
|
2241
|
+
var IMAGE_EXTENSIONS = {
|
|
2242
|
+
".png": "image/png",
|
|
2243
|
+
".jpg": "image/jpeg",
|
|
2244
|
+
".jpeg": "image/jpeg",
|
|
2245
|
+
".gif": "image/gif",
|
|
2246
|
+
".webp": "image/webp"
|
|
2247
|
+
};
|
|
2248
|
+
function isImageFile(filePath) {
|
|
2249
|
+
return extname(filePath).toLowerCase() in IMAGE_EXTENSIONS;
|
|
2250
|
+
}
|
|
2251
|
+
function getImageMediaType(filePath) {
|
|
2252
|
+
return IMAGE_EXTENSIONS[extname(filePath).toLowerCase()] || "image/png";
|
|
2253
|
+
}
|
|
2233
2254
|
var readFileInputSchema = z3.object({
|
|
2234
|
-
path: z3.string().describe("The path to the file to read. Can be relative to working directory or absolute."),
|
|
2235
|
-
startLine: z3.number().optional().describe("Optional: Start reading from this line number (1-indexed)"),
|
|
2236
|
-
endLine: z3.number().optional().describe("Optional: Stop reading at this line number (1-indexed, inclusive)")
|
|
2255
|
+
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)."),
|
|
2256
|
+
startLine: z3.number().optional().describe("Optional: Start reading from this line number (1-indexed). Only for text files."),
|
|
2257
|
+
endLine: z3.number().optional().describe("Optional: Stop reading at this line number (1-indexed, inclusive). Only for text files.")
|
|
2237
2258
|
});
|
|
2238
2259
|
function createReadFileTool(options) {
|
|
2239
2260
|
return tool2({
|
|
2240
2261
|
description: `Read the contents of a file. Provide a path relative to the working directory (${options.workingDirectory}) or an absolute path.
|
|
2241
|
-
|
|
2242
|
-
|
|
2262
|
+
Supports text files (automatically truncated if large) and image files (png, jpg, jpeg, gif, webp).
|
|
2263
|
+
For images, the file contents are returned as visual data you can see and analyze.
|
|
2264
|
+
Use this to understand existing code, check file contents, view screenshots, or gather context.`,
|
|
2243
2265
|
inputSchema: readFileInputSchema,
|
|
2244
|
-
execute: async ({ path, startLine, endLine }) => {
|
|
2266
|
+
execute: async ({ path: filePath, startLine, endLine }) => {
|
|
2245
2267
|
try {
|
|
2246
|
-
const absolutePath = isAbsolute(
|
|
2268
|
+
const absolutePath = isAbsolute(filePath) ? filePath : resolve2(options.workingDirectory, filePath);
|
|
2247
2269
|
const relativePath = relative(options.workingDirectory, absolutePath);
|
|
2248
|
-
if (relativePath.startsWith("..") && !isAbsolute(
|
|
2270
|
+
if (relativePath.startsWith("..") && !isAbsolute(filePath)) {
|
|
2249
2271
|
return {
|
|
2250
2272
|
success: false,
|
|
2251
2273
|
error: "Path escapes the working directory. Use an absolute path if intentional.",
|
|
@@ -2255,22 +2277,43 @@ Use this to understand existing code, check file contents, or gather context.`,
|
|
|
2255
2277
|
if (!existsSync3(absolutePath)) {
|
|
2256
2278
|
return {
|
|
2257
2279
|
success: false,
|
|
2258
|
-
error: `File not found: ${
|
|
2280
|
+
error: `File not found: ${filePath}`,
|
|
2259
2281
|
content: null
|
|
2260
2282
|
};
|
|
2261
2283
|
}
|
|
2262
2284
|
const stats = await stat(absolutePath);
|
|
2263
|
-
if (stats.
|
|
2285
|
+
if (stats.isDirectory()) {
|
|
2264
2286
|
return {
|
|
2265
2287
|
success: false,
|
|
2266
|
-
error:
|
|
2288
|
+
error: 'Path is a directory, not a file. Use bash with "ls" to list directory contents.',
|
|
2267
2289
|
content: null
|
|
2268
2290
|
};
|
|
2269
2291
|
}
|
|
2270
|
-
if (
|
|
2292
|
+
if (isImageFile(absolutePath)) {
|
|
2293
|
+
if (stats.size > MAX_IMAGE_SIZE) {
|
|
2294
|
+
return {
|
|
2295
|
+
success: false,
|
|
2296
|
+
error: `Image is too large (${(stats.size / 1024 / 1024).toFixed(2)}MB). Maximum size is ${MAX_IMAGE_SIZE / 1024 / 1024}MB.`,
|
|
2297
|
+
content: null
|
|
2298
|
+
};
|
|
2299
|
+
}
|
|
2300
|
+
const buffer = await readFile2(absolutePath);
|
|
2301
|
+
const base64 = buffer.toString("base64");
|
|
2302
|
+
const mediaType = getImageMediaType(absolutePath);
|
|
2303
|
+
return {
|
|
2304
|
+
success: true,
|
|
2305
|
+
path: absolutePath,
|
|
2306
|
+
relativePath: relative(options.workingDirectory, absolutePath),
|
|
2307
|
+
content: `[Image: ${relativePath} (${mediaType}, ${(stats.size / 1024).toFixed(1)}KB)]`,
|
|
2308
|
+
mediaType,
|
|
2309
|
+
imageData: base64,
|
|
2310
|
+
sizeBytes: stats.size
|
|
2311
|
+
};
|
|
2312
|
+
}
|
|
2313
|
+
if (stats.size > MAX_FILE_SIZE) {
|
|
2271
2314
|
return {
|
|
2272
2315
|
success: false,
|
|
2273
|
-
error:
|
|
2316
|
+
error: `File is too large (${(stats.size / 1024 / 1024).toFixed(2)}MB). Maximum size is ${MAX_FILE_SIZE / 1024 / 1024}MB.`,
|
|
2274
2317
|
content: null
|
|
2275
2318
|
};
|
|
2276
2319
|
}
|
|
@@ -2286,9 +2329,7 @@ Use this to understand existing code, check file contents, or gather context.`,
|
|
|
2286
2329
|
content: null
|
|
2287
2330
|
};
|
|
2288
2331
|
}
|
|
2289
|
-
content = lines.slice(start, end).join("\n");
|
|
2290
|
-
const lineNumbers = lines.slice(start, end).map((line, idx) => `${(start + idx + 1).toString().padStart(4)}: ${line}`).join("\n");
|
|
2291
|
-
content = lineNumbers;
|
|
2332
|
+
content = lines.slice(start, end).map((line, idx) => `${(start + idx + 1).toString().padStart(4)}: ${line}`).join("\n");
|
|
2292
2333
|
}
|
|
2293
2334
|
const truncatedContent = truncateOutput(content, MAX_OUTPUT_CHARS3);
|
|
2294
2335
|
const wasTruncated = truncatedContent.length < content.length;
|
|
@@ -2315,6 +2356,19 @@ Use this to understand existing code, check file contents, or gather context.`,
|
|
|
2315
2356
|
content: null
|
|
2316
2357
|
};
|
|
2317
2358
|
}
|
|
2359
|
+
},
|
|
2360
|
+
toModelOutput: ({ output }) => {
|
|
2361
|
+
if (output && typeof output === "object" && "imageData" in output && output.imageData) {
|
|
2362
|
+
const result = output;
|
|
2363
|
+
return {
|
|
2364
|
+
type: "content",
|
|
2365
|
+
value: [
|
|
2366
|
+
{ type: "text", text: result.content },
|
|
2367
|
+
{ type: "image-data", data: result.imageData, mediaType: result.mediaType }
|
|
2368
|
+
]
|
|
2369
|
+
};
|
|
2370
|
+
}
|
|
2371
|
+
return typeof output === "string" ? { type: "text", value: output } : { type: "json", value: output };
|
|
2318
2372
|
}
|
|
2319
2373
|
});
|
|
2320
2374
|
}
|
|
@@ -2515,7 +2569,7 @@ function clearCheckpointManager(sessionId) {
|
|
|
2515
2569
|
}
|
|
2516
2570
|
|
|
2517
2571
|
// src/lsp/index.ts
|
|
2518
|
-
import { extname as
|
|
2572
|
+
import { extname as extname3, dirname as dirname4 } from "path";
|
|
2519
2573
|
|
|
2520
2574
|
// src/lsp/servers.ts
|
|
2521
2575
|
import { spawn } from "child_process";
|
|
@@ -2638,9 +2692,9 @@ import {
|
|
|
2638
2692
|
import { pathToFileURL, fileURLToPath } from "url";
|
|
2639
2693
|
import { readFile as readFile4 } from "fs/promises";
|
|
2640
2694
|
import { existsSync as existsSync6 } from "fs";
|
|
2641
|
-
import { extname, normalize } from "path";
|
|
2695
|
+
import { extname as extname2, normalize } from "path";
|
|
2642
2696
|
function getLanguageId(filePath) {
|
|
2643
|
-
const ext =
|
|
2697
|
+
const ext = extname2(filePath).toLowerCase();
|
|
2644
2698
|
const map = {
|
|
2645
2699
|
".ts": "typescript",
|
|
2646
2700
|
".tsx": "typescriptreact",
|
|
@@ -3028,7 +3082,7 @@ var state = {
|
|
|
3028
3082
|
};
|
|
3029
3083
|
async function getClientForFile(filePath) {
|
|
3030
3084
|
const normalized = normalizePath(filePath);
|
|
3031
|
-
const ext =
|
|
3085
|
+
const ext = extname3(normalized);
|
|
3032
3086
|
const serverDef = getServerForExtension(ext);
|
|
3033
3087
|
if (!serverDef) {
|
|
3034
3088
|
return null;
|
|
@@ -3121,7 +3175,7 @@ async function formatDiagnosticsOutput(filePath, options = {}) {
|
|
|
3121
3175
|
return formatDiagnosticsForAgent(filePath, diagnostics, options);
|
|
3122
3176
|
}
|
|
3123
3177
|
function isSupported(filePath) {
|
|
3124
|
-
const ext =
|
|
3178
|
+
const ext = extname3(filePath);
|
|
3125
3179
|
return getServerForExtension(ext) !== null;
|
|
3126
3180
|
}
|
|
3127
3181
|
|
|
@@ -3548,7 +3602,7 @@ Once loaded, a skill's content will be available in the conversation context.`,
|
|
|
3548
3602
|
// src/tools/linter.ts
|
|
3549
3603
|
import { tool as tool6 } from "ai";
|
|
3550
3604
|
import { z as z7 } from "zod";
|
|
3551
|
-
import { resolve as resolve7, relative as relative5, isAbsolute as isAbsolute3, extname as
|
|
3605
|
+
import { resolve as resolve7, relative as relative5, isAbsolute as isAbsolute3, extname as extname5 } from "path";
|
|
3552
3606
|
import { existsSync as existsSync9 } from "fs";
|
|
3553
3607
|
import { readdir as readdir2, stat as stat2 } from "fs/promises";
|
|
3554
3608
|
var linterInputSchema = z7.object({
|
|
@@ -3571,7 +3625,7 @@ async function findSupportedFiles(dir, workingDirectory, maxFiles = 50) {
|
|
|
3571
3625
|
}
|
|
3572
3626
|
await walk(fullPath);
|
|
3573
3627
|
} else if (entry.isFile()) {
|
|
3574
|
-
const ext =
|
|
3628
|
+
const ext = extname5(entry.name);
|
|
3575
3629
|
if (supportedExtensions.includes(ext)) {
|
|
3576
3630
|
files.push(fullPath);
|
|
3577
3631
|
}
|
|
@@ -6395,7 +6449,7 @@ sessions.post("/:id/attachments", async (c) => {
|
|
|
6395
6449
|
}
|
|
6396
6450
|
const dir = ensureAttachmentsDir(sessionId);
|
|
6397
6451
|
const id = nanoid4(10);
|
|
6398
|
-
const ext =
|
|
6452
|
+
const ext = extname7(file.name) || "";
|
|
6399
6453
|
const safeFilename = `${id}_${basename4(file.name).replace(/[^a-zA-Z0-9._-]/g, "_")}`;
|
|
6400
6454
|
const filePath = join5(dir, safeFilename);
|
|
6401
6455
|
const arrayBuffer = await file.arrayBuffer();
|
|
@@ -6421,7 +6475,7 @@ sessions.post("/:id/attachments", async (c) => {
|
|
|
6421
6475
|
}
|
|
6422
6476
|
const dir = ensureAttachmentsDir(sessionId);
|
|
6423
6477
|
const id = nanoid4(10);
|
|
6424
|
-
const ext =
|
|
6478
|
+
const ext = extname7(body.filename) || "";
|
|
6425
6479
|
const safeFilename = `${id}_${basename4(body.filename).replace(/[^a-zA-Z0-9._-]/g, "_")}`;
|
|
6426
6480
|
const filePath = join5(dir, safeFilename);
|
|
6427
6481
|
let base64Data = body.data;
|
|
@@ -6551,7 +6605,7 @@ async function listWorkspaceFiles(baseDir, currentDir, query, limit, results = [
|
|
|
6551
6605
|
if (entry.name.startsWith(".")) {
|
|
6552
6606
|
continue;
|
|
6553
6607
|
}
|
|
6554
|
-
const ext =
|
|
6608
|
+
const ext = extname7(entry.name).toLowerCase();
|
|
6555
6609
|
if (IGNORED_EXTENSIONS.has(ext)) {
|
|
6556
6610
|
continue;
|
|
6557
6611
|
}
|