lucidscan 0.5.12__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.
Files changed (91) hide show
  1. lucidscan/__init__.py +12 -0
  2. lucidscan/bootstrap/__init__.py +26 -0
  3. lucidscan/bootstrap/paths.py +160 -0
  4. lucidscan/bootstrap/platform.py +111 -0
  5. lucidscan/bootstrap/validation.py +76 -0
  6. lucidscan/bootstrap/versions.py +119 -0
  7. lucidscan/cli/__init__.py +50 -0
  8. lucidscan/cli/__main__.py +8 -0
  9. lucidscan/cli/arguments.py +405 -0
  10. lucidscan/cli/commands/__init__.py +64 -0
  11. lucidscan/cli/commands/autoconfigure.py +294 -0
  12. lucidscan/cli/commands/help.py +69 -0
  13. lucidscan/cli/commands/init.py +656 -0
  14. lucidscan/cli/commands/list_scanners.py +59 -0
  15. lucidscan/cli/commands/scan.py +307 -0
  16. lucidscan/cli/commands/serve.py +142 -0
  17. lucidscan/cli/commands/status.py +84 -0
  18. lucidscan/cli/commands/validate.py +105 -0
  19. lucidscan/cli/config_bridge.py +152 -0
  20. lucidscan/cli/exit_codes.py +17 -0
  21. lucidscan/cli/runner.py +284 -0
  22. lucidscan/config/__init__.py +29 -0
  23. lucidscan/config/ignore.py +178 -0
  24. lucidscan/config/loader.py +431 -0
  25. lucidscan/config/models.py +316 -0
  26. lucidscan/config/validation.py +645 -0
  27. lucidscan/core/__init__.py +3 -0
  28. lucidscan/core/domain_runner.py +463 -0
  29. lucidscan/core/git.py +174 -0
  30. lucidscan/core/logging.py +34 -0
  31. lucidscan/core/models.py +207 -0
  32. lucidscan/core/streaming.py +340 -0
  33. lucidscan/core/subprocess_runner.py +164 -0
  34. lucidscan/detection/__init__.py +21 -0
  35. lucidscan/detection/detector.py +154 -0
  36. lucidscan/detection/frameworks.py +270 -0
  37. lucidscan/detection/languages.py +328 -0
  38. lucidscan/detection/tools.py +229 -0
  39. lucidscan/generation/__init__.py +15 -0
  40. lucidscan/generation/config_generator.py +275 -0
  41. lucidscan/generation/package_installer.py +330 -0
  42. lucidscan/mcp/__init__.py +20 -0
  43. lucidscan/mcp/formatter.py +510 -0
  44. lucidscan/mcp/server.py +297 -0
  45. lucidscan/mcp/tools.py +1049 -0
  46. lucidscan/mcp/watcher.py +237 -0
  47. lucidscan/pipeline/__init__.py +17 -0
  48. lucidscan/pipeline/executor.py +187 -0
  49. lucidscan/pipeline/parallel.py +181 -0
  50. lucidscan/plugins/__init__.py +40 -0
  51. lucidscan/plugins/coverage/__init__.py +28 -0
  52. lucidscan/plugins/coverage/base.py +160 -0
  53. lucidscan/plugins/coverage/coverage_py.py +454 -0
  54. lucidscan/plugins/coverage/istanbul.py +411 -0
  55. lucidscan/plugins/discovery.py +107 -0
  56. lucidscan/plugins/enrichers/__init__.py +61 -0
  57. lucidscan/plugins/enrichers/base.py +63 -0
  58. lucidscan/plugins/linters/__init__.py +26 -0
  59. lucidscan/plugins/linters/base.py +125 -0
  60. lucidscan/plugins/linters/biome.py +448 -0
  61. lucidscan/plugins/linters/checkstyle.py +393 -0
  62. lucidscan/plugins/linters/eslint.py +368 -0
  63. lucidscan/plugins/linters/ruff.py +498 -0
  64. lucidscan/plugins/reporters/__init__.py +45 -0
  65. lucidscan/plugins/reporters/base.py +30 -0
  66. lucidscan/plugins/reporters/json_reporter.py +79 -0
  67. lucidscan/plugins/reporters/sarif_reporter.py +303 -0
  68. lucidscan/plugins/reporters/summary_reporter.py +61 -0
  69. lucidscan/plugins/reporters/table_reporter.py +81 -0
  70. lucidscan/plugins/scanners/__init__.py +57 -0
  71. lucidscan/plugins/scanners/base.py +60 -0
  72. lucidscan/plugins/scanners/checkov.py +484 -0
  73. lucidscan/plugins/scanners/opengrep.py +464 -0
  74. lucidscan/plugins/scanners/trivy.py +492 -0
  75. lucidscan/plugins/test_runners/__init__.py +27 -0
  76. lucidscan/plugins/test_runners/base.py +111 -0
  77. lucidscan/plugins/test_runners/jest.py +381 -0
  78. lucidscan/plugins/test_runners/karma.py +481 -0
  79. lucidscan/plugins/test_runners/playwright.py +434 -0
  80. lucidscan/plugins/test_runners/pytest.py +598 -0
  81. lucidscan/plugins/type_checkers/__init__.py +27 -0
  82. lucidscan/plugins/type_checkers/base.py +106 -0
  83. lucidscan/plugins/type_checkers/mypy.py +355 -0
  84. lucidscan/plugins/type_checkers/pyright.py +313 -0
  85. lucidscan/plugins/type_checkers/typescript.py +280 -0
  86. lucidscan-0.5.12.dist-info/METADATA +242 -0
  87. lucidscan-0.5.12.dist-info/RECORD +91 -0
  88. lucidscan-0.5.12.dist-info/WHEEL +5 -0
  89. lucidscan-0.5.12.dist-info/entry_points.txt +34 -0
  90. lucidscan-0.5.12.dist-info/licenses/LICENSE +201 -0
  91. lucidscan-0.5.12.dist-info/top_level.txt +1 -0
@@ -0,0 +1,405 @@
1
+ """Argument parser construction for lucidscan CLI.
2
+
3
+ This module builds the argument parser with subcommands:
4
+ - lucidscan init - Configure AI tools (Claude Code, Cursor)
5
+ - lucidscan autoconfigure - Auto-configure project (generate lucidscan.yml)
6
+ - lucidscan scan - Run security/quality scans
7
+ - lucidscan status - Show configuration and tool status
8
+ - lucidscan serve - Run as MCP server or file watcher
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import argparse
14
+ from pathlib import Path
15
+
16
+
17
+ def _add_global_options(parser: argparse.ArgumentParser) -> None:
18
+ """Add global options available to all commands."""
19
+ parser.add_argument(
20
+ "--version",
21
+ action="store_true",
22
+ help="Show lucidscan version and exit.",
23
+ )
24
+ parser.add_argument(
25
+ "--debug",
26
+ action="store_true",
27
+ help="Enable debug logging.",
28
+ )
29
+ parser.add_argument(
30
+ "--verbose", "-v",
31
+ action="store_true",
32
+ help="Enable verbose (info-level) logging.",
33
+ )
34
+ parser.add_argument(
35
+ "--quiet", "-q",
36
+ action="store_true",
37
+ help="Reduce logging output to errors only.",
38
+ )
39
+
40
+
41
+ def _build_init_parser(subparsers: argparse._SubParsersAction) -> None:
42
+ """Build the 'init' subcommand parser.
43
+
44
+ This command configures AI tools (Claude Code, Cursor) to use LucidScan.
45
+ """
46
+ init_parser = subparsers.add_parser(
47
+ "init",
48
+ help="Configure AI tools to use LucidScan.",
49
+ description=(
50
+ "Configure Claude Code, Cursor, or other MCP-compatible AI tools "
51
+ "to use LucidScan for code quality checks."
52
+ ),
53
+ )
54
+
55
+ # Tool selection
56
+ tool_group = init_parser.add_argument_group("AI tools")
57
+ tool_group.add_argument(
58
+ "--claude-code",
59
+ action="store_true",
60
+ help="Configure Claude Code MCP settings.",
61
+ )
62
+ tool_group.add_argument(
63
+ "--cursor",
64
+ action="store_true",
65
+ help="Configure Cursor MCP settings.",
66
+ )
67
+ tool_group.add_argument(
68
+ "--all",
69
+ action="store_true",
70
+ dest="init_all",
71
+ help="Configure all supported AI tools.",
72
+ )
73
+
74
+ # Options
75
+ options_group = init_parser.add_argument_group("options")
76
+ options_group.add_argument(
77
+ "--dry-run",
78
+ action="store_true",
79
+ help="Show what would be done without making changes.",
80
+ )
81
+ options_group.add_argument(
82
+ "--force",
83
+ action="store_true",
84
+ help="Overwrite existing LucidScan configuration.",
85
+ )
86
+ options_group.add_argument(
87
+ "--remove",
88
+ action="store_true",
89
+ help="Remove LucidScan from the specified tool's configuration.",
90
+ )
91
+
92
+
93
+ def _build_autoconfigure_parser(subparsers: argparse._SubParsersAction) -> None:
94
+ """Build the 'autoconfigure' subcommand parser.
95
+
96
+ This command detects project characteristics and generates lucidscan.yml.
97
+ """
98
+ autoconfigure_parser = subparsers.add_parser(
99
+ "autoconfigure",
100
+ help="Auto-configure LucidScan for the current project.",
101
+ description=(
102
+ "Analyze your codebase, detect languages and frameworks, "
103
+ "and generate lucidscan.yml configuration."
104
+ ),
105
+ )
106
+ autoconfigure_parser.add_argument(
107
+ "--non-interactive", "-y",
108
+ action="store_true",
109
+ help="Use defaults without prompting (non-interactive mode).",
110
+ )
111
+ autoconfigure_parser.add_argument(
112
+ "--force", "-f",
113
+ action="store_true",
114
+ help="Overwrite existing configuration files.",
115
+ )
116
+ autoconfigure_parser.add_argument(
117
+ "path",
118
+ nargs="?",
119
+ default=".",
120
+ help="Project directory to autoconfigure (default: current directory).",
121
+ )
122
+
123
+
124
+ def _build_scan_parser(subparsers: argparse._SubParsersAction) -> None:
125
+ """Build the 'scan' subcommand parser."""
126
+ scan_parser = subparsers.add_parser(
127
+ "scan",
128
+ help="Run the quality/security pipeline.",
129
+ description=(
130
+ "Execute configured scanners and linters. "
131
+ "Results are output in the specified format."
132
+ ),
133
+ )
134
+
135
+ # Domain selection
136
+ domain_group = scan_parser.add_argument_group("scan domains")
137
+ domain_group.add_argument(
138
+ "--sca",
139
+ action="store_true",
140
+ help="Scan dependencies for known vulnerabilities (uses Trivy).",
141
+ )
142
+ domain_group.add_argument(
143
+ "--container",
144
+ action="store_true",
145
+ help="Scan container images for vulnerabilities. Use with --image.",
146
+ )
147
+ domain_group.add_argument(
148
+ "--iac",
149
+ action="store_true",
150
+ help="Scan Infrastructure-as-Code (Terraform, K8s, CloudFormation).",
151
+ )
152
+ domain_group.add_argument(
153
+ "--sast",
154
+ action="store_true",
155
+ help="Static application security testing (code pattern analysis).",
156
+ )
157
+ domain_group.add_argument(
158
+ "--linting",
159
+ action="store_true",
160
+ help="Run linting checks (Ruff for Python, ESLint for JS/TS).",
161
+ )
162
+ domain_group.add_argument(
163
+ "--type-checking",
164
+ action="store_true",
165
+ help="Run type checking (mypy/pyright for Python, tsc for TypeScript).",
166
+ )
167
+ domain_group.add_argument(
168
+ "--testing",
169
+ action="store_true",
170
+ help="Run test suite (pytest for Python, Jest for JS/TS).",
171
+ )
172
+ domain_group.add_argument(
173
+ "--coverage",
174
+ action="store_true",
175
+ help="Run coverage analysis (coverage.py for Python, Istanbul for JS/TS).",
176
+ )
177
+ domain_group.add_argument(
178
+ "--all",
179
+ action="store_true",
180
+ help="Enable all domains (sca, sast, iac, container, linting, type_checking, testing, coverage).",
181
+ )
182
+
183
+ # Target options
184
+ target_group = scan_parser.add_argument_group("targets")
185
+ target_group.add_argument(
186
+ "path",
187
+ nargs="?",
188
+ default=".",
189
+ help="Path to scan (default: current directory).",
190
+ )
191
+ target_group.add_argument(
192
+ "--files",
193
+ nargs="+",
194
+ metavar="FILE",
195
+ help="Specific files to scan (overrides default changed-files behavior).",
196
+ )
197
+ target_group.add_argument(
198
+ "--all-files",
199
+ action="store_true",
200
+ dest="all_files",
201
+ help="Scan entire project instead of just changed files.",
202
+ )
203
+ target_group.add_argument(
204
+ "--image",
205
+ action="append",
206
+ dest="images",
207
+ metavar="IMAGE",
208
+ help="Container image to scan (can be specified multiple times).",
209
+ )
210
+
211
+ # Output options
212
+ output_group = scan_parser.add_argument_group("output")
213
+ output_group.add_argument(
214
+ "--format",
215
+ choices=["json", "table", "sarif", "summary"],
216
+ default=None,
217
+ help="Output format (default: json, or as specified in config file).",
218
+ )
219
+
220
+ # Configuration options
221
+ config_group = scan_parser.add_argument_group("configuration")
222
+ config_group.add_argument(
223
+ "--fail-on",
224
+ choices=["critical", "high", "medium", "low"],
225
+ default=None,
226
+ help="Exit with code 1 if issues at or above this severity are found.",
227
+ )
228
+ config_group.add_argument(
229
+ "--coverage-threshold",
230
+ type=float,
231
+ default=None,
232
+ metavar="PERCENT",
233
+ help="Coverage percentage threshold (default: 80). Fail if below.",
234
+ )
235
+ config_group.add_argument(
236
+ "--config",
237
+ metavar="PATH",
238
+ type=Path,
239
+ help="Path to config file (default: .lucidscan.yml in project root).",
240
+ )
241
+
242
+ # Execution options
243
+ exec_group = scan_parser.add_argument_group("execution")
244
+ exec_group.add_argument(
245
+ "--sequential",
246
+ action="store_true",
247
+ help="Disable parallel scanner execution (for debugging).",
248
+ )
249
+ exec_group.add_argument(
250
+ "--fix",
251
+ action="store_true",
252
+ help="Apply auto-fixes where possible (linting only).",
253
+ )
254
+ exec_group.add_argument(
255
+ "--stream",
256
+ action="store_true",
257
+ help="Stream tool output in real-time as scans run.",
258
+ )
259
+
260
+
261
+ def _build_status_parser(subparsers: argparse._SubParsersAction) -> None:
262
+ """Build the 'status' subcommand parser."""
263
+ status_parser = subparsers.add_parser(
264
+ "status",
265
+ help="Show configuration and tool status.",
266
+ description=(
267
+ "Display lucidscan version, platform info, installed tools, "
268
+ "and scanner plugin status."
269
+ ),
270
+ )
271
+ status_parser.add_argument(
272
+ "--tools",
273
+ action="store_true",
274
+ help="Show detailed installed tool versions.",
275
+ )
276
+ status_parser.add_argument(
277
+ "--config",
278
+ action="store_true",
279
+ dest="show_config",
280
+ help="Show effective configuration.",
281
+ )
282
+
283
+
284
+ def _build_serve_parser(subparsers: argparse._SubParsersAction) -> None:
285
+ """Build the 'serve' subcommand parser."""
286
+ serve_parser = subparsers.add_parser(
287
+ "serve",
288
+ help="Run LucidScan as a server for AI integration.",
289
+ description=(
290
+ "Run LucidScan as an MCP server for Claude Code, Cursor, "
291
+ "or as a file watcher for real-time checking."
292
+ ),
293
+ )
294
+
295
+ # Server mode options
296
+ mode_group = serve_parser.add_argument_group("server mode")
297
+ mode_group.add_argument(
298
+ "--mcp",
299
+ action="store_true",
300
+ help="Run as MCP server (for Claude Code, Cursor).",
301
+ )
302
+ mode_group.add_argument(
303
+ "--watch",
304
+ action="store_true",
305
+ help="Watch files and run incremental checks on changes.",
306
+ )
307
+
308
+ # Server configuration
309
+ config_group = serve_parser.add_argument_group("configuration")
310
+ config_group.add_argument(
311
+ "--port",
312
+ type=int,
313
+ default=7432,
314
+ help="HTTP port for status endpoint (default: 7432).",
315
+ )
316
+ config_group.add_argument(
317
+ "--debounce",
318
+ type=int,
319
+ default=1000,
320
+ metavar="MS",
321
+ help="Debounce delay in milliseconds for file watcher (default: 1000).",
322
+ )
323
+ config_group.add_argument(
324
+ "path",
325
+ nargs="?",
326
+ default=".",
327
+ help="Project directory to serve (default: current directory).",
328
+ )
329
+
330
+
331
+ def _build_help_parser(subparsers: argparse._SubParsersAction) -> None:
332
+ """Build the 'help' subcommand parser."""
333
+ subparsers.add_parser(
334
+ "help",
335
+ help="Show LLM-friendly documentation.",
336
+ description=(
337
+ "Display comprehensive LucidScan documentation including "
338
+ "CLI commands, MCP tools, and configuration reference."
339
+ ),
340
+ )
341
+
342
+
343
+ def _build_validate_parser(subparsers: argparse._SubParsersAction) -> None:
344
+ """Build the 'validate' subcommand parser.
345
+
346
+ This command validates lucidscan.yml configuration files.
347
+ """
348
+ validate_parser = subparsers.add_parser(
349
+ "validate",
350
+ help="Validate lucidscan.yml configuration file.",
351
+ description=(
352
+ "Check a LucidScan configuration file for errors and warnings. "
353
+ "Reports issues with suggestions for fixes."
354
+ ),
355
+ )
356
+ validate_parser.add_argument(
357
+ "--config",
358
+ metavar="PATH",
359
+ type=Path,
360
+ help="Path to config file (default: find lucidscan.yml in current directory).",
361
+ )
362
+
363
+
364
+ def build_parser() -> argparse.ArgumentParser:
365
+ """Build and return the argument parser for lucidscan CLI.
366
+
367
+ Returns:
368
+ Configured ArgumentParser instance with subcommands.
369
+ """
370
+ parser = argparse.ArgumentParser(
371
+ prog="lucidscan",
372
+ description="LucidScan - The trust layer for AI-assisted development.",
373
+ epilog=(
374
+ "Examples:\n"
375
+ " lucidscan init --claude-code # Configure Claude Code\n"
376
+ " lucidscan init --cursor # Configure Cursor\n"
377
+ " lucidscan autoconfigure # Auto-configure project\n"
378
+ " lucidscan scan --sca # Scan dependencies\n"
379
+ " lucidscan scan --all # Run all scans\n"
380
+ " lucidscan scan --linting --fix # Lint and auto-fix\n"
381
+ " lucidscan status # Show tool status\n"
382
+ " lucidscan serve --mcp # Run MCP server\n"
383
+ ),
384
+ formatter_class=argparse.RawDescriptionHelpFormatter,
385
+ )
386
+
387
+ _add_global_options(parser)
388
+
389
+ # Create subcommands
390
+ subparsers = parser.add_subparsers(
391
+ dest="command",
392
+ title="commands",
393
+ description="Available commands:",
394
+ metavar="COMMAND",
395
+ )
396
+
397
+ _build_init_parser(subparsers)
398
+ _build_autoconfigure_parser(subparsers)
399
+ _build_scan_parser(subparsers)
400
+ _build_status_parser(subparsers)
401
+ _build_serve_parser(subparsers)
402
+ _build_help_parser(subparsers)
403
+ _build_validate_parser(subparsers)
404
+
405
+ return parser
@@ -0,0 +1,64 @@
1
+ """CLI commands package.
2
+
3
+ This module provides the base Command class and exports all command implementations.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from abc import ABC, abstractmethod
9
+ from argparse import Namespace
10
+ from typing import TYPE_CHECKING
11
+
12
+ if TYPE_CHECKING:
13
+ from lucidscan.config.models import LucidScanConfig
14
+
15
+
16
+ class Command(ABC):
17
+ """Base class for CLI commands.
18
+
19
+ All CLI commands should inherit from this class and implement
20
+ the execute method.
21
+ """
22
+
23
+ @property
24
+ @abstractmethod
25
+ def name(self) -> str:
26
+ """Command identifier.
27
+
28
+ Returns:
29
+ String name of the command.
30
+ """
31
+
32
+ @abstractmethod
33
+ def execute(self, args: Namespace, config: "LucidScanConfig | None" = None) -> int:
34
+ """Execute the command.
35
+
36
+ Args:
37
+ args: Parsed command-line arguments.
38
+ config: Optional LucidScan configuration.
39
+
40
+ Returns:
41
+ Exit code (0 for success, non-zero for error).
42
+ """
43
+
44
+
45
+ # Import command implementations for convenience
46
+ # ruff: noqa: E402
47
+ from lucidscan.cli.commands.status import StatusCommand
48
+ from lucidscan.cli.commands.list_scanners import ListScannersCommand
49
+ from lucidscan.cli.commands.scan import ScanCommand
50
+ from lucidscan.cli.commands.init import InitCommand
51
+ from lucidscan.cli.commands.autoconfigure import AutoconfigureCommand
52
+ from lucidscan.cli.commands.serve import ServeCommand
53
+ from lucidscan.cli.commands.validate import ValidateCommand
54
+
55
+ __all__ = [
56
+ "Command",
57
+ "StatusCommand",
58
+ "ListScannersCommand",
59
+ "ScanCommand",
60
+ "InitCommand",
61
+ "AutoconfigureCommand",
62
+ "ServeCommand",
63
+ "ValidateCommand",
64
+ ]