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 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(cmd: list[str], timeout: int = 600) -> list[TextContent]:
415
- """Execute a command and return the result.
416
-
417
- Args:
418
- cmd: Command to execute
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
- output = json.dumps(parsed, indent=2)
430
+ return ([TextContent(type="text", text=json.dumps(parsed, indent=2))], parsed)
437
431
  except json.JSONDecodeError:
438
- pass
439
-
440
- return [TextContent(type="text", text=output)]
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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"}