@lousy-agents/mcp 5.18.1 → 5.19.0
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/mcp-server.js +166 -137
- package/package.json +3 -2
package/dist/mcp-server.js
CHANGED
|
@@ -34967,8 +34967,9 @@ async function readVersionFileContent(targetDir, relativePath) {
|
|
|
34967
34967
|
continue;
|
|
34968
34968
|
}
|
|
34969
34969
|
if (await file_system_utils_pathExistsWithinRoot(targetDir, pmConfig.manifestFile)) {
|
|
34970
|
-
const
|
|
34971
|
-
const
|
|
34970
|
+
const { lockfile } = pmConfig;
|
|
34971
|
+
const lockfilePath = lockfile ? await file_system_utils_resolveSafePath(targetDir, lockfile) : undefined;
|
|
34972
|
+
const hasLockfile = lockfilePath && lockfile ? await file_system_utils_pathExistsWithinRoot(targetDir, lockfile) : false;
|
|
34972
34973
|
if (pmConfig.requiresLockfile && !hasLockfile) {
|
|
34973
34974
|
continue;
|
|
34974
34975
|
}
|
|
@@ -34985,8 +34986,9 @@ async function readVersionFileContent(targetDir, relativePath) {
|
|
|
34985
34986
|
const packageManagers = [];
|
|
34986
34987
|
for (const pmConfig of otherPackageManagers){
|
|
34987
34988
|
if (await file_system_utils_pathExistsWithinRoot(targetDir, pmConfig.manifestFile)) {
|
|
34988
|
-
const
|
|
34989
|
-
const
|
|
34989
|
+
const { lockfile } = pmConfig;
|
|
34990
|
+
const lockfilePath = lockfile ? await file_system_utils_resolveSafePath(targetDir, lockfile) : undefined;
|
|
34991
|
+
const hasLockfile = lockfilePath && lockfile ? await file_system_utils_pathExistsWithinRoot(targetDir, lockfile) : false;
|
|
34990
34992
|
if (pmConfig.requiresLockfile && !hasLockfile) {
|
|
34991
34993
|
continue;
|
|
34992
34994
|
}
|
|
@@ -35148,11 +35150,18 @@ function defaultExec(command, args, options) {
|
|
|
35148
35150
|
throw new Error("Not authenticated");
|
|
35149
35151
|
}
|
|
35150
35152
|
try {
|
|
35151
|
-
|
|
35153
|
+
const params = {
|
|
35152
35154
|
owner,
|
|
35153
35155
|
repo,
|
|
35154
|
-
|
|
35155
|
-
|
|
35156
|
+
name: payload.name,
|
|
35157
|
+
enforcement: payload.enforcement,
|
|
35158
|
+
target: payload.target,
|
|
35159
|
+
// biome-ignore lint/style/useNamingConvention: GitHub API schema requires snake_case
|
|
35160
|
+
bypass_actors: payload.bypass_actors,
|
|
35161
|
+
conditions: payload.conditions,
|
|
35162
|
+
rules: payload.rules
|
|
35163
|
+
};
|
|
35164
|
+
await this.octokit.rest.repos.createRepoRuleset(params);
|
|
35156
35165
|
} catch (error) {
|
|
35157
35166
|
const details = formatOctokitError(error);
|
|
35158
35167
|
throw new Error(`Failed to create ruleset for ${owner}/${repo}: ${details}`);
|
|
@@ -37626,13 +37635,13 @@ const PackageJsonSchema = schemas_object({
|
|
|
37626
37635
|
"shared"
|
|
37627
37636
|
]
|
|
37628
37637
|
},
|
|
37629
|
-
//
|
|
37638
|
+
// Additional skill roots (SKILL.md convention, no alternate layout documented)
|
|
37630
37639
|
{
|
|
37631
37640
|
id: "skill-pi",
|
|
37632
37641
|
path: ".pi/skills",
|
|
37633
37642
|
matchKind: "directory-prefix",
|
|
37634
37643
|
primaryConstruct: "skill",
|
|
37635
|
-
lintTarget: "
|
|
37644
|
+
lintTarget: "skills",
|
|
37636
37645
|
harnessHints: [
|
|
37637
37646
|
"pi"
|
|
37638
37647
|
]
|
|
@@ -37642,7 +37651,7 @@ const PackageJsonSchema = schemas_object({
|
|
|
37642
37651
|
path: ".pi/prompts",
|
|
37643
37652
|
matchKind: "directory-prefix",
|
|
37644
37653
|
primaryConstruct: "skill",
|
|
37645
|
-
lintTarget: "
|
|
37654
|
+
lintTarget: "skills",
|
|
37646
37655
|
harnessHints: [
|
|
37647
37656
|
"pi"
|
|
37648
37657
|
]
|
|
@@ -37762,13 +37771,13 @@ const PackageJsonSchema = schemas_object({
|
|
|
37762
37771
|
],
|
|
37763
37772
|
instructionFormat: "claude-md"
|
|
37764
37773
|
},
|
|
37765
|
-
//
|
|
37774
|
+
// Subagent lint root
|
|
37766
37775
|
{
|
|
37767
37776
|
id: "subagent-claude",
|
|
37768
37777
|
path: ".claude/agents",
|
|
37769
37778
|
matchKind: "directory-prefix",
|
|
37770
37779
|
primaryConstruct: "subagent",
|
|
37771
|
-
lintTarget: "
|
|
37780
|
+
lintTarget: "subagents",
|
|
37772
37781
|
harnessHints: [
|
|
37773
37782
|
"claude"
|
|
37774
37783
|
]
|
|
@@ -37804,11 +37813,14 @@ const PackageJsonSchema = schemas_object({
|
|
|
37804
37813
|
* Normalizes a repo-relative path for catalog matching.
|
|
37805
37814
|
* Collapses `.` / `..` segments. Returns "" when the path is absolute or
|
|
37806
37815
|
* escapes the repository root — callers treat "" as non-matching.
|
|
37807
|
-
*/ function
|
|
37808
|
-
const normalized = path.replaceAll("\\", "/");
|
|
37816
|
+
*/ function isAbsoluteRepoPath(normalized) {
|
|
37809
37817
|
// POSIX absolute, UNC-style leading slash after backslash conversion,
|
|
37810
37818
|
// and Windows drive-letter absolute (C:/..., d:\...).
|
|
37811
|
-
|
|
37819
|
+
return normalized.startsWith("/") || /^[A-Za-z]:(\/|$)/.test(normalized);
|
|
37820
|
+
}
|
|
37821
|
+
function normalizeRepoRelativePath(path) {
|
|
37822
|
+
const normalized = path.replaceAll("\\", "/");
|
|
37823
|
+
if (isAbsoluteRepoPath(normalized)) {
|
|
37812
37824
|
return "";
|
|
37813
37825
|
}
|
|
37814
37826
|
const resolved = [];
|
|
@@ -37816,10 +37828,10 @@ const PackageJsonSchema = schemas_object({
|
|
|
37816
37828
|
if (segment === "" || segment === ".") {
|
|
37817
37829
|
continue;
|
|
37818
37830
|
}
|
|
37831
|
+
if (segment === ".." && resolved.length === 0) {
|
|
37832
|
+
return "";
|
|
37833
|
+
}
|
|
37819
37834
|
if (segment === "..") {
|
|
37820
|
-
if (resolved.length === 0) {
|
|
37821
|
-
return "";
|
|
37822
|
-
}
|
|
37823
37835
|
resolved.pop();
|
|
37824
37836
|
continue;
|
|
37825
37837
|
}
|
|
@@ -37867,14 +37879,15 @@ function constructTypesForPath(path, catalog = AGENTIC_LOCATION_CATALOG) {
|
|
|
37867
37879
|
if (!best) {
|
|
37868
37880
|
return [];
|
|
37869
37881
|
}
|
|
37870
|
-
|
|
37882
|
+
const secondary = best.secondaryConstructs ?? [];
|
|
37883
|
+
if (secondary.length === 0) {
|
|
37871
37884
|
return [
|
|
37872
|
-
best.primaryConstruct
|
|
37873
|
-
...best.secondaryConstructs
|
|
37885
|
+
best.primaryConstruct
|
|
37874
37886
|
];
|
|
37875
37887
|
}
|
|
37876
37888
|
return [
|
|
37877
|
-
best.primaryConstruct
|
|
37889
|
+
best.primaryConstruct,
|
|
37890
|
+
...secondary
|
|
37878
37891
|
];
|
|
37879
37892
|
}
|
|
37880
37893
|
function lintTargetEntries(target, catalog = agentic_location_catalog_AGENTIC_LOCATION_CATALOG) {
|
|
@@ -37886,8 +37899,14 @@ function skillDirectoryRoots(catalog = agentic_location_catalog_AGENTIC_LOCATION
|
|
|
37886
37899
|
function agentDirectoryRoots(catalog = AGENTIC_LOCATION_CATALOG) {
|
|
37887
37900
|
return lintTargetEntries("agents", catalog).filter((entry)=>entry.matchKind === "directory-prefix").map((entry)=>entry.path);
|
|
37888
37901
|
}
|
|
37902
|
+
function subagentDirectoryRoots(catalog = AGENTIC_LOCATION_CATALOG) {
|
|
37903
|
+
return lintTargetEntries("subagents", catalog).filter((entry)=>entry.matchKind === "directory-prefix").map((entry)=>entry.path);
|
|
37904
|
+
}
|
|
37905
|
+
function isHookConfigEntry(entry) {
|
|
37906
|
+
return entry.matchKind === "exact" && entry.hookPlatform != null;
|
|
37907
|
+
}
|
|
37889
37908
|
function hookConfigPaths(catalog = AGENTIC_LOCATION_CATALOG) {
|
|
37890
|
-
return lintTargetEntries("hooks", catalog).filter(
|
|
37909
|
+
return lintTargetEntries("hooks", catalog).filter(isHookConfigEntry).map((entry)=>({
|
|
37891
37910
|
relativePath: entry.path,
|
|
37892
37911
|
platform: entry.hookPlatform
|
|
37893
37912
|
}));
|
|
@@ -57474,120 +57493,6 @@ function lib_isUint8Array(value) {
|
|
|
57474
57493
|
*/
|
|
57475
57494
|
const remark = unified().use(remarkParse).use(remarkStringify).freeze()
|
|
57476
57495
|
|
|
57477
|
-
;// CONCATENATED MODULE: ../core/src/gateways/markdown-ast-gateway.ts
|
|
57478
|
-
/**
|
|
57479
|
-
* Gateway for parsing Markdown files into AST using remark.
|
|
57480
|
-
* Extracts structural features like headings, code blocks, and paragraphs.
|
|
57481
|
-
*/
|
|
57482
|
-
|
|
57483
|
-
|
|
57484
|
-
/** Maximum instruction file size: 1 MB */ const markdown_ast_gateway_MAX_INSTRUCTION_FILE_BYTES = 1_048_576;
|
|
57485
|
-
/**
|
|
57486
|
-
* Remark-based implementation of the Markdown AST gateway.
|
|
57487
|
-
*/ class RemarkMarkdownAstGateway {
|
|
57488
|
-
async parseFile(filePath) {
|
|
57489
|
-
const content = await read_file_no_follow_readFileNoFollow(filePath, markdown_ast_gateway_MAX_INSTRUCTION_FILE_BYTES);
|
|
57490
|
-
return this.parseContent(content);
|
|
57491
|
-
}
|
|
57492
|
-
parseContent(content) {
|
|
57493
|
-
const processor = remark();
|
|
57494
|
-
const ast = processor.parse(content);
|
|
57495
|
-
const headings = [];
|
|
57496
|
-
const codeBlocks = [];
|
|
57497
|
-
const inlineCodes = [];
|
|
57498
|
-
lib_visit(ast, "heading", (node)=>{
|
|
57499
|
-
const text = this.extractHeadingText(node);
|
|
57500
|
-
headings.push({
|
|
57501
|
-
text,
|
|
57502
|
-
depth: node.depth,
|
|
57503
|
-
position: {
|
|
57504
|
-
line: node.position?.start.line ?? 0
|
|
57505
|
-
}
|
|
57506
|
-
});
|
|
57507
|
-
});
|
|
57508
|
-
// Track code blocks with their node index in root children
|
|
57509
|
-
for(let i = 0; i < ast.children.length; i++){
|
|
57510
|
-
const child = ast.children[i];
|
|
57511
|
-
if (child.type === "code") {
|
|
57512
|
-
const codeNode = child;
|
|
57513
|
-
codeBlocks.push({
|
|
57514
|
-
value: codeNode.value,
|
|
57515
|
-
lang: codeNode.lang ?? undefined,
|
|
57516
|
-
position: {
|
|
57517
|
-
line: codeNode.position?.start.line ?? 0
|
|
57518
|
-
},
|
|
57519
|
-
nodeIndex: i
|
|
57520
|
-
});
|
|
57521
|
-
}
|
|
57522
|
-
}
|
|
57523
|
-
lib_visit(ast, "inlineCode", (node)=>{
|
|
57524
|
-
inlineCodes.push({
|
|
57525
|
-
value: node.value,
|
|
57526
|
-
position: {
|
|
57527
|
-
line: node.position?.start.line ?? 0
|
|
57528
|
-
}
|
|
57529
|
-
});
|
|
57530
|
-
});
|
|
57531
|
-
return {
|
|
57532
|
-
headings,
|
|
57533
|
-
codeBlocks,
|
|
57534
|
-
inlineCodes,
|
|
57535
|
-
ast
|
|
57536
|
-
};
|
|
57537
|
-
}
|
|
57538
|
-
findConditionalKeywordsInProximity(structure, codeBlockNodeIndex, proximityWindow, keywords) {
|
|
57539
|
-
const ast = structure.ast;
|
|
57540
|
-
const endIndex = Math.min(ast.children.length, codeBlockNodeIndex + 1 + proximityWindow);
|
|
57541
|
-
for(let i = codeBlockNodeIndex + 1; i < endIndex; i++){
|
|
57542
|
-
const sibling = ast.children[i];
|
|
57543
|
-
const text = extractTextFromNode(sibling);
|
|
57544
|
-
const lowerText = text.toLowerCase();
|
|
57545
|
-
for (const keyword of keywords){
|
|
57546
|
-
if (containsWordBoundary(lowerText, keyword.toLowerCase())) {
|
|
57547
|
-
return true;
|
|
57548
|
-
}
|
|
57549
|
-
}
|
|
57550
|
-
}
|
|
57551
|
-
return false;
|
|
57552
|
-
}
|
|
57553
|
-
extractHeadingText(node) {
|
|
57554
|
-
const parts = [];
|
|
57555
|
-
lib_visit(node, "text", (textNode)=>{
|
|
57556
|
-
parts.push(textNode.value);
|
|
57557
|
-
});
|
|
57558
|
-
return parts.join("");
|
|
57559
|
-
}
|
|
57560
|
-
}
|
|
57561
|
-
/**
|
|
57562
|
-
* Checks if text contains a keyword at a word boundary (safe string matching, no regex).
|
|
57563
|
-
*/ function containsWordBoundary(text, keyword) {
|
|
57564
|
-
const index = text.indexOf(keyword);
|
|
57565
|
-
if (index === -1) {
|
|
57566
|
-
return false;
|
|
57567
|
-
}
|
|
57568
|
-
const charBefore = index > 0 ? text[index - 1] : " ";
|
|
57569
|
-
const charAfter = index + keyword.length < text.length ? text[index + keyword.length] : " ";
|
|
57570
|
-
const isWordBoundaryBefore = !/[a-z0-9]/i.test(charBefore);
|
|
57571
|
-
const isWordBoundaryAfter = !/[a-z0-9]/i.test(charAfter);
|
|
57572
|
-
return isWordBoundaryBefore && isWordBoundaryAfter;
|
|
57573
|
-
}
|
|
57574
|
-
/**
|
|
57575
|
-
* Extracts plain text content from any AST node recursively.
|
|
57576
|
-
*/ function extractTextFromNode(node) {
|
|
57577
|
-
if (node.value && typeof node.value === "string") {
|
|
57578
|
-
return node.value;
|
|
57579
|
-
}
|
|
57580
|
-
if (Array.isArray(node.children)) {
|
|
57581
|
-
return node.children.map((child)=>extractTextFromNode(child)).join(" ");
|
|
57582
|
-
}
|
|
57583
|
-
return "";
|
|
57584
|
-
}
|
|
57585
|
-
/**
|
|
57586
|
-
* Creates and returns the default Markdown AST gateway.
|
|
57587
|
-
*/ function createMarkdownAstGateway() {
|
|
57588
|
-
return new RemarkMarkdownAstGateway();
|
|
57589
|
-
}
|
|
57590
|
-
|
|
57591
57496
|
;// CONCATENATED MODULE: ../core/src/entities/instruction-quality.ts
|
|
57592
57497
|
/**
|
|
57593
57498
|
* Core domain entities for instruction quality analysis.
|
|
@@ -57639,6 +57544,9 @@ const HEADING_PATTERN_DESCRIPTIONS = new Map(Object.entries(HEADING_PATTERN_DESC
|
|
|
57639
57544
|
* Orchestrates discovery, AST parsing, and scoring of feedback loop documentation.
|
|
57640
57545
|
*/
|
|
57641
57546
|
|
|
57547
|
+
/** Type guard narrowing an `unknown` AST child to {@link AstNodeLike}. */ function isAstNodeLike(node) {
|
|
57548
|
+
return typeof node === "object" && node !== null && "type" in node && typeof node.type === "string";
|
|
57549
|
+
}
|
|
57642
57550
|
/** Maximum number of raw heading pattern entries accepted before deduplication. */ const MAX_RAW_HEADING_PATTERNS = 1000;
|
|
57643
57551
|
/** Maximum number of heading patterns accepted in a single execute() call. */ const MAX_HEADING_PATTERNS = 50;
|
|
57644
57552
|
/** Maximum character length for a single heading pattern. */ const analyze_instruction_quality_MAX_PATTERN_LENGTH = 200;
|
|
@@ -57994,6 +57902,9 @@ const HEADING_PATTERN_DESCRIPTIONS = new Map(Object.entries(HEADING_PATTERN_DESC
|
|
|
57994
57902
|
return parts.join(" ");
|
|
57995
57903
|
}
|
|
57996
57904
|
collectText(node, parts) {
|
|
57905
|
+
if (!isAstNodeLike(node)) {
|
|
57906
|
+
return;
|
|
57907
|
+
}
|
|
57997
57908
|
if (node.type === "text" && typeof node.value === "string") {
|
|
57998
57909
|
parts.push(node.value);
|
|
57999
57910
|
}
|
|
@@ -58140,6 +58051,124 @@ const HEADING_PATTERN_DESCRIPTIONS = new Map(Object.entries(HEADING_PATTERN_DESC
|
|
|
58140
58051
|
}
|
|
58141
58052
|
}
|
|
58142
58053
|
|
|
58054
|
+
;// CONCATENATED MODULE: ../core/src/gateways/markdown-ast-gateway.ts
|
|
58055
|
+
/**
|
|
58056
|
+
* Gateway for parsing Markdown files into AST using remark.
|
|
58057
|
+
* Extracts structural features like headings, code blocks, and paragraphs.
|
|
58058
|
+
*/
|
|
58059
|
+
|
|
58060
|
+
|
|
58061
|
+
|
|
58062
|
+
/** Maximum instruction file size: 1 MB */ const markdown_ast_gateway_MAX_INSTRUCTION_FILE_BYTES = 1_048_576;
|
|
58063
|
+
/**
|
|
58064
|
+
* Remark-based implementation of the Markdown AST gateway.
|
|
58065
|
+
*/ class RemarkMarkdownAstGateway {
|
|
58066
|
+
async parseFile(filePath) {
|
|
58067
|
+
const content = await read_file_no_follow_readFileNoFollow(filePath, markdown_ast_gateway_MAX_INSTRUCTION_FILE_BYTES);
|
|
58068
|
+
return this.parseContent(content);
|
|
58069
|
+
}
|
|
58070
|
+
parseContent(content) {
|
|
58071
|
+
const processor = remark();
|
|
58072
|
+
const ast = processor.parse(content);
|
|
58073
|
+
const headings = [];
|
|
58074
|
+
const codeBlocks = [];
|
|
58075
|
+
const inlineCodes = [];
|
|
58076
|
+
lib_visit(ast, "heading", (node)=>{
|
|
58077
|
+
const text = this.extractHeadingText(node);
|
|
58078
|
+
headings.push({
|
|
58079
|
+
text,
|
|
58080
|
+
depth: node.depth,
|
|
58081
|
+
position: {
|
|
58082
|
+
line: node.position?.start.line ?? 0
|
|
58083
|
+
}
|
|
58084
|
+
});
|
|
58085
|
+
});
|
|
58086
|
+
// Track code blocks with their node index in root children
|
|
58087
|
+
for(let i = 0; i < ast.children.length; i++){
|
|
58088
|
+
const child = ast.children[i];
|
|
58089
|
+
if (child.type === "code") {
|
|
58090
|
+
const codeNode = child;
|
|
58091
|
+
codeBlocks.push({
|
|
58092
|
+
value: codeNode.value,
|
|
58093
|
+
lang: codeNode.lang ?? undefined,
|
|
58094
|
+
position: {
|
|
58095
|
+
line: codeNode.position?.start.line ?? 0
|
|
58096
|
+
},
|
|
58097
|
+
nodeIndex: i
|
|
58098
|
+
});
|
|
58099
|
+
}
|
|
58100
|
+
}
|
|
58101
|
+
lib_visit(ast, "inlineCode", (node)=>{
|
|
58102
|
+
inlineCodes.push({
|
|
58103
|
+
value: node.value,
|
|
58104
|
+
position: {
|
|
58105
|
+
line: node.position?.start.line ?? 0
|
|
58106
|
+
}
|
|
58107
|
+
});
|
|
58108
|
+
});
|
|
58109
|
+
return {
|
|
58110
|
+
headings,
|
|
58111
|
+
codeBlocks,
|
|
58112
|
+
inlineCodes,
|
|
58113
|
+
ast
|
|
58114
|
+
};
|
|
58115
|
+
}
|
|
58116
|
+
findConditionalKeywordsInProximity(structure, codeBlockNodeIndex, proximityWindow, keywords) {
|
|
58117
|
+
const ast = structure.ast;
|
|
58118
|
+
const endIndex = Math.min(ast.children.length, codeBlockNodeIndex + 1 + proximityWindow);
|
|
58119
|
+
for(let i = codeBlockNodeIndex + 1; i < endIndex; i++){
|
|
58120
|
+
const sibling = ast.children[i];
|
|
58121
|
+
const text = extractTextFromNode(sibling);
|
|
58122
|
+
const lowerText = text.toLowerCase();
|
|
58123
|
+
for (const keyword of keywords){
|
|
58124
|
+
if (containsWordBoundary(lowerText, keyword.toLowerCase())) {
|
|
58125
|
+
return true;
|
|
58126
|
+
}
|
|
58127
|
+
}
|
|
58128
|
+
}
|
|
58129
|
+
return false;
|
|
58130
|
+
}
|
|
58131
|
+
extractHeadingText(node) {
|
|
58132
|
+
const parts = [];
|
|
58133
|
+
lib_visit(node, "text", (textNode)=>{
|
|
58134
|
+
parts.push(textNode.value);
|
|
58135
|
+
});
|
|
58136
|
+
return parts.join("");
|
|
58137
|
+
}
|
|
58138
|
+
}
|
|
58139
|
+
/**
|
|
58140
|
+
* Checks if text contains a keyword at a word boundary (safe string matching, no regex).
|
|
58141
|
+
*/ function containsWordBoundary(text, keyword) {
|
|
58142
|
+
const index = text.indexOf(keyword);
|
|
58143
|
+
if (index === -1) {
|
|
58144
|
+
return false;
|
|
58145
|
+
}
|
|
58146
|
+
const charBefore = index > 0 ? text[index - 1] : " ";
|
|
58147
|
+
const charAfter = index + keyword.length < text.length ? text[index + keyword.length] : " ";
|
|
58148
|
+
const isWordBoundaryBefore = !/[a-z0-9]/i.test(charBefore);
|
|
58149
|
+
const isWordBoundaryAfter = !/[a-z0-9]/i.test(charAfter);
|
|
58150
|
+
return isWordBoundaryBefore && isWordBoundaryAfter;
|
|
58151
|
+
}
|
|
58152
|
+
/**
|
|
58153
|
+
* Extracts plain text content from any AST node recursively.
|
|
58154
|
+
*/ function extractTextFromNode(node) {
|
|
58155
|
+
if (!isAstNodeLike(node)) {
|
|
58156
|
+
return "";
|
|
58157
|
+
}
|
|
58158
|
+
if (node.value && typeof node.value === "string") {
|
|
58159
|
+
return node.value;
|
|
58160
|
+
}
|
|
58161
|
+
if (Array.isArray(node.children)) {
|
|
58162
|
+
return node.children.map((child)=>extractTextFromNode(child)).join(" ");
|
|
58163
|
+
}
|
|
58164
|
+
return "";
|
|
58165
|
+
}
|
|
58166
|
+
/**
|
|
58167
|
+
* Creates and returns the default Markdown AST gateway.
|
|
58168
|
+
*/ function createMarkdownAstGateway() {
|
|
58169
|
+
return new RemarkMarkdownAstGateway();
|
|
58170
|
+
}
|
|
58171
|
+
|
|
58143
58172
|
;// CONCATENATED MODULE: ./src/tools/analyze-instruction-quality.ts
|
|
58144
58173
|
/**
|
|
58145
58174
|
* MCP tool handler for analyzing instruction quality.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lousy-agents/mcp",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.19.0",
|
|
4
4
|
"description": "MCP server for lousy-agents - provides AI coding assistant tools via the Model Context Protocol",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"lousy-agents-mcp": "dist/mcp-server.js"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
|
-
"build": "rspack build --config rspack.config.ts && chmod +x dist/mcp-server.js"
|
|
36
|
+
"build": "rspack build --config rspack.config.ts && chmod +x dist/mcp-server.js",
|
|
37
|
+
"typecheck": "tsc --noEmit"
|
|
37
38
|
},
|
|
38
39
|
"dependencies": {
|
|
39
40
|
"@modelcontextprotocol/sdk": "1.30.0",
|