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/tools/index.js
CHANGED
|
@@ -426,7 +426,7 @@ var init_hasher = __esm({
|
|
|
426
426
|
});
|
|
427
427
|
|
|
428
428
|
// src/semantic/chunker.ts
|
|
429
|
-
import { extname as
|
|
429
|
+
import { extname as extname6, basename as basename2 } from "path";
|
|
430
430
|
var init_chunker = __esm({
|
|
431
431
|
"src/semantic/chunker.ts"() {
|
|
432
432
|
"use strict";
|
|
@@ -1296,26 +1296,41 @@ Terminal output is stored in the global SparkECoder data directory. Use the \`ta
|
|
|
1296
1296
|
import { tool as tool2 } from "ai";
|
|
1297
1297
|
import { z as z3 } from "zod";
|
|
1298
1298
|
import { readFile as readFile2, stat } from "fs/promises";
|
|
1299
|
-
import { resolve as resolve2, relative, isAbsolute } from "path";
|
|
1299
|
+
import { resolve as resolve2, relative, isAbsolute, extname } from "path";
|
|
1300
1300
|
import { existsSync as existsSync3 } from "fs";
|
|
1301
1301
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
1302
|
+
var MAX_IMAGE_SIZE = 20 * 1024 * 1024;
|
|
1302
1303
|
var MAX_OUTPUT_CHARS3 = 5e4;
|
|
1304
|
+
var IMAGE_EXTENSIONS = {
|
|
1305
|
+
".png": "image/png",
|
|
1306
|
+
".jpg": "image/jpeg",
|
|
1307
|
+
".jpeg": "image/jpeg",
|
|
1308
|
+
".gif": "image/gif",
|
|
1309
|
+
".webp": "image/webp"
|
|
1310
|
+
};
|
|
1311
|
+
function isImageFile(filePath) {
|
|
1312
|
+
return extname(filePath).toLowerCase() in IMAGE_EXTENSIONS;
|
|
1313
|
+
}
|
|
1314
|
+
function getImageMediaType(filePath) {
|
|
1315
|
+
return IMAGE_EXTENSIONS[extname(filePath).toLowerCase()] || "image/png";
|
|
1316
|
+
}
|
|
1303
1317
|
var readFileInputSchema = z3.object({
|
|
1304
|
-
path: z3.string().describe("The path to the file to read. Can be relative to working directory or absolute."),
|
|
1305
|
-
startLine: z3.number().optional().describe("Optional: Start reading from this line number (1-indexed)"),
|
|
1306
|
-
endLine: z3.number().optional().describe("Optional: Stop reading at this line number (1-indexed, inclusive)")
|
|
1318
|
+
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)."),
|
|
1319
|
+
startLine: z3.number().optional().describe("Optional: Start reading from this line number (1-indexed). Only for text files."),
|
|
1320
|
+
endLine: z3.number().optional().describe("Optional: Stop reading at this line number (1-indexed, inclusive). Only for text files.")
|
|
1307
1321
|
});
|
|
1308
1322
|
function createReadFileTool(options) {
|
|
1309
1323
|
return tool2({
|
|
1310
1324
|
description: `Read the contents of a file. Provide a path relative to the working directory (${options.workingDirectory}) or an absolute path.
|
|
1311
|
-
|
|
1312
|
-
|
|
1325
|
+
Supports text files (automatically truncated if large) and image files (png, jpg, jpeg, gif, webp).
|
|
1326
|
+
For images, the file contents are returned as visual data you can see and analyze.
|
|
1327
|
+
Use this to understand existing code, check file contents, view screenshots, or gather context.`,
|
|
1313
1328
|
inputSchema: readFileInputSchema,
|
|
1314
|
-
execute: async ({ path, startLine, endLine }) => {
|
|
1329
|
+
execute: async ({ path: filePath, startLine, endLine }) => {
|
|
1315
1330
|
try {
|
|
1316
|
-
const absolutePath = isAbsolute(
|
|
1331
|
+
const absolutePath = isAbsolute(filePath) ? filePath : resolve2(options.workingDirectory, filePath);
|
|
1317
1332
|
const relativePath = relative(options.workingDirectory, absolutePath);
|
|
1318
|
-
if (relativePath.startsWith("..") && !isAbsolute(
|
|
1333
|
+
if (relativePath.startsWith("..") && !isAbsolute(filePath)) {
|
|
1319
1334
|
return {
|
|
1320
1335
|
success: false,
|
|
1321
1336
|
error: "Path escapes the working directory. Use an absolute path if intentional.",
|
|
@@ -1325,22 +1340,43 @@ Use this to understand existing code, check file contents, or gather context.`,
|
|
|
1325
1340
|
if (!existsSync3(absolutePath)) {
|
|
1326
1341
|
return {
|
|
1327
1342
|
success: false,
|
|
1328
|
-
error: `File not found: ${
|
|
1343
|
+
error: `File not found: ${filePath}`,
|
|
1329
1344
|
content: null
|
|
1330
1345
|
};
|
|
1331
1346
|
}
|
|
1332
1347
|
const stats = await stat(absolutePath);
|
|
1333
|
-
if (stats.
|
|
1348
|
+
if (stats.isDirectory()) {
|
|
1334
1349
|
return {
|
|
1335
1350
|
success: false,
|
|
1336
|
-
error:
|
|
1351
|
+
error: 'Path is a directory, not a file. Use bash with "ls" to list directory contents.',
|
|
1337
1352
|
content: null
|
|
1338
1353
|
};
|
|
1339
1354
|
}
|
|
1340
|
-
if (
|
|
1355
|
+
if (isImageFile(absolutePath)) {
|
|
1356
|
+
if (stats.size > MAX_IMAGE_SIZE) {
|
|
1357
|
+
return {
|
|
1358
|
+
success: false,
|
|
1359
|
+
error: `Image is too large (${(stats.size / 1024 / 1024).toFixed(2)}MB). Maximum size is ${MAX_IMAGE_SIZE / 1024 / 1024}MB.`,
|
|
1360
|
+
content: null
|
|
1361
|
+
};
|
|
1362
|
+
}
|
|
1363
|
+
const buffer = await readFile2(absolutePath);
|
|
1364
|
+
const base64 = buffer.toString("base64");
|
|
1365
|
+
const mediaType = getImageMediaType(absolutePath);
|
|
1366
|
+
return {
|
|
1367
|
+
success: true,
|
|
1368
|
+
path: absolutePath,
|
|
1369
|
+
relativePath: relative(options.workingDirectory, absolutePath),
|
|
1370
|
+
content: `[Image: ${relativePath} (${mediaType}, ${(stats.size / 1024).toFixed(1)}KB)]`,
|
|
1371
|
+
mediaType,
|
|
1372
|
+
imageData: base64,
|
|
1373
|
+
sizeBytes: stats.size
|
|
1374
|
+
};
|
|
1375
|
+
}
|
|
1376
|
+
if (stats.size > MAX_FILE_SIZE) {
|
|
1341
1377
|
return {
|
|
1342
1378
|
success: false,
|
|
1343
|
-
error:
|
|
1379
|
+
error: `File is too large (${(stats.size / 1024 / 1024).toFixed(2)}MB). Maximum size is ${MAX_FILE_SIZE / 1024 / 1024}MB.`,
|
|
1344
1380
|
content: null
|
|
1345
1381
|
};
|
|
1346
1382
|
}
|
|
@@ -1356,9 +1392,7 @@ Use this to understand existing code, check file contents, or gather context.`,
|
|
|
1356
1392
|
content: null
|
|
1357
1393
|
};
|
|
1358
1394
|
}
|
|
1359
|
-
content = lines.slice(start, end).join("\n");
|
|
1360
|
-
const lineNumbers = lines.slice(start, end).map((line, idx) => `${(start + idx + 1).toString().padStart(4)}: ${line}`).join("\n");
|
|
1361
|
-
content = lineNumbers;
|
|
1395
|
+
content = lines.slice(start, end).map((line, idx) => `${(start + idx + 1).toString().padStart(4)}: ${line}`).join("\n");
|
|
1362
1396
|
}
|
|
1363
1397
|
const truncatedContent = truncateOutput(content, MAX_OUTPUT_CHARS3);
|
|
1364
1398
|
const wasTruncated = truncatedContent.length < content.length;
|
|
@@ -1385,6 +1419,19 @@ Use this to understand existing code, check file contents, or gather context.`,
|
|
|
1385
1419
|
content: null
|
|
1386
1420
|
};
|
|
1387
1421
|
}
|
|
1422
|
+
},
|
|
1423
|
+
toModelOutput: ({ output }) => {
|
|
1424
|
+
if (output && typeof output === "object" && "imageData" in output && output.imageData) {
|
|
1425
|
+
const result = output;
|
|
1426
|
+
return {
|
|
1427
|
+
type: "content",
|
|
1428
|
+
value: [
|
|
1429
|
+
{ type: "text", text: result.content },
|
|
1430
|
+
{ type: "image-data", data: result.imageData, mediaType: result.mediaType }
|
|
1431
|
+
]
|
|
1432
|
+
};
|
|
1433
|
+
}
|
|
1434
|
+
return typeof output === "string" ? { type: "text", value: output } : { type: "json", value: output };
|
|
1388
1435
|
}
|
|
1389
1436
|
});
|
|
1390
1437
|
}
|
|
@@ -1449,7 +1496,7 @@ async function backupFile(sessionId, workingDirectory, filePath) {
|
|
|
1449
1496
|
}
|
|
1450
1497
|
|
|
1451
1498
|
// src/lsp/index.ts
|
|
1452
|
-
import { extname as
|
|
1499
|
+
import { extname as extname3, dirname as dirname4 } from "path";
|
|
1453
1500
|
|
|
1454
1501
|
// src/lsp/servers.ts
|
|
1455
1502
|
import { spawn } from "child_process";
|
|
@@ -1572,9 +1619,9 @@ import {
|
|
|
1572
1619
|
import { pathToFileURL, fileURLToPath } from "url";
|
|
1573
1620
|
import { readFile as readFile4 } from "fs/promises";
|
|
1574
1621
|
import { existsSync as existsSync6 } from "fs";
|
|
1575
|
-
import { extname, normalize } from "path";
|
|
1622
|
+
import { extname as extname2, normalize } from "path";
|
|
1576
1623
|
function getLanguageId(filePath) {
|
|
1577
|
-
const ext =
|
|
1624
|
+
const ext = extname2(filePath).toLowerCase();
|
|
1578
1625
|
const map = {
|
|
1579
1626
|
".ts": "typescript",
|
|
1580
1627
|
".tsx": "typescriptreact",
|
|
@@ -1962,7 +2009,7 @@ var state = {
|
|
|
1962
2009
|
};
|
|
1963
2010
|
async function getClientForFile(filePath) {
|
|
1964
2011
|
const normalized = normalizePath(filePath);
|
|
1965
|
-
const ext =
|
|
2012
|
+
const ext = extname3(normalized);
|
|
1966
2013
|
const serverDef = getServerForExtension(ext);
|
|
1967
2014
|
if (!serverDef) {
|
|
1968
2015
|
return null;
|
|
@@ -2055,7 +2102,7 @@ async function formatDiagnosticsOutput(filePath, options = {}) {
|
|
|
2055
2102
|
return formatDiagnosticsForAgent(filePath, diagnostics, options);
|
|
2056
2103
|
}
|
|
2057
2104
|
function isSupported(filePath) {
|
|
2058
|
-
const ext =
|
|
2105
|
+
const ext = extname3(filePath);
|
|
2059
2106
|
return getServerForExtension(ext) !== null;
|
|
2060
2107
|
}
|
|
2061
2108
|
|
|
@@ -2402,7 +2449,7 @@ import { z as z6 } from "zod";
|
|
|
2402
2449
|
// src/skills/index.ts
|
|
2403
2450
|
init_types();
|
|
2404
2451
|
import { readFile as readFile6, readdir } from "fs/promises";
|
|
2405
|
-
import { resolve as resolve6, basename, extname as
|
|
2452
|
+
import { resolve as resolve6, basename, extname as extname4, relative as relative4 } from "path";
|
|
2406
2453
|
import { existsSync as existsSync8 } from "fs";
|
|
2407
2454
|
import { minimatch } from "minimatch";
|
|
2408
2455
|
function parseSkillFrontmatter(content) {
|
|
@@ -2473,7 +2520,7 @@ function parseSkillFrontmatter(content) {
|
|
|
2473
2520
|
}
|
|
2474
2521
|
}
|
|
2475
2522
|
function getSkillNameFromPath(filePath) {
|
|
2476
|
-
return basename(filePath,
|
|
2523
|
+
return basename(filePath, extname4(filePath)).replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
2477
2524
|
}
|
|
2478
2525
|
async function loadSkillsFromDirectory(directory, options = {}) {
|
|
2479
2526
|
const {
|
|
@@ -2661,7 +2708,7 @@ Once loaded, a skill's content will be available in the conversation context.`,
|
|
|
2661
2708
|
// src/tools/linter.ts
|
|
2662
2709
|
import { tool as tool6 } from "ai";
|
|
2663
2710
|
import { z as z7 } from "zod";
|
|
2664
|
-
import { resolve as resolve7, relative as relative5, isAbsolute as isAbsolute3, extname as
|
|
2711
|
+
import { resolve as resolve7, relative as relative5, isAbsolute as isAbsolute3, extname as extname5 } from "path";
|
|
2665
2712
|
import { existsSync as existsSync9 } from "fs";
|
|
2666
2713
|
import { readdir as readdir2, stat as stat2 } from "fs/promises";
|
|
2667
2714
|
var linterInputSchema = z7.object({
|
|
@@ -2684,7 +2731,7 @@ async function findSupportedFiles(dir, workingDirectory, maxFiles = 50) {
|
|
|
2684
2731
|
}
|
|
2685
2732
|
await walk(fullPath);
|
|
2686
2733
|
} else if (entry.isFile()) {
|
|
2687
|
-
const ext =
|
|
2734
|
+
const ext = extname5(entry.name);
|
|
2688
2735
|
if (supportedExtensions.includes(ext)) {
|
|
2689
2736
|
files.push(fullPath);
|
|
2690
2737
|
}
|