invar-tools 1.17.17__py3-none-any.whl → 1.17.19__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/node_tools/eslint-plugin/cli.js +85 -42
- invar/node_tools/eslint-plugin/rules/require-schema-validation.js +80 -66
- invar/shell/prove/guard_ts.py +16 -3
- {invar_tools-1.17.17.dist-info → invar_tools-1.17.19.dist-info}/METADATA +1 -1
- {invar_tools-1.17.17.dist-info → invar_tools-1.17.19.dist-info}/RECORD +10 -10
- {invar_tools-1.17.17.dist-info → invar_tools-1.17.19.dist-info}/WHEEL +0 -0
- {invar_tools-1.17.17.dist-info → invar_tools-1.17.19.dist-info}/entry_points.txt +0 -0
- {invar_tools-1.17.17.dist-info → invar_tools-1.17.19.dist-info}/licenses/LICENSE +0 -0
- {invar_tools-1.17.17.dist-info → invar_tools-1.17.19.dist-info}/licenses/LICENSE-GPL +0 -0
- {invar_tools-1.17.17.dist-info → invar_tools-1.17.19.dist-info}/licenses/NOTICE +0 -0
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import { ESLint } from 'eslint';
|
|
17
17
|
import { resolve, dirname } from 'path';
|
|
18
18
|
import { statSync, realpathSync } from 'fs';
|
|
19
|
+
import { spawnSync } from 'child_process';
|
|
19
20
|
import { fileURLToPath } from 'url';
|
|
20
21
|
import { createRequire } from 'module';
|
|
21
22
|
import plugin from './index.js';
|
|
@@ -27,12 +28,49 @@ const require = createRequire(import.meta.url);
|
|
|
27
28
|
|
|
28
29
|
function resolveTsParser(projectPath) {
|
|
29
30
|
try {
|
|
30
|
-
|
|
31
|
+
const tseslintEntry = require.resolve('typescript-eslint', { paths: [projectPath] });
|
|
32
|
+
if (tseslintEntry) {
|
|
33
|
+
const tseslintRoot = dirname(dirname(tseslintEntry));
|
|
34
|
+
return require.resolve('@typescript-eslint/parser', { paths: [tseslintRoot] });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
return require.resolve('@typescript-eslint/parser', { paths: [projectPath] });
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
return require.resolve('@typescript-eslint/parser', { paths: [__dirname] });
|
|
31
48
|
}
|
|
32
49
|
catch {
|
|
33
50
|
return null;
|
|
34
51
|
}
|
|
35
52
|
}
|
|
53
|
+
function _gitLsFiles(projectPath) {
|
|
54
|
+
const check = spawnSync('git', ['-C', projectPath, 'rev-parse', '--is-inside-work-tree'], {
|
|
55
|
+
encoding: 'utf8',
|
|
56
|
+
timeout: 2000,
|
|
57
|
+
});
|
|
58
|
+
if (check.status !== 0) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const ls = spawnSync('git', ['-C', projectPath, 'ls-files', '-z', '--', '*.ts', '*.tsx'], {
|
|
63
|
+
encoding: 'utf8',
|
|
64
|
+
timeout: 15000,
|
|
65
|
+
});
|
|
66
|
+
if (ls.status !== 0 || !ls.stdout) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const files = ls.stdout.split('\0').filter(Boolean);
|
|
71
|
+
return files.length > 0 ? files : null;
|
|
72
|
+
}
|
|
73
|
+
|
|
36
74
|
function parseArgs(args) {
|
|
37
75
|
const projectPath = args.find(arg => !arg.startsWith('--')) || '.';
|
|
38
76
|
const configArg = args.find(arg => arg.startsWith('--config='));
|
|
@@ -107,20 +145,51 @@ async function main() {
|
|
|
107
145
|
}
|
|
108
146
|
const tsParser = resolveTsParser(projectPath);
|
|
109
147
|
if (!tsParser) {
|
|
110
|
-
console.error("ESLint failed: Failed to load
|
|
111
|
-
console.error("Install
|
|
112
|
-
|
|
148
|
+
console.error("ESLint failed: Failed to load TypeScript parser.");
|
|
149
|
+
console.error("Install either 'typescript-eslint' or '@typescript-eslint/parser' in your project.");
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
let filesToLint;
|
|
154
|
+
let lintCwd = projectPath;
|
|
155
|
+
let globInputPaths = true;
|
|
156
|
+
try {
|
|
157
|
+
const stats = statSync(projectPath);
|
|
158
|
+
if (stats.isFile()) {
|
|
159
|
+
lintCwd = dirname(projectPath);
|
|
160
|
+
filesToLint = [projectPath];
|
|
161
|
+
globInputPaths = false;
|
|
162
|
+
}
|
|
163
|
+
else if (stats.isDirectory()) {
|
|
164
|
+
const gitFiles = _gitLsFiles(projectPath);
|
|
165
|
+
if (gitFiles) {
|
|
166
|
+
filesToLint = gitFiles;
|
|
167
|
+
globInputPaths = false;
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
filesToLint = [
|
|
171
|
+
"**/*.ts",
|
|
172
|
+
"**/*.tsx",
|
|
173
|
+
];
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
console.error(`Error: Path is neither a file nor a directory: ${projectPath}`);
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
183
|
+
console.error(`Error: Cannot access path: ${errorMessage}`);
|
|
113
184
|
process.exit(1);
|
|
114
185
|
}
|
|
115
186
|
|
|
116
|
-
// Create ESLint instance with programmatic configuration
|
|
117
|
-
// Use __dirname (where CLI is located) for module resolution
|
|
118
|
-
// This allows ESLint to find embedded node_modules in site-packages
|
|
119
187
|
const eslint = new ESLint({
|
|
120
|
-
useEslintrc: false,
|
|
121
|
-
cwd:
|
|
122
|
-
resolvePluginsRelativeTo: __dirname,
|
|
188
|
+
useEslintrc: false,
|
|
189
|
+
cwd: lintCwd,
|
|
190
|
+
resolvePluginsRelativeTo: __dirname,
|
|
123
191
|
errorOnUnmatchedPattern: false,
|
|
192
|
+
globInputPaths,
|
|
124
193
|
baseConfig: {
|
|
125
194
|
parser: tsParser,
|
|
126
195
|
parserOptions: {
|
|
@@ -130,49 +199,23 @@ async function main() {
|
|
|
130
199
|
plugins: ['@invar'],
|
|
131
200
|
rules: selectedConfig.rules,
|
|
132
201
|
ignorePatterns: [
|
|
133
|
-
// Explicit ignores to prevent scanning generated/cached directories
|
|
134
202
|
'**/node_modules/**',
|
|
135
203
|
'**/.next/**',
|
|
136
204
|
'**/dist/**',
|
|
137
205
|
'**/build/**',
|
|
138
206
|
'**/.cache/**',
|
|
139
207
|
'**/coverage/**',
|
|
208
|
+
'**/.turbo/**',
|
|
209
|
+
'**/.vercel/**',
|
|
210
|
+
'**/playwright-report/**',
|
|
211
|
+
'**/test-results/**',
|
|
140
212
|
],
|
|
141
213
|
},
|
|
142
214
|
plugins: {
|
|
143
215
|
'@invar': plugin, // Register plugin directly
|
|
144
216
|
},
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
// ESLint defaults to .js only, so we need glob patterns for .ts/.tsx
|
|
148
|
-
let filesToLint;
|
|
149
|
-
try {
|
|
150
|
-
const stats = statSync(projectPath);
|
|
151
|
-
// Note: Advisory check for optimization - TOCTOU race condition is acceptable
|
|
152
|
-
// because ESLint will handle file system changes gracefully during actual linting
|
|
153
|
-
if (stats.isFile()) {
|
|
154
|
-
// Single file - lint it directly
|
|
155
|
-
filesToLint = [projectPath];
|
|
156
|
-
}
|
|
157
|
-
else if (stats.isDirectory()) {
|
|
158
|
-
// Directory - use relative glob patterns for TypeScript files
|
|
159
|
-
// Note: Focus on TypeScript files as this is a TypeScript Guard tool
|
|
160
|
-
// Use relative patterns (no projectPath prefix) since cwd is set to projectPath
|
|
161
|
-
filesToLint = [
|
|
162
|
-
"**/*.ts",
|
|
163
|
-
"**/*.tsx",
|
|
164
|
-
];
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
console.error(`Error: Path is neither a file nor a directory: ${projectPath}`);
|
|
168
|
-
process.exit(1);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
catch (error) {
|
|
172
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
173
|
-
console.error(`Error: Cannot access path: ${errorMessage}`);
|
|
174
|
-
process.exit(1);
|
|
175
|
-
}
|
|
217
|
+
});
|
|
218
|
+
|
|
176
219
|
const results = await eslint.lintFiles(filesToLint);
|
|
177
220
|
// Output in standard ESLint JSON format (compatible with guard_ts.py)
|
|
178
221
|
const formatter = await eslint.loadFormatter('json');
|
|
@@ -77,49 +77,58 @@ function matchesEnforcePattern(filePath, patterns) {
|
|
|
77
77
|
function isZodType(typeAnnotation) {
|
|
78
78
|
return ZOD_TYPE_PATTERNS.some(pattern => pattern.test(typeAnnotation));
|
|
79
79
|
}
|
|
80
|
-
function
|
|
80
|
+
function collectParseArgs(body, visitorKeys) {
|
|
81
|
+
const parsed = new Set();
|
|
81
82
|
if (!body)
|
|
82
|
-
return
|
|
83
|
-
|
|
84
|
-
const MAX_DEPTH = 50;
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
return parsed;
|
|
84
|
+
|
|
85
|
+
const MAX_DEPTH = 50;
|
|
86
|
+
const stack = [{ node: body, depth: 0 }];
|
|
87
|
+
|
|
88
|
+
while (stack.length > 0) {
|
|
89
|
+
const current = stack.pop();
|
|
90
|
+
if (!current)
|
|
91
|
+
continue;
|
|
92
|
+
const node = current.node;
|
|
93
|
+
const depth = current.depth;
|
|
94
|
+
if (!node || typeof node !== 'object')
|
|
95
|
+
continue;
|
|
88
96
|
if (depth > MAX_DEPTH)
|
|
89
|
-
|
|
97
|
+
continue;
|
|
98
|
+
|
|
90
99
|
if (node.type === 'CallExpression') {
|
|
91
100
|
const callee = node.callee;
|
|
92
|
-
if (callee.type === 'MemberExpression') {
|
|
101
|
+
if (callee && callee.type === 'MemberExpression') {
|
|
93
102
|
const property = callee.property;
|
|
94
|
-
if (property.type === 'Identifier' &&
|
|
95
|
-
(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return;
|
|
103
|
+
if (property && property.type === 'Identifier' && (property.name === 'parse' || property.name === 'safeParse')) {
|
|
104
|
+
for (const arg of node.arguments || []) {
|
|
105
|
+
if (arg && arg.type === 'Identifier') {
|
|
106
|
+
parsed.add(arg.name);
|
|
107
|
+
}
|
|
100
108
|
}
|
|
101
109
|
}
|
|
102
110
|
}
|
|
103
111
|
}
|
|
104
|
-
|
|
105
|
-
|
|
112
|
+
|
|
113
|
+
const keys = (visitorKeys && node.type && visitorKeys[node.type]) || [];
|
|
114
|
+
for (const key of keys) {
|
|
106
115
|
const value = node[key];
|
|
107
|
-
if (value
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
116
|
+
if (!value)
|
|
117
|
+
continue;
|
|
118
|
+
if (Array.isArray(value)) {
|
|
119
|
+
for (const item of value) {
|
|
120
|
+
if (item && typeof item === 'object' && item.type) {
|
|
121
|
+
stack.push({ node: item, depth: depth + 1 });
|
|
113
122
|
}
|
|
114
123
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
124
|
+
}
|
|
125
|
+
else if (typeof value === 'object' && value.type) {
|
|
126
|
+
stack.push({ node: value, depth: depth + 1 });
|
|
118
127
|
}
|
|
119
128
|
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return parsed;
|
|
123
132
|
}
|
|
124
133
|
export const requireSchemaValidation = {
|
|
125
134
|
meta: {
|
|
@@ -206,49 +215,54 @@ export const requireSchemaValidation = {
|
|
|
206
215
|
}
|
|
207
216
|
function checkFunction(node, params) {
|
|
208
217
|
const functionName = getFunctionName(node);
|
|
209
|
-
// Skip if shouldn't check based on mode
|
|
210
218
|
if (!shouldCheck(functionName)) {
|
|
211
219
|
return;
|
|
212
220
|
}
|
|
221
|
+
|
|
213
222
|
const body = 'body' in node ? node.body : null;
|
|
223
|
+
const zodParams = params.filter((p) => p.typeAnnotation && isZodType(p.typeAnnotation) && p.name && p.name !== '{...}' && p.name !== '[...]');
|
|
224
|
+
if (zodParams.length === 0) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const parsedArgs = collectParseArgs(body, sourceCode.visitorKeys);
|
|
214
229
|
const isRiskFunction = isHighRiskFunction(functionName, filename);
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const schemaMatch = param.typeAnnotation.match(/typeof\s+(\w+)/);
|
|
220
|
-
const schemaName = schemaMatch ? schemaMatch[1] : 'Schema';
|
|
221
|
-
const validatedVarName = `validated${param.name.charAt(0).toUpperCase()}${param.name.slice(1)}`;
|
|
222
|
-
context.report({
|
|
223
|
-
node: node,
|
|
224
|
-
messageId: isRiskFunction ? 'missingValidationRisk' : 'missingValidation',
|
|
225
|
-
data: {
|
|
226
|
-
name: param.name,
|
|
227
|
-
functionName: functionName,
|
|
228
|
-
},
|
|
229
|
-
suggest: [
|
|
230
|
-
{
|
|
231
|
-
messageId: 'addParseCall',
|
|
232
|
-
data: { name: param.name },
|
|
233
|
-
fix(fixer) {
|
|
234
|
-
// Find the opening brace of the function body
|
|
235
|
-
if (!body || body.type !== 'BlockStatement')
|
|
236
|
-
return null;
|
|
237
|
-
const blockBody = body;
|
|
238
|
-
if (!blockBody.body || blockBody.body.length === 0)
|
|
239
|
-
return null;
|
|
240
|
-
const firstStatement = blockBody.body[0];
|
|
241
|
-
// Detect indentation from the first statement
|
|
242
|
-
const firstStatementStart = firstStatement.loc?.start.column ?? 2;
|
|
243
|
-
const indent = ' '.repeat(firstStatementStart);
|
|
244
|
-
const parseCode = `const ${validatedVarName} = ${schemaName}.parse(${param.name});\n${indent}`;
|
|
245
|
-
return fixer.insertTextBefore(firstStatement, parseCode);
|
|
246
|
-
},
|
|
247
|
-
},
|
|
248
|
-
],
|
|
249
|
-
});
|
|
250
|
-
}
|
|
230
|
+
|
|
231
|
+
for (const param of zodParams) {
|
|
232
|
+
if (parsedArgs.has(param.name)) {
|
|
233
|
+
continue;
|
|
251
234
|
}
|
|
235
|
+
|
|
236
|
+
const schemaMatch = param.typeAnnotation.match(/typeof\s+(\w+)/);
|
|
237
|
+
const schemaName = schemaMatch ? schemaMatch[1] : 'Schema';
|
|
238
|
+
const validatedVarName = `validated${param.name.charAt(0).toUpperCase()}${param.name.slice(1)}`;
|
|
239
|
+
|
|
240
|
+
context.report({
|
|
241
|
+
node: node,
|
|
242
|
+
messageId: isRiskFunction ? 'missingValidationRisk' : 'missingValidation',
|
|
243
|
+
data: {
|
|
244
|
+
name: param.name,
|
|
245
|
+
functionName: functionName,
|
|
246
|
+
},
|
|
247
|
+
suggest: [
|
|
248
|
+
{
|
|
249
|
+
messageId: 'addParseCall',
|
|
250
|
+
data: { name: param.name },
|
|
251
|
+
fix(fixer) {
|
|
252
|
+
if (!body || body.type !== 'BlockStatement')
|
|
253
|
+
return null;
|
|
254
|
+
const blockBody = body;
|
|
255
|
+
if (!blockBody.body || blockBody.body.length === 0)
|
|
256
|
+
return null;
|
|
257
|
+
const firstStatement = blockBody.body[0];
|
|
258
|
+
const firstStatementStart = firstStatement.loc?.start.column ?? 2;
|
|
259
|
+
const indent = ' '.repeat(firstStatementStart);
|
|
260
|
+
const parseCode = `const ${validatedVarName} = ${schemaName}.parse(${param.name});\n${indent}`;
|
|
261
|
+
return fixer.insertTextBefore(firstStatement, parseCode);
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
],
|
|
265
|
+
});
|
|
252
266
|
}
|
|
253
267
|
}
|
|
254
268
|
/**
|
invar/shell/prove/guard_ts.py
CHANGED
|
@@ -374,6 +374,19 @@ def _check_tool_available(tool: str, check_args: list[str]) -> bool:
|
|
|
374
374
|
# =============================================================================
|
|
375
375
|
|
|
376
376
|
|
|
377
|
+
def _is_invar_package_dir(package_dir: Path, package_name: str) -> bool:
|
|
378
|
+
package_json = package_dir / "package.json"
|
|
379
|
+
if not package_json.exists():
|
|
380
|
+
return False
|
|
381
|
+
|
|
382
|
+
try:
|
|
383
|
+
data = json.loads(package_json.read_text(encoding="utf-8"))
|
|
384
|
+
except (OSError, json.JSONDecodeError):
|
|
385
|
+
return False
|
|
386
|
+
|
|
387
|
+
return data.get("name") == f"@invar/{package_name}"
|
|
388
|
+
|
|
389
|
+
|
|
377
390
|
# @shell_complexity: Path discovery with fallback logic
|
|
378
391
|
def _get_invar_package_cmd(package_name: str, project_path: Path) -> list[str]:
|
|
379
392
|
"""Get command to run an @invar/* package.
|
|
@@ -395,11 +408,11 @@ def _get_invar_package_cmd(package_name: str, project_path: Path) -> list[str]:
|
|
|
395
408
|
resolved_path = project_path.resolve()
|
|
396
409
|
|
|
397
410
|
local_cli = resolved_path / "typescript" / "packages" / package_name / "dist" / "cli.js"
|
|
398
|
-
if local_cli.exists():
|
|
411
|
+
if local_cli.exists() and _is_invar_package_dir(local_cli.parent.parent, package_name):
|
|
399
412
|
return ["node", str(local_cli)]
|
|
400
413
|
|
|
401
414
|
local_cli = resolved_path / "packages" / package_name / "dist" / "cli.js"
|
|
402
|
-
if local_cli.exists():
|
|
415
|
+
if local_cli.exists() and _is_invar_package_dir(local_cli.parent.parent, package_name):
|
|
403
416
|
return ["node", str(local_cli)]
|
|
404
417
|
|
|
405
418
|
# Priority 2: Embedded tools (from pip install)
|
|
@@ -417,7 +430,7 @@ def _get_invar_package_cmd(package_name: str, project_path: Path) -> list[str]:
|
|
|
417
430
|
check_path = resolved_path
|
|
418
431
|
for _ in range(5): # Max 5 levels up
|
|
419
432
|
candidate = check_path / f"typescript/packages/{package_name}/dist/cli.js"
|
|
420
|
-
if candidate.exists():
|
|
433
|
+
if candidate.exists() and _is_invar_package_dir(candidate.parent.parent, package_name):
|
|
421
434
|
return ["node", str(candidate)]
|
|
422
435
|
parent = check_path.parent
|
|
423
436
|
if parent == check_path:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: invar-tools
|
|
3
|
-
Version: 1.17.
|
|
3
|
+
Version: 1.17.19
|
|
4
4
|
Summary: AI-native software engineering tools with design-by-contract verification
|
|
5
5
|
Project-URL: Homepage, https://github.com/tefx/invar
|
|
6
6
|
Project-URL: Documentation, https://github.com/tefx/invar#readme
|
|
@@ -56,7 +56,7 @@ invar/node_tools/.gitignore,sha256=M2kz8Iw7Kzmi44mKo1r7_HOZMh79a7dFDdRrqXyaEhI,5
|
|
|
56
56
|
invar/node_tools/MANIFEST,sha256=2Z2at-27MK8K7DSjOjjtR4faTbt6eCiKQuEfvP_lwH8,145
|
|
57
57
|
invar/node_tools/__init__.py,sha256=HzILh3jtP28Lm2jZwss1SY65ECxbtw2J2uFpXQA6Y94,1740
|
|
58
58
|
invar/node_tools/ts-query.js,sha256=fEc_f0JT_Mb18dEoA4_vJoazvd7Lqv_rsed4eHSAbCg,13303
|
|
59
|
-
invar/node_tools/eslint-plugin/cli.js,sha256=
|
|
59
|
+
invar/node_tools/eslint-plugin/cli.js,sha256=jgRHHHDRbyQiVbIWgmaxlsA9PlDvonWFEEYf9_XPaZ4,8481
|
|
60
60
|
invar/node_tools/eslint-plugin/cli.js.map,sha256=AZt_DYAD6NnHGjR6oxXfGYaOHc6-vfDs0ENvYsbw5Ro,4489
|
|
61
61
|
invar/node_tools/eslint-plugin/index.js,sha256=atrI37dn1yDznQrgKY-1xIhLnCdvJQTU53123ZI_9J4,5132
|
|
62
62
|
invar/node_tools/eslint-plugin/index.js.map,sha256=MlFuNso9sZ4v9ggGJLyMq4Pt_JdEzP1OyouyCCki1wA,2344
|
|
@@ -2616,7 +2616,7 @@ invar/node_tools/eslint-plugin/rules/require-complete-validation.js,sha256=ZGeAE
|
|
|
2616
2616
|
invar/node_tools/eslint-plugin/rules/require-complete-validation.js.map,sha256=UhEr4fql0TObHt3ya8DydqbFlig5CSDFKIIJZSf74rA,2497
|
|
2617
2617
|
invar/node_tools/eslint-plugin/rules/require-jsdoc-example.js,sha256=Uql3FKdnTHFBMh_OkwGuOdMBzf4k94QHOaWo9frAcSM,4488
|
|
2618
2618
|
invar/node_tools/eslint-plugin/rules/require-jsdoc-example.js.map,sha256=00cKhvu890f-8UXPZcEAaX44IjCxxw12E4l_gsi93JM,2960
|
|
2619
|
-
invar/node_tools/eslint-plugin/rules/require-schema-validation.js,sha256=
|
|
2619
|
+
invar/node_tools/eslint-plugin/rules/require-schema-validation.js,sha256=6kRnMrTBuqeHmNOdBz78jZ0WBZgTmIUBoR_0ozWlK4k,12155
|
|
2620
2620
|
invar/node_tools/eslint-plugin/rules/require-schema-validation.js.map,sha256=akTSZQq-OC6ZvwMklIBRaxsesJ9w6GHaPhRTJ_ihmaE,8211
|
|
2621
2621
|
invar/node_tools/eslint-plugin/rules/shell-complexity.js,sha256=Bhc9i7ILYMNNAUvxf9l7PlwhC_Neb69Jl1nUNABu2jg,11260
|
|
2622
2622
|
invar/node_tools/eslint-plugin/rules/shell-complexity.js.map,sha256=0oJoDxXpXg2VTrwGMa-UDZ6te15Sv9vq-LgwWjJB5Q4,7140
|
|
@@ -2697,7 +2697,7 @@ invar/shell/prove/__init__.py,sha256=ZqlbmyMFJf6yAle8634jFuPRv8wNvHps8loMlOJyf8A
|
|
|
2697
2697
|
invar/shell/prove/accept.py,sha256=cnY_6jzU1EBnpLF8-zWUWcXiSXtCwxPsXEYXsSVPG38,3717
|
|
2698
2698
|
invar/shell/prove/cache.py,sha256=jbNdrvfLjvK7S0iqugErqeabb4YIbQuwIlcSRyCKbcg,4105
|
|
2699
2699
|
invar/shell/prove/crosshair.py,sha256=XhJDsQWIriX9SuqeflUYvJgp9gJTDH7I7Uka6zjNzZ0,16734
|
|
2700
|
-
invar/shell/prove/guard_ts.py,sha256=
|
|
2700
|
+
invar/shell/prove/guard_ts.py,sha256=8InEWFd6oqFxBUEaAdlqOvPi43p0VZKxJIrAaF0eReU,37936
|
|
2701
2701
|
invar/shell/prove/hypothesis.py,sha256=QUclOOUg_VB6wbmHw8O2EPiL5qBOeBRqQeM04AVuLw0,9880
|
|
2702
2702
|
invar/templates/CLAUDE.md.template,sha256=eaGU3SyRO_NEifw5b26k3srgQH4jyeujjCJ-HbM36_w,4913
|
|
2703
2703
|
invar/templates/__init__.py,sha256=cb3ht8KPK5oBn5oG6HsTznujmo9WriJ_P--fVxJwycc,45
|
|
@@ -2778,10 +2778,10 @@ invar/templates/skills/invar-reflect/template.md,sha256=Rr5hvbllvmd8jSLf_0ZjyKt6
|
|
|
2778
2778
|
invar/templates/skills/investigate/SKILL.md.jinja,sha256=cp6TBEixBYh1rLeeHOR1yqEnFqv1NZYePORMnavLkQI,3231
|
|
2779
2779
|
invar/templates/skills/propose/SKILL.md.jinja,sha256=6BuKiCqO1AEu3VtzMHy1QWGqr_xqG9eJlhbsKT4jev4,3463
|
|
2780
2780
|
invar/templates/skills/review/SKILL.md.jinja,sha256=ET5mbdSe_eKgJbi2LbgFC-z1aviKcHOBw7J5Q28fr4U,14105
|
|
2781
|
-
invar_tools-1.17.
|
|
2782
|
-
invar_tools-1.17.
|
|
2783
|
-
invar_tools-1.17.
|
|
2784
|
-
invar_tools-1.17.
|
|
2785
|
-
invar_tools-1.17.
|
|
2786
|
-
invar_tools-1.17.
|
|
2787
|
-
invar_tools-1.17.
|
|
2781
|
+
invar_tools-1.17.19.dist-info/METADATA,sha256=ecuhzoJZslp81KIMpPROD2LH-owOo4p8viFpMB5uKbw,28596
|
|
2782
|
+
invar_tools-1.17.19.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
2783
|
+
invar_tools-1.17.19.dist-info/entry_points.txt,sha256=RwH_EhqgtFPsnO6RcrwrAb70Zyfb8Mh6uUtztWnUxGk,102
|
|
2784
|
+
invar_tools-1.17.19.dist-info/licenses/LICENSE,sha256=qeFksp4H4kfTgQxPCIu3OdagXyiZcgBlVfsQ6M5oFyk,10767
|
|
2785
|
+
invar_tools-1.17.19.dist-info/licenses/LICENSE-GPL,sha256=IvZfC6ZbP7CLjytoHVzvpDZpD-Z3R_qa1GdMdWlWQ6Q,35157
|
|
2786
|
+
invar_tools-1.17.19.dist-info/licenses/NOTICE,sha256=joEyMyFhFY8Vd8tTJ-a3SirI0m2Sd0WjzqYt3sdcglc,2561
|
|
2787
|
+
invar_tools-1.17.19.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|