invar-tools 1.16.0__py3-none-any.whl → 1.17.1__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.
@@ -159,11 +159,13 @@ def text_with_pattern(
159
159
  )
160
160
  noise_lines = st.lists(noise_line, min_size=0, max_size=10)
161
161
 
162
+ # Note: Hypothesis will automatically explore different orderings of the lines,
163
+ # so explicit shuffling is unnecessary. The concatenation order is sufficient.
162
164
  return st.builds(
163
165
  lambda p, n: "\n".join(p + n),
164
166
  pattern_lines,
165
167
  noise_lines,
166
- ).map(lambda x: "\n".join(sorted(x.split("\n"), key=lambda _: __import__("random").random())))
168
+ )
167
169
 
168
170
 
169
171
  @pre(lambda pattern: len(pattern) > 0)
invar/mcp/handlers.py CHANGED
@@ -24,6 +24,11 @@ def _validate_path(path: str) -> tuple[bool, str]:
24
24
 
25
25
  Returns (is_valid, error_message).
26
26
  Rejects paths that could be interpreted as shell commands or flags.
27
+
28
+ Note: This validation is for MCP (Model Context Protocol) handlers, which
29
+ are designed to provide AI agents with access to the project filesystem.
30
+ We validate format and reject shell injection patterns, but do not restrict
31
+ to working directory (unlike CLI tools) since MCP is a trusted local protocol.
27
32
  """
28
33
  if not path:
29
34
  return True, "" # Empty path defaults to "." in handlers
@@ -38,9 +43,13 @@ def _validate_path(path: str) -> tuple[bool, str]:
38
43
  if char in path:
39
44
  return False, f"Invalid path: contains forbidden character: {char!r}"
40
45
 
41
- # Try to resolve path - this catches malformed paths
46
+ # Resolve path to canonical form, following symlinks
47
+ # This ensures path is valid and catches directory traversal attempts
42
48
  try:
43
49
  Path(path).resolve()
50
+ # Note: We don't restrict to cwd here because MCP handlers are designed
51
+ # to access the full project. If path restriction is needed, implement
52
+ # at the MCP server level, not per-handler.
44
53
  except (OSError, ValueError) as e:
45
54
  return False, f"Invalid path: {e}"
46
55
 
@@ -14,12 +14,9 @@
14
14
  * --help Show help message
15
15
  */
16
16
  import { ESLint } from 'eslint';
17
- import { resolve, dirname } from 'path';
18
- import { fileURLToPath } from 'url';
17
+ import { resolve } from 'path';
18
+ import { statSync, realpathSync } from 'fs';
19
19
  import plugin from './index.js';
20
- // Get directory containing this CLI script (for resolving node_modules)
21
- const __filename = fileURLToPath(import.meta.url);
22
- const __dirname = dirname(__filename);
23
20
  function parseArgs(args) {
24
21
  const projectPath = args.find(arg => !arg.startsWith('--')) || '.';
25
22
  const configArg = args.find(arg => arg.startsWith('--config='));
@@ -58,15 +55,32 @@ async function main() {
58
55
  process.exit(0);
59
56
  }
60
57
  const projectPath = resolve(args.projectPath);
61
- // Validate resolved path is within current working directory or explicit allowed paths
58
+ // Validate resolved path is within current working directory
62
59
  // This prevents path traversal attacks via "../../../etc/passwd" patterns
60
+ // and symlink-based bypasses (e.g., "./symlink_inside/../../../etc/passwd")
63
61
  const cwd = process.cwd();
64
- if (!projectPath.startsWith(cwd) && !projectPath.startsWith('/')) {
65
- console.error(`Error: Project path must be within current directory`);
66
- console.error(` Requested: ${args.projectPath}`);
67
- console.error(` Resolved: ${projectPath}`);
68
- console.error(` Working dir: ${cwd}`);
69
- process.exit(1);
62
+ try {
63
+ // Use realpath to resolve symlinks and prevent bypass attacks
64
+ const realProjectPath = realpathSync(projectPath);
65
+ const realCwd = realpathSync(cwd);
66
+ if (!realProjectPath.startsWith(realCwd)) {
67
+ console.error(`Error: Project path must be within current directory`);
68
+ console.error(` Requested: ${args.projectPath}`);
69
+ console.error(` Resolved: ${realProjectPath}`);
70
+ console.error(` Working dir: ${realCwd}`);
71
+ process.exit(1);
72
+ }
73
+ }
74
+ catch (error) {
75
+ // If realpath fails (path doesn't exist), fall back to string comparison
76
+ // This allows error messages to be more specific
77
+ if (!projectPath.startsWith(cwd)) {
78
+ console.error(`Error: Project path must be within current directory`);
79
+ console.error(` Requested: ${args.projectPath}`);
80
+ console.error(` Resolved: ${projectPath}`);
81
+ console.error(` Working dir: ${cwd}`);
82
+ process.exit(1);
83
+ }
70
84
  }
71
85
  try {
72
86
  // Get the rules config for the selected mode
@@ -76,10 +90,11 @@ async function main() {
76
90
  process.exit(1);
77
91
  }
78
92
  // Create ESLint instance with programmatic configuration
79
- // Set cwd to CLI directory so ESLint can find parser in our node_modules
93
+ // ESLint will resolve modules relative to where it was installed (embedded node_modules)
94
+ // But process files relative to project directory
80
95
  const eslint = new ESLint({
81
96
  useEslintrc: false, // Don't load .eslintrc files
82
- cwd: __dirname, // Set working directory to CLI location for module resolution
97
+ cwd: projectPath, // Project directory for file processing and config resolution
83
98
  baseConfig: {
84
99
  parser: '@typescript-eslint/parser',
85
100
  parserOptions: {
@@ -93,8 +108,36 @@ async function main() {
93
108
  '@invar': plugin, // Register our plugin programmatically
94
109
  },
95
110
  }); // Type assertion for ESLint config complexity
96
- // Lint the project
97
- const results = await eslint.lintFiles([projectPath]);
111
+ // Lint the project - detect if path is a file or directory
112
+ // ESLint defaults to .js only, so we need glob patterns for .ts/.tsx
113
+ let filesToLint;
114
+ try {
115
+ const stats = statSync(projectPath);
116
+ // Note: Advisory check for optimization - TOCTOU race condition is acceptable
117
+ // because ESLint will handle file system changes gracefully during actual linting
118
+ if (stats.isFile()) {
119
+ // Single file - lint it directly
120
+ filesToLint = [projectPath];
121
+ }
122
+ else if (stats.isDirectory()) {
123
+ // Directory - use glob patterns for TypeScript files primarily
124
+ // Note: Focus on TypeScript files as this is a TypeScript Guard tool
125
+ filesToLint = [
126
+ `${projectPath}/**/*.ts`,
127
+ `${projectPath}/**/*.tsx`,
128
+ ];
129
+ }
130
+ else {
131
+ console.error(`Error: Path is neither a file nor a directory: ${projectPath}`);
132
+ process.exit(1);
133
+ }
134
+ }
135
+ catch (error) {
136
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
137
+ console.error(`Error: Cannot access path: ${errorMessage}`);
138
+ process.exit(1);
139
+ }
140
+ const results = await eslint.lintFiles(filesToLint);
98
141
  // Output in standard ESLint JSON format (compatible with guard_ts.py)
99
142
  const formatter = await eslint.loadFormatter('json');
100
143
  const resultText = await Promise.resolve(formatter.format(results, {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC5C,OAAO,MAAM,MAAM,YAAY,CAAC;AAQhC,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC;IACnE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC;IAChF,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACvC,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;CAqBb,CAAC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9C,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,SAAS,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAE9C,6DAA6D;IAC7D,0EAA0E;IAC1E,4EAA4E;IAC5E,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,IAAI,CAAC;QACH,8DAA8D;QAC9D,MAAM,eAAe,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAElC,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzC,OAAO,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;YACtE,OAAO,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YAClD,OAAO,CAAC,KAAK,CAAC,eAAe,eAAe,EAAE,CAAC,CAAC;YAChD,OAAO,CAAC,KAAK,CAAC,kBAAkB,OAAO,EAAE,CAAC,CAAC;YAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,yEAAyE;QACzE,iDAAiD;QACjD,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;YACtE,OAAO,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YAClD,OAAO,CAAC,KAAK,CAAC,eAAe,WAAW,EAAE,CAAC,CAAC;YAC5C,OAAO,CAAC,KAAK,CAAC,kBAAkB,GAAG,EAAE,CAAC,CAAC;YACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,6CAA6C;QAC7C,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,MAAM,CAAQ,CAAC;QAC5D,IAAI,CAAC,cAAc,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;YAC7C,OAAO,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,MAAM,wBAAwB,CAAC,CAAC;YAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,yDAAyD;QACzD,yFAAyF;QACzF,kDAAkD;QAClD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;YACxB,WAAW,EAAE,KAAK,EAAE,6BAA6B;YACjD,GAAG,EAAE,WAAW,EAAE,8DAA8D;YAChF,UAAU,EAAE;gBACV,MAAM,EAAE,2BAA2B;gBACnC,aAAa,EAAE;oBACb,WAAW,EAAE,IAAI;oBACjB,UAAU,EAAE,QAAQ;iBACrB;gBACD,OAAO,EAAE,CAAC,QAAQ,CAAC;gBACnB,KAAK,EAAE,cAAc,CAAC,KAAK;aAC5B;YACD,OAAO,EAAE;gBACP,QAAQ,EAAE,MAAM,EAAE,uCAAuC;aAC1D;SACK,CAAC,CAAC,CAAC,8CAA8C;QAEzD,2DAA2D;QAC3D,qEAAqE;QACrE,IAAI,WAAqB,CAAC;QAE1B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;YACpC,8EAA8E;YAC9E,kFAAkF;YAClF,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBACnB,iCAAiC;gBACjC,WAAW,GAAG,CAAC,WAAW,CAAC,CAAC;YAC9B,CAAC;iBAAM,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBAC/B,+DAA+D;gBAC/D,qEAAqE;gBACrE,WAAW,GAAG;oBACZ,GAAG,WAAW,UAAU;oBACxB,GAAG,WAAW,WAAW;iBAC1B,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,kDAAkD,WAAW,EAAE,CAAC,CAAC;gBAC/E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YAC9E,OAAO,CAAC,KAAK,CAAC,8BAA8B,YAAY,EAAE,CAAC,CAAC;YAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAEpD,sEAAsE;QACtE,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QACrD,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE;YACjE,GAAG,EAAE,WAAW;YAChB,SAAS,EAAE,MAAM,CAAC,sBAAsB,CAAC,OAAO,CAAC;SAClD,CAAC,CAAC,CAAC;QAEJ,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAExB,2CAA2C;QAC3C,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAElC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,2EAA2E;QAC3E,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QAC9E,OAAO,CAAC,KAAK,CAAC,kBAAkB,YAAY,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * @invar/eslint-plugin - ESLint plugin with Invar-specific rules
3
+ *
4
+ * Rules:
5
+ * - @invar/require-schema-validation: Zod-typed params must have .parse()
6
+ * - @invar/no-io-in-core: Forbid I/O imports in /core/ directories
7
+ * - @invar/shell-result-type: Shell functions must return Result<T, E>
8
+ * - @invar/no-any-in-schema: Forbid z.any() in schemas
9
+ * - @invar/require-jsdoc-example: Exported functions need @example
10
+ * - @invar/max-file-lines: Enforce max file length (layer-based)
11
+ * - @invar/max-function-lines: Enforce max function length (layer-based)
12
+ * - @invar/no-empty-schema: Forbid empty or permissive Zod schemas
13
+ * - @invar/no-redundant-type-schema: Forbid schemas that only repeat TypeScript types
14
+ * - @invar/require-complete-validation: All function params must be validated, or none
15
+ * - @invar/no-runtime-imports: Forbid require()/import() inside functions
16
+ * - @invar/no-impure-calls-in-core: Forbid Core importing from Shell
17
+ * - @invar/no-pure-logic-in-shell: Warn when Shell contains pure logic
18
+ * - @invar/shell-complexity: Warn when Shell functions are too complex
19
+ * - @invar/thin-entry-points: Warn when entry points contain substantial logic
20
+ */
21
+ import { requireSchemaValidation } from './rules/require-schema-validation.js';
22
+ import { noIoInCore } from './rules/no-io-in-core.js';
23
+ import { shellResultType } from './rules/shell-result-type.js';
24
+ import { noAnyInSchema } from './rules/no-any-in-schema.js';
25
+ import { requireJsdocExample } from './rules/require-jsdoc-example.js';
26
+ import { maxFileLines } from './rules/max-file-lines.js';
27
+ import { maxFunctionLines } from './rules/max-function-lines.js';
28
+ import { noEmptySchema } from './rules/no-empty-schema.js';
29
+ import { noRedundantTypeSchema } from './rules/no-redundant-type-schema.js';
30
+ import { requireCompleteValidation } from './rules/require-complete-validation.js';
31
+ import { noRuntimeImports } from './rules/no-runtime-imports.js';
32
+ import { noImpureCallsInCore } from './rules/no-impure-calls-in-core.js';
33
+ import { noPureLogicInShell } from './rules/no-pure-logic-in-shell.js';
34
+ import { shellComplexity } from './rules/shell-complexity.js';
35
+ import { thinEntryPoints } from './rules/thin-entry-points.js';
36
+ // ============================================================================
37
+ // Plugin Definition
38
+ // ============================================================================
39
+ const rules = {
40
+ 'require-schema-validation': requireSchemaValidation,
41
+ 'no-io-in-core': noIoInCore,
42
+ 'shell-result-type': shellResultType,
43
+ 'no-any-in-schema': noAnyInSchema,
44
+ 'require-jsdoc-example': requireJsdocExample,
45
+ 'max-file-lines': maxFileLines,
46
+ 'max-function-lines': maxFunctionLines,
47
+ 'no-empty-schema': noEmptySchema,
48
+ 'no-redundant-type-schema': noRedundantTypeSchema,
49
+ 'require-complete-validation': requireCompleteValidation,
50
+ 'no-runtime-imports': noRuntimeImports,
51
+ 'no-impure-calls-in-core': noImpureCallsInCore,
52
+ 'no-pure-logic-in-shell': noPureLogicInShell,
53
+ 'shell-complexity': shellComplexity,
54
+ 'thin-entry-points': thinEntryPoints,
55
+ };
56
+ // ESLint legacy config format (for ESLint 8 compatibility)
57
+ const configs = {
58
+ recommended: {
59
+ plugins: ['@invar'],
60
+ rules: {
61
+ '@invar/require-schema-validation': ['error', { mode: 'recommended' }],
62
+ '@invar/no-io-in-core': 'error',
63
+ '@invar/shell-result-type': 'warn',
64
+ '@invar/no-any-in-schema': 'warn',
65
+ '@invar/require-jsdoc-example': 'error',
66
+ '@invar/max-file-lines': 'error',
67
+ '@invar/max-function-lines': 'warn', // DX-22: Align with Python (WARN, not ERROR)
68
+ '@invar/no-empty-schema': 'error',
69
+ '@invar/no-redundant-type-schema': 'warn',
70
+ '@invar/require-complete-validation': 'warn',
71
+ '@invar/no-runtime-imports': 'error',
72
+ '@invar/no-impure-calls-in-core': 'error',
73
+ '@invar/no-pure-logic-in-shell': 'warn',
74
+ '@invar/shell-complexity': 'warn',
75
+ '@invar/thin-entry-points': 'warn',
76
+ },
77
+ },
78
+ strict: {
79
+ plugins: ['@invar'],
80
+ rules: {
81
+ '@invar/require-schema-validation': ['error', { mode: 'strict' }],
82
+ '@invar/no-io-in-core': 'error',
83
+ '@invar/shell-result-type': 'error',
84
+ '@invar/no-any-in-schema': 'error',
85
+ '@invar/require-jsdoc-example': 'error',
86
+ '@invar/max-file-lines': 'error',
87
+ '@invar/max-function-lines': 'error',
88
+ '@invar/no-empty-schema': 'error',
89
+ '@invar/no-redundant-type-schema': 'error',
90
+ '@invar/require-complete-validation': 'error',
91
+ '@invar/no-runtime-imports': 'error',
92
+ '@invar/no-impure-calls-in-core': 'error',
93
+ '@invar/no-pure-logic-in-shell': 'error',
94
+ '@invar/shell-complexity': 'error',
95
+ '@invar/thin-entry-points': 'error',
96
+ },
97
+ },
98
+ };
99
+ const plugin = {
100
+ rules,
101
+ configs: configs, // Type assertion due to ESLint config type complexity
102
+ };
103
+ export default plugin;
104
+ export { rules, configs };
105
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}