@myspec/mcp-server 0.1.3-next.41 → 0.1.3
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/index.js +65 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3333,8 +3333,14 @@ var PackCache = class {
|
|
|
3333
3333
|
this.entries.delete(oldestKey);
|
|
3334
3334
|
}
|
|
3335
3335
|
const lines = splitIntoLines(content);
|
|
3336
|
-
const
|
|
3337
|
-
const entry = {
|
|
3336
|
+
const pages = planPages(lines);
|
|
3337
|
+
const entry = {
|
|
3338
|
+
outputId,
|
|
3339
|
+
lines,
|
|
3340
|
+
createdAt: Date.now(),
|
|
3341
|
+
totalPages: pages.length,
|
|
3342
|
+
pages
|
|
3343
|
+
};
|
|
3338
3344
|
this.entries.set(outputId, entry);
|
|
3339
3345
|
return entry;
|
|
3340
3346
|
}
|
|
@@ -3360,6 +3366,56 @@ function splitIntoLines(text) {
|
|
|
3360
3366
|
if (parts.length > 0 && parts[parts.length - 1] === "") parts.pop();
|
|
3361
3367
|
return parts;
|
|
3362
3368
|
}
|
|
3369
|
+
var FILES_OPEN = "<files>";
|
|
3370
|
+
var FILES_CLOSE = "</files>";
|
|
3371
|
+
var FILE_CLOSE = "</file>";
|
|
3372
|
+
function planPages(lines) {
|
|
3373
|
+
if (lines.length === 0) {
|
|
3374
|
+
return [{ start: 0, end: 0 }];
|
|
3375
|
+
}
|
|
3376
|
+
let filesOpenIdx = -1;
|
|
3377
|
+
let filesCloseIdx = -1;
|
|
3378
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
3379
|
+
const t = lines[i]?.trim();
|
|
3380
|
+
if (filesOpenIdx === -1) {
|
|
3381
|
+
if (t === FILES_OPEN) filesOpenIdx = i;
|
|
3382
|
+
} else if (t === FILES_CLOSE) {
|
|
3383
|
+
filesCloseIdx = i;
|
|
3384
|
+
break;
|
|
3385
|
+
}
|
|
3386
|
+
}
|
|
3387
|
+
if (filesOpenIdx !== -1 && filesCloseIdx === -1) filesCloseIdx = lines.length;
|
|
3388
|
+
const insideFiles = (end) => filesOpenIdx !== -1 && filesCloseIdx !== -1 && end > filesOpenIdx && end <= filesCloseIdx;
|
|
3389
|
+
const pages = [];
|
|
3390
|
+
let cursor = 0;
|
|
3391
|
+
while (cursor < lines.length) {
|
|
3392
|
+
let end = Math.min(cursor + PAGE_SIZE_LINES, lines.length);
|
|
3393
|
+
if (end < lines.length && insideFiles(end)) {
|
|
3394
|
+
let back = -1;
|
|
3395
|
+
for (let i = end - 1; i >= cursor; i -= 1) {
|
|
3396
|
+
if (lines[i]?.trim() === FILE_CLOSE) {
|
|
3397
|
+
back = i;
|
|
3398
|
+
break;
|
|
3399
|
+
}
|
|
3400
|
+
}
|
|
3401
|
+
if (back >= cursor) {
|
|
3402
|
+
end = back + 1;
|
|
3403
|
+
} else {
|
|
3404
|
+
let fwd = -1;
|
|
3405
|
+
for (let i = end; i < lines.length; i += 1) {
|
|
3406
|
+
if (lines[i]?.trim() === FILE_CLOSE) {
|
|
3407
|
+
fwd = i;
|
|
3408
|
+
break;
|
|
3409
|
+
}
|
|
3410
|
+
}
|
|
3411
|
+
end = fwd >= 0 ? fwd + 1 : lines.length;
|
|
3412
|
+
}
|
|
3413
|
+
}
|
|
3414
|
+
pages.push({ start: cursor, end });
|
|
3415
|
+
cursor = end;
|
|
3416
|
+
}
|
|
3417
|
+
return pages;
|
|
3418
|
+
}
|
|
3363
3419
|
async function runPack(opts) {
|
|
3364
3420
|
const subpath = opts.args.subpath ?? ".";
|
|
3365
3421
|
const targetDir = await resolveSafePath(opts.realRoot, subpath);
|
|
@@ -3417,18 +3473,17 @@ var InvalidPageError = class extends Error {
|
|
|
3417
3473
|
totalPages;
|
|
3418
3474
|
};
|
|
3419
3475
|
function buildPage(entry, page) {
|
|
3420
|
-
const
|
|
3421
|
-
const
|
|
3422
|
-
const sliceLines = entry.lines.slice(start, end);
|
|
3476
|
+
const plan = entry.pages[page - 1];
|
|
3477
|
+
const body = plan ? entry.lines.slice(plan.start, plan.end) : [];
|
|
3423
3478
|
const hasMore = page < entry.totalPages;
|
|
3424
3479
|
return {
|
|
3425
3480
|
outputId: entry.outputId,
|
|
3426
3481
|
page,
|
|
3427
3482
|
totalPages: entry.totalPages,
|
|
3428
3483
|
totalLines: entry.lines.length,
|
|
3429
|
-
pageLines:
|
|
3484
|
+
pageLines: body.length,
|
|
3430
3485
|
hasMore,
|
|
3431
|
-
content:
|
|
3486
|
+
content: body.join("\n"),
|
|
3432
3487
|
...hasMore && {
|
|
3433
3488
|
nextPage: {
|
|
3434
3489
|
tool: "local_pack_codebase_read_page",
|
|
@@ -3442,7 +3497,7 @@ async function invokeRepomix(exec, targetDir, args, timeoutMs) {
|
|
|
3442
3497
|
const outputFile = join(workDir, "pack.txt");
|
|
3443
3498
|
const options = {
|
|
3444
3499
|
compress: true,
|
|
3445
|
-
style: "
|
|
3500
|
+
style: "xml",
|
|
3446
3501
|
quiet: true,
|
|
3447
3502
|
output: outputFile,
|
|
3448
3503
|
securityCheck: true,
|
|
@@ -3956,7 +4011,7 @@ function registerLocalFsTools(server, opts) {
|
|
|
3956
4011
|
},
|
|
3957
4012
|
{
|
|
3958
4013
|
name: "local_pack_codebase",
|
|
3959
|
-
description: "Pack the entire local codebase (under the granted --root) into a single
|
|
4014
|
+
description: "Pack the entire local codebase (under the granted --root) into a single XML bundle using `npx repomix@latest --style xml --compress`. Prefer this over many `local_fs_read_file` calls when you need broad codebase context. Output is paginated at ~2500 lines per page; a `<file>` block is never split across a page boundary, but the `<files>` root wrapper spans pages (its opener is on the first files page and its closer on the last) \u2014 always keep reading while `hasMore` is true rather than stopping at a `</files>`. The response includes `outputId`, `page`, `totalPages`, `totalLines`, `pageLines`, `hasMore`, and a `nextPage` hint. Use `local_pack_codebase_read_page` to fetch subsequent pages by `outputId`. Repeat calls with the same `subpath`/`includePatterns`/`ignorePatterns` return the same `outputId` and are served instantly from the 30-minute cache without re-running repomix.",
|
|
3960
4015
|
inputSchema: jsonSchemaFromZod(packCodebaseInput),
|
|
3961
4016
|
handler: async (args) => {
|
|
3962
4017
|
try {
|
|
@@ -3969,7 +4024,7 @@ function registerLocalFsTools(server, opts) {
|
|
|
3969
4024
|
},
|
|
3970
4025
|
{
|
|
3971
4026
|
name: "local_pack_codebase_read_page",
|
|
3972
|
-
description: "Read a specific page of a previously packed codebase output. Provide the `outputId` returned by `local_pack_codebase` and the 1-indexed `page` to fetch.
|
|
4027
|
+
description: "Read a specific page of a previously packed codebase output. Provide the `outputId` returned by `local_pack_codebase` and the 1-indexed `page` to fetch. Each page is up to ~2500 lines of XML; no `<file>` block is split across pages, but the `<files>` root wrapper spans pages \u2014 keep fetching while `hasMore` is true, do not stop at a `</files>`. Cache entries expire after 30 minutes; on cache miss, re-run `local_pack_codebase` (same args return the same outputId \u2014 re-pack is cheap, served from cache).",
|
|
3973
4028
|
inputSchema: jsonSchemaFromZod(packCodebaseReadPageInput),
|
|
3974
4029
|
handler: (args) => {
|
|
3975
4030
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myspec/mcp-server",
|
|
3
|
-
"version": "0.1.3
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "MySpec MCP server — exposes MySpec platform projects, files and attachments to MCP-aware clients via OAuth-authenticated access tokens.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|