invar-tools 1.17.6__py3-none-any.whl → 1.17.8__py3-none-any.whl
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.
- invar/mcp/handlers.py +23 -28
- invar/node_tools/eslint-plugin/rules/require-jsdoc-example.js +25 -0
- invar/node_tools/eslint-plugin/rules/require-jsdoc-example.js.map +1 -1
- invar/node_tools/fc-runner/cli.js +45 -117
- invar/shell/commands/guard.py +69 -59
- {invar_tools-1.17.6.dist-info → invar_tools-1.17.8.dist-info}/METADATA +1 -1
- {invar_tools-1.17.6.dist-info → invar_tools-1.17.8.dist-info}/RECORD +12 -12
- {invar_tools-1.17.6.dist-info → invar_tools-1.17.8.dist-info}/WHEEL +0 -0
- {invar_tools-1.17.6.dist-info → invar_tools-1.17.8.dist-info}/entry_points.txt +0 -0
- {invar_tools-1.17.6.dist-info → invar_tools-1.17.8.dist-info}/licenses/LICENSE +0 -0
- {invar_tools-1.17.6.dist-info → invar_tools-1.17.8.dist-info}/licenses/LICENSE-GPL +0 -0
- {invar_tools-1.17.6.dist-info → invar_tools-1.17.8.dist-info}/licenses/NOTICE +0 -0
invar/mcp/handlers.py
CHANGED
|
@@ -13,6 +13,7 @@ import sys
|
|
|
13
13
|
from pathlib import Path
|
|
14
14
|
from typing import Any, Literal
|
|
15
15
|
|
|
16
|
+
from mcp.server.lowlevel.server import StructuredContent, CombinationContent
|
|
16
17
|
from mcp.types import TextContent
|
|
17
18
|
from returns.result import Success
|
|
18
19
|
|
|
@@ -59,7 +60,7 @@ def _validate_path(path: str) -> tuple[bool, str]:
|
|
|
59
60
|
# @shell_orchestration: MCP handler - subprocess is called inside
|
|
60
61
|
# @shell_complexity: Guard command with multiple optional flags
|
|
61
62
|
# @invar:allow shell_result: MCP handler for guard tool
|
|
62
|
-
async def _run_guard(args: dict[str, Any]) -> list[TextContent]:
|
|
63
|
+
async def _run_guard(args: dict[str, Any]) -> list[TextContent] | CombinationContent:
|
|
63
64
|
"""Run invar guard command."""
|
|
64
65
|
path = args.get("path", ".")
|
|
65
66
|
is_valid, error = _validate_path(path)
|
|
@@ -88,7 +89,7 @@ async def _run_guard(args: dict[str, Any]) -> list[TextContent]:
|
|
|
88
89
|
|
|
89
90
|
# @shell_orchestration: MCP handler - subprocess is called inside
|
|
90
91
|
# @invar:allow shell_result: MCP handler for sig tool
|
|
91
|
-
async def _run_sig(args: dict[str, Any]) -> list[TextContent]:
|
|
92
|
+
async def _run_sig(args: dict[str, Any]) -> list[TextContent] | CombinationContent:
|
|
92
93
|
"""Run invar sig command."""
|
|
93
94
|
target = args.get("target", "")
|
|
94
95
|
if not target:
|
|
@@ -106,7 +107,7 @@ async def _run_sig(args: dict[str, Any]) -> list[TextContent]:
|
|
|
106
107
|
|
|
107
108
|
# @shell_orchestration: MCP handler - subprocess is called inside
|
|
108
109
|
# @invar:allow shell_result: MCP handler for map tool
|
|
109
|
-
async def _run_map(args: dict[str, Any]) -> list[TextContent]:
|
|
110
|
+
async def _run_map(args: dict[str, Any]) -> list[TextContent] | CombinationContent:
|
|
110
111
|
"""Run invar map command."""
|
|
111
112
|
path = args.get("path", ".")
|
|
112
113
|
is_valid, error = _validate_path(path)
|
|
@@ -125,7 +126,7 @@ async def _run_map(args: dict[str, Any]) -> list[TextContent]:
|
|
|
125
126
|
|
|
126
127
|
# @shell_orchestration: MCP handler - orchestrates refs command execution
|
|
127
128
|
# @invar:allow shell_result: MCP handler for refs tool
|
|
128
|
-
async def _run_refs(args: dict[str, Any]) -> list[TextContent]:
|
|
129
|
+
async def _run_refs(args: dict[str, Any]) -> list[TextContent] | CombinationContent:
|
|
129
130
|
"""Run invar refs command.
|
|
130
131
|
|
|
131
132
|
DX-78: Find all references to a symbol.
|
|
@@ -155,7 +156,7 @@ async def _run_refs(args: dict[str, Any]) -> list[TextContent]:
|
|
|
155
156
|
# @shell_orchestration: MCP handler - calls shell layer directly
|
|
156
157
|
# @shell_complexity: MCP input validation + result handling
|
|
157
158
|
# @invar:allow shell_result: MCP handler for doc_toc tool
|
|
158
|
-
async def _run_doc_toc(args: dict[str, Any]) -> list[TextContent]:
|
|
159
|
+
async def _run_doc_toc(args: dict[str, Any]) -> list[TextContent] | CombinationContent:
|
|
159
160
|
"""Run invar_doc_toc - extract document structure."""
|
|
160
161
|
from dataclasses import asdict
|
|
161
162
|
|
|
@@ -203,7 +204,7 @@ def _section_to_dict(section: Any) -> dict[str, Any]:
|
|
|
203
204
|
# @shell_orchestration: MCP handler - calls shell layer directly
|
|
204
205
|
# @shell_complexity: MCP input validation + result handling
|
|
205
206
|
# @invar:allow shell_result: MCP handler for doc_read tool
|
|
206
|
-
async def _run_doc_read(args: dict[str, Any]) -> list[TextContent]:
|
|
207
|
+
async def _run_doc_read(args: dict[str, Any]) -> list[TextContent] | CombinationContent:
|
|
207
208
|
"""Run invar_doc_read - read a specific section."""
|
|
208
209
|
from invar.shell.doc_tools import read_section
|
|
209
210
|
|
|
@@ -232,7 +233,7 @@ async def _run_doc_read(args: dict[str, Any]) -> list[TextContent]:
|
|
|
232
233
|
|
|
233
234
|
# @shell_complexity: Multiple arg validation branches + error handling
|
|
234
235
|
# @invar:allow shell_result: MCP handler for doc_read_many tool
|
|
235
|
-
async def _run_doc_read_many(args: dict[str, Any]) -> list[TextContent]:
|
|
236
|
+
async def _run_doc_read_many(args: dict[str, Any]) -> list[TextContent] | CombinationContent:
|
|
236
237
|
"""Run invar_doc_read_many - read multiple sections."""
|
|
237
238
|
from invar.shell.doc_tools import read_sections_batch
|
|
238
239
|
|
|
@@ -264,7 +265,7 @@ async def _run_doc_read_many(args: dict[str, Any]) -> list[TextContent]:
|
|
|
264
265
|
# @shell_orchestration: MCP handler - calls shell layer directly
|
|
265
266
|
# @shell_complexity: MCP input validation + result handling
|
|
266
267
|
# @invar:allow shell_result: MCP handler for doc_find tool
|
|
267
|
-
async def _run_doc_find(args: dict[str, Any]) -> list[TextContent]:
|
|
268
|
+
async def _run_doc_find(args: dict[str, Any]) -> list[TextContent] | CombinationContent:
|
|
268
269
|
"""Run invar_doc_find - find sections matching pattern."""
|
|
269
270
|
from invar.shell.doc_tools import find_sections
|
|
270
271
|
|
|
@@ -308,7 +309,7 @@ async def _run_doc_find(args: dict[str, Any]) -> list[TextContent]:
|
|
|
308
309
|
# @shell_orchestration: MCP handler - calls shell layer directly
|
|
309
310
|
# @shell_complexity: MCP input validation + result handling
|
|
310
311
|
# @invar:allow shell_result: MCP handler for doc_replace tool
|
|
311
|
-
async def _run_doc_replace(args: dict[str, Any]) -> list[TextContent]:
|
|
312
|
+
async def _run_doc_replace(args: dict[str, Any]) -> list[TextContent] | CombinationContent:
|
|
312
313
|
"""Run invar_doc_replace - replace section content."""
|
|
313
314
|
from invar.shell.doc_tools import replace_section_content
|
|
314
315
|
|
|
@@ -342,7 +343,7 @@ async def _run_doc_replace(args: dict[str, Any]) -> list[TextContent]:
|
|
|
342
343
|
# @shell_orchestration: MCP handler - calls shell layer directly
|
|
343
344
|
# @shell_complexity: MCP input validation + result handling
|
|
344
345
|
# @invar:allow shell_result: MCP handler for doc_insert tool
|
|
345
|
-
async def _run_doc_insert(args: dict[str, Any]) -> list[TextContent]:
|
|
346
|
+
async def _run_doc_insert(args: dict[str, Any]) -> list[TextContent] | CombinationContent:
|
|
346
347
|
"""Run invar_doc_insert - insert content relative to section."""
|
|
347
348
|
from invar.shell.doc_tools import insert_section_content
|
|
348
349
|
|
|
@@ -382,7 +383,7 @@ async def _run_doc_insert(args: dict[str, Any]) -> list[TextContent]:
|
|
|
382
383
|
# @shell_orchestration: MCP handler - calls shell layer directly
|
|
383
384
|
# @shell_complexity: MCP input validation + result handling
|
|
384
385
|
# @invar:allow shell_result: MCP handler for doc_delete tool
|
|
385
|
-
async def _run_doc_delete(args: dict[str, Any]) -> list[TextContent]:
|
|
386
|
+
async def _run_doc_delete(args: dict[str, Any]) -> list[TextContent] | CombinationContent:
|
|
386
387
|
"""Run invar_doc_delete - delete a section."""
|
|
387
388
|
from invar.shell.doc_tools import delete_section_content
|
|
388
389
|
|
|
@@ -411,13 +412,11 @@ async def _run_doc_delete(args: dict[str, Any]) -> list[TextContent]:
|
|
|
411
412
|
|
|
412
413
|
# @shell_complexity: Command execution with error handling branches
|
|
413
414
|
# @invar:allow shell_result: MCP subprocess wrapper utility
|
|
414
|
-
async def _execute_command(
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
timeout: Maximum time in seconds (default: 600, accommodates full Guard cycle)
|
|
420
|
-
"""
|
|
415
|
+
async def _execute_command(
|
|
416
|
+
cmd: list[str],
|
|
417
|
+
timeout: int = 600,
|
|
418
|
+
) -> list[TextContent] | CombinationContent:
|
|
419
|
+
"""Execute a command and return result."""
|
|
421
420
|
try:
|
|
422
421
|
result = subprocess.run(
|
|
423
422
|
cmd,
|
|
@@ -426,20 +425,16 @@ async def _execute_command(cmd: list[str], timeout: int = 600) -> list[TextConte
|
|
|
426
425
|
timeout=timeout,
|
|
427
426
|
)
|
|
428
427
|
|
|
429
|
-
output = result.stdout
|
|
430
|
-
if result.stderr:
|
|
431
|
-
output += f"\n\nStderr:\n{result.stderr}"
|
|
432
|
-
|
|
433
|
-
# Try to parse as JSON for better formatting
|
|
434
428
|
try:
|
|
435
429
|
parsed = json.loads(result.stdout)
|
|
436
|
-
|
|
430
|
+
return ([TextContent(type="text", text=json.dumps(parsed, indent=2))], parsed)
|
|
437
431
|
except json.JSONDecodeError:
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
432
|
+
output = result.stdout
|
|
433
|
+
if result.stderr:
|
|
434
|
+
output += f"\n\nStderr:\n{result.stderr}"
|
|
435
|
+
return [TextContent(type="text", text=output)]
|
|
441
436
|
|
|
442
437
|
except subprocess.TimeoutExpired:
|
|
443
|
-
return [TextContent(type="text", text=f"Error: Command timed out ({timeout}s
|
|
438
|
+
return [TextContent(type="text", text=f"Error: Command timed out ({timeout}s")]
|
|
444
439
|
except Exception as e:
|
|
445
440
|
return [TextContent(type="text", text=f"Error: {e}")]
|
|
@@ -47,7 +47,32 @@ export const requireJsdocExample = {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
return {
|
|
50
|
+
// Handle exported function declarations (async or sync)
|
|
51
|
+
// JSDoc comments are attached to ExportNamedDeclaration parent node
|
|
52
|
+
'ExportNamedDeclaration > FunctionDeclaration'(node) {
|
|
53
|
+
const anyNode = node;
|
|
54
|
+
const name = anyNode.id?.name || null;
|
|
55
|
+
if (!name)
|
|
56
|
+
return;
|
|
57
|
+
// Get JSDoc from parent ExportNamedDeclaration
|
|
58
|
+
const sourceCode = context.sourceCode || context.getSourceCode();
|
|
59
|
+
const exportDeclaration = anyNode.parent;
|
|
60
|
+
const comments = sourceCode.getCommentsBefore(exportDeclaration);
|
|
61
|
+
const hasExample = comments.some((comment) => comment.type === 'Block' &&
|
|
62
|
+
comment.value.includes('@example'));
|
|
63
|
+
if (!hasExample) {
|
|
64
|
+
context.report({
|
|
65
|
+
node,
|
|
66
|
+
messageId: 'missingExample',
|
|
67
|
+
data: { name },
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
// Handle non-exported function declarations
|
|
50
72
|
FunctionDeclaration(node) {
|
|
73
|
+
// Skip if exported (handled by selector above)
|
|
74
|
+
if (isExported(node))
|
|
75
|
+
return;
|
|
51
76
|
checkFunction(node, node.id?.name || null);
|
|
52
77
|
},
|
|
53
78
|
// Also check arrow functions assigned to exported variables
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"require-jsdoc-example.js","sourceRoot":"","sources":["../../src/rules/require-jsdoc-example.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"require-jsdoc-example.js","sourceRoot":"","sources":["../../src/rules/require-jsdoc-example.ts"],"names":[],"mappings":"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"}
|