invar-tools 1.15.6__py3-none-any.whl → 1.16.0__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/.gitignore +17 -0
- invar/node_tools/MANIFEST +1 -0
- invar/node_tools/eslint-plugin/cli.js +117 -0
- invar/shell/commands/init.py +2 -1
- invar/shell/prove/guard_ts.py +25 -3
- invar/shell/templates.py +44 -6
- {invar_tools-1.15.6.dist-info → invar_tools-1.16.0.dist-info}/METADATA +1 -1
- {invar_tools-1.15.6.dist-info → invar_tools-1.16.0.dist-info}/RECORD +13 -11
- {invar_tools-1.15.6.dist-info → invar_tools-1.16.0.dist-info}/WHEEL +0 -0
- {invar_tools-1.15.6.dist-info → invar_tools-1.16.0.dist-info}/entry_points.txt +0 -0
- {invar_tools-1.15.6.dist-info → invar_tools-1.16.0.dist-info}/licenses/LICENSE +0 -0
- {invar_tools-1.15.6.dist-info → invar_tools-1.16.0.dist-info}/licenses/LICENSE-GPL +0 -0
- {invar_tools-1.15.6.dist-info → invar_tools-1.16.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Embedded Node.js tools - runtime dependencies
|
|
2
|
+
# These are installed by scripts/embed_node_tools.py
|
|
3
|
+
# Run that script before building or testing
|
|
4
|
+
|
|
5
|
+
*/node_modules/
|
|
6
|
+
*/package.json
|
|
7
|
+
|
|
8
|
+
# eslint-plugin is unbundled (entire dist/ directory)
|
|
9
|
+
# All other tools are bundled (single cli.js file)
|
|
10
|
+
eslint-plugin/
|
|
11
|
+
|
|
12
|
+
# Common generated/temp files
|
|
13
|
+
*.log
|
|
14
|
+
.DS_Store
|
|
15
|
+
.npm/
|
|
16
|
+
npm-debug.log*
|
|
17
|
+
node_modules/.cache/
|
invar/node_tools/MANIFEST
CHANGED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CLI for @invar/eslint-plugin
|
|
4
|
+
*
|
|
5
|
+
* Runs ESLint with @invar/* rules pre-configured.
|
|
6
|
+
* Outputs standard ESLint JSON format for integration with guard_ts.py.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* node cli.js [path] [--config=recommended|strict]
|
|
10
|
+
*
|
|
11
|
+
* Options:
|
|
12
|
+
* path Project directory to lint (default: current directory)
|
|
13
|
+
* --config Use 'recommended' or 'strict' preset (default: recommended)
|
|
14
|
+
* --help Show help message
|
|
15
|
+
*/
|
|
16
|
+
import { ESLint } from 'eslint';
|
|
17
|
+
import { resolve, dirname } from 'path';
|
|
18
|
+
import { fileURLToPath } from 'url';
|
|
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
|
+
function parseArgs(args) {
|
|
24
|
+
const projectPath = args.find(arg => !arg.startsWith('--')) || '.';
|
|
25
|
+
const configArg = args.find(arg => arg.startsWith('--config='));
|
|
26
|
+
const config = configArg?.split('=')[1] === 'strict' ? 'strict' : 'recommended';
|
|
27
|
+
const help = args.includes('--help') || args.includes('-h');
|
|
28
|
+
return { projectPath, config, help };
|
|
29
|
+
}
|
|
30
|
+
function printHelp() {
|
|
31
|
+
console.log(`
|
|
32
|
+
@invar/eslint-plugin - ESLint with Invar-specific rules
|
|
33
|
+
|
|
34
|
+
Usage:
|
|
35
|
+
node cli.js [path] [options]
|
|
36
|
+
|
|
37
|
+
Arguments:
|
|
38
|
+
path Project directory to lint (default: current directory)
|
|
39
|
+
|
|
40
|
+
Options:
|
|
41
|
+
--config=MODE Use 'recommended' or 'strict' preset (default: recommended)
|
|
42
|
+
--help, -h Show this help message
|
|
43
|
+
|
|
44
|
+
Examples:
|
|
45
|
+
node cli.js # Lint current directory (recommended mode)
|
|
46
|
+
node cli.js ./src # Lint specific directory
|
|
47
|
+
node cli.js --config=strict # Use strict mode (all rules as errors)
|
|
48
|
+
|
|
49
|
+
Output:
|
|
50
|
+
JSON format compatible with ESLint's --format=json
|
|
51
|
+
Exit code 0 if no errors, 1 if errors found
|
|
52
|
+
`);
|
|
53
|
+
}
|
|
54
|
+
async function main() {
|
|
55
|
+
const args = parseArgs(process.argv.slice(2));
|
|
56
|
+
if (args.help) {
|
|
57
|
+
printHelp();
|
|
58
|
+
process.exit(0);
|
|
59
|
+
}
|
|
60
|
+
const projectPath = resolve(args.projectPath);
|
|
61
|
+
// Validate resolved path is within current working directory or explicit allowed paths
|
|
62
|
+
// This prevents path traversal attacks via "../../../etc/passwd" patterns
|
|
63
|
+
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);
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
// Get the rules config for the selected mode
|
|
73
|
+
const selectedConfig = plugin.configs?.[args.config];
|
|
74
|
+
if (!selectedConfig || !selectedConfig.rules) {
|
|
75
|
+
console.error(`Config "${args.config}" not found or invalid`);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
// Create ESLint instance with programmatic configuration
|
|
79
|
+
// Set cwd to CLI directory so ESLint can find parser in our node_modules
|
|
80
|
+
const eslint = new ESLint({
|
|
81
|
+
useEslintrc: false, // Don't load .eslintrc files
|
|
82
|
+
cwd: __dirname, // Set working directory to CLI location for module resolution
|
|
83
|
+
baseConfig: {
|
|
84
|
+
parser: '@typescript-eslint/parser',
|
|
85
|
+
parserOptions: {
|
|
86
|
+
ecmaVersion: 2022,
|
|
87
|
+
sourceType: 'module',
|
|
88
|
+
},
|
|
89
|
+
plugins: ['@invar'],
|
|
90
|
+
rules: selectedConfig.rules,
|
|
91
|
+
},
|
|
92
|
+
plugins: {
|
|
93
|
+
'@invar': plugin, // Register our plugin programmatically
|
|
94
|
+
},
|
|
95
|
+
}); // Type assertion for ESLint config complexity
|
|
96
|
+
// Lint the project
|
|
97
|
+
const results = await eslint.lintFiles([projectPath]);
|
|
98
|
+
// Output in standard ESLint JSON format (compatible with guard_ts.py)
|
|
99
|
+
const formatter = await eslint.loadFormatter('json');
|
|
100
|
+
const resultText = await Promise.resolve(formatter.format(results, {
|
|
101
|
+
cwd: projectPath,
|
|
102
|
+
rulesMeta: eslint.getRulesMetaForResults(results),
|
|
103
|
+
}));
|
|
104
|
+
console.log(resultText);
|
|
105
|
+
// Exit with error code if there are errors
|
|
106
|
+
const hasErrors = results.some(result => result.errorCount > 0);
|
|
107
|
+
process.exit(hasErrors ? 1 : 0);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
// Sanitize error message to avoid leaking file paths or system information
|
|
111
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
112
|
+
console.error(`ESLint failed: ${errorMessage}`);
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
main();
|
|
117
|
+
//# sourceMappingURL=cli.js.map
|
invar/shell/commands/init.py
CHANGED
|
@@ -553,7 +553,8 @@ def init(
|
|
|
553
553
|
skipped: list[str] = []
|
|
554
554
|
|
|
555
555
|
# Add config file (.invar/config.toml or pyproject.toml)
|
|
556
|
-
|
|
556
|
+
# LX-05: Pass language for language-specific config generation
|
|
557
|
+
config_result = add_config(path, console, language)
|
|
557
558
|
if isinstance(config_result, Failure):
|
|
558
559
|
console.print(f"[red]Error:[/red] {config_result.failure()}")
|
|
559
560
|
raise typer.Exit(1)
|
invar/shell/prove/guard_ts.py
CHANGED
|
@@ -664,7 +664,9 @@ def _parse_tsc_line(line: str) -> TypeScriptViolation | None:
|
|
|
664
664
|
|
|
665
665
|
# @shell_complexity: CLI tool integration with JSON parsing and error handling
|
|
666
666
|
def run_eslint(project_path: Path) -> Result[list[TypeScriptViolation], str]:
|
|
667
|
-
"""Run ESLint
|
|
667
|
+
"""Run ESLint with @invar/eslint-plugin rules.
|
|
668
|
+
|
|
669
|
+
Uses @invar/eslint-plugin CLI which pre-loads Invar-specific rules.
|
|
668
670
|
|
|
669
671
|
Args:
|
|
670
672
|
project_path: Path to project root.
|
|
@@ -677,9 +679,12 @@ def run_eslint(project_path: Path) -> Result[list[TypeScriptViolation], str]:
|
|
|
677
679
|
return Failure(f"Project path does not exist: {project_path}")
|
|
678
680
|
|
|
679
681
|
try:
|
|
682
|
+
# Get command for @invar/eslint-plugin (embedded or local dev)
|
|
683
|
+
cmd = _get_invar_package_cmd("eslint-plugin", project_path)
|
|
684
|
+
cmd.append(str(project_path)) # Add project path as argument
|
|
685
|
+
|
|
680
686
|
result = subprocess.run(
|
|
681
|
-
|
|
682
|
-
cwd=project_path,
|
|
687
|
+
cmd,
|
|
683
688
|
capture_output=True,
|
|
684
689
|
text=True,
|
|
685
690
|
timeout=120,
|
|
@@ -748,6 +753,23 @@ def run_vitest(project_path: Path) -> Result[list[TypeScriptViolation], str]:
|
|
|
748
753
|
except json.JSONDecodeError:
|
|
749
754
|
pass
|
|
750
755
|
|
|
756
|
+
# LX-15 Phase 1: Generate doctests before running vitest
|
|
757
|
+
try:
|
|
758
|
+
doctest_result = subprocess.run(
|
|
759
|
+
["node", "scripts/generate-doctests.mjs", "doctest.config.json"],
|
|
760
|
+
cwd=project_path,
|
|
761
|
+
capture_output=True,
|
|
762
|
+
text=True,
|
|
763
|
+
timeout=60,
|
|
764
|
+
)
|
|
765
|
+
# Doctest generation failure is not fatal - continue with regular tests
|
|
766
|
+
if doctest_result.returncode != 0:
|
|
767
|
+
# Log warning but don't fail
|
|
768
|
+
pass
|
|
769
|
+
except (FileNotFoundError, subprocess.TimeoutExpired):
|
|
770
|
+
# Doctest generation not available or timed out - continue with regular tests
|
|
771
|
+
pass
|
|
772
|
+
|
|
751
773
|
try:
|
|
752
774
|
result = subprocess.run(
|
|
753
775
|
["npx", "vitest", "run", "--reporter=json"],
|
invar/shell/templates.py
CHANGED
|
@@ -11,7 +11,12 @@ from pathlib import Path
|
|
|
11
11
|
|
|
12
12
|
from returns.result import Failure, Result, Success
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
# =============================================================================
|
|
15
|
+
# Language-Specific Configurations (LX-05)
|
|
16
|
+
# =============================================================================
|
|
17
|
+
|
|
18
|
+
# Python configuration
|
|
19
|
+
_PYTHON_PYPROJECT_CONFIG = """\n# Invar Configuration
|
|
15
20
|
[tool.invar.guard]
|
|
16
21
|
core_paths = ["src/core"]
|
|
17
22
|
shell_paths = ["src/shell"]
|
|
@@ -23,7 +28,7 @@ forbidden_imports = ["os", "sys", "socket", "requests", "urllib", "subprocess",
|
|
|
23
28
|
exclude_paths = ["tests", "test", "scripts", ".venv", "venv", "__pycache__", ".pytest_cache", "node_modules", "dist", "build"]
|
|
24
29
|
"""
|
|
25
30
|
|
|
26
|
-
|
|
31
|
+
_PYTHON_INVAR_TOML = """# Invar Configuration (Python)
|
|
27
32
|
# For projects without pyproject.toml
|
|
28
33
|
|
|
29
34
|
[guard]
|
|
@@ -41,6 +46,37 @@ exclude_paths = ["tests", "test", "scripts", ".venv", "venv", "__pycache__", ".p
|
|
|
41
46
|
# shell_patterns = ["**/api/**", "**/cli/**"]
|
|
42
47
|
"""
|
|
43
48
|
|
|
49
|
+
# TypeScript configuration (LX-05)
|
|
50
|
+
_TYPESCRIPT_INVAR_TOML = """# Invar Configuration (TypeScript)
|
|
51
|
+
# For TypeScript/JavaScript projects
|
|
52
|
+
|
|
53
|
+
[guard]
|
|
54
|
+
core_paths = ["src/core"]
|
|
55
|
+
shell_paths = ["src/shell"]
|
|
56
|
+
max_file_lines = 500
|
|
57
|
+
max_function_lines = 50
|
|
58
|
+
require_contracts = true
|
|
59
|
+
require_doctests = false # TypeScript uses JSDoc examples instead
|
|
60
|
+
# TypeScript/Node.js I/O modules to forbid in Core
|
|
61
|
+
forbidden_imports = ["fs", "path", "http", "https", "net", "child_process", "os", "process"]
|
|
62
|
+
exclude_paths = ["tests", "test", "scripts", "node_modules", "dist", "build", ".next", "coverage"]
|
|
63
|
+
|
|
64
|
+
# Pattern-based classification (optional, takes priority over paths)
|
|
65
|
+
# core_patterns = ["**/domain/**", "**/models/**"]
|
|
66
|
+
# shell_patterns = ["**/api/**", "**/cli/**"]
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
# Backward compatibility alias
|
|
70
|
+
_DEFAULT_PYPROJECT_CONFIG = _PYTHON_PYPROJECT_CONFIG
|
|
71
|
+
_DEFAULT_INVAR_TOML = _PYTHON_INVAR_TOML
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _get_invar_config(language: str) -> str:
|
|
75
|
+
"""Get the appropriate config content for the language."""
|
|
76
|
+
if language == "typescript":
|
|
77
|
+
return _TYPESCRIPT_INVAR_TOML
|
|
78
|
+
return _PYTHON_INVAR_TOML
|
|
79
|
+
|
|
44
80
|
|
|
45
81
|
def get_template_path(name: str) -> Result[Path, str]:
|
|
46
82
|
"""Get path to a template file."""
|
|
@@ -75,10 +111,11 @@ def copy_template(
|
|
|
75
111
|
|
|
76
112
|
|
|
77
113
|
# @shell_complexity: Config addition with existing file detection
|
|
78
|
-
def add_config(path: Path, console) -> Result[bool, str]:
|
|
114
|
+
def add_config(path: Path, console, language: str = "python") -> Result[bool, str]:
|
|
79
115
|
"""Add configuration to project. Returns Success(True) if added, Success(False) if skipped.
|
|
80
116
|
|
|
81
117
|
DX-70: Creates .invar/config.toml instead of invar.toml for cleaner organization.
|
|
118
|
+
LX-05: Now generates language-specific config (Python vs TypeScript).
|
|
82
119
|
Backward compatible: still reads from invar.toml if it exists.
|
|
83
120
|
"""
|
|
84
121
|
pyproject = path / "pyproject.toml"
|
|
@@ -87,8 +124,8 @@ def add_config(path: Path, console) -> Result[bool, str]:
|
|
|
87
124
|
legacy_invar_toml = path / "invar.toml"
|
|
88
125
|
|
|
89
126
|
try:
|
|
90
|
-
# Priority 1: Add to pyproject.toml if it exists
|
|
91
|
-
if pyproject.exists():
|
|
127
|
+
# Priority 1: Add to pyproject.toml if it exists (Python projects only)
|
|
128
|
+
if pyproject.exists() and language == "python":
|
|
92
129
|
content = pyproject.read_text()
|
|
93
130
|
if "[tool.invar]" not in content:
|
|
94
131
|
with pyproject.open("a") as f:
|
|
@@ -102,9 +139,10 @@ def add_config(path: Path, console) -> Result[bool, str]:
|
|
|
102
139
|
return Success(False)
|
|
103
140
|
|
|
104
141
|
# Create .invar/config.toml (DX-70: new default location)
|
|
142
|
+
# LX-05: Use language-specific config
|
|
105
143
|
if not invar_config.exists():
|
|
106
144
|
invar_dir.mkdir(exist_ok=True)
|
|
107
|
-
invar_config.write_text(
|
|
145
|
+
invar_config.write_text(_get_invar_config(language))
|
|
108
146
|
console.print("[green]Created[/green] .invar/config.toml")
|
|
109
147
|
return Success(True)
|
|
110
148
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: invar-tools
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.16.0
|
|
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
|
|
@@ -52,9 +52,11 @@ invar/mcp/__init__.py,sha256=n3S7QwMjSMqOMT8cI2jf9E0yZPjKmBOJyIYhq4WZ8TQ,226
|
|
|
52
52
|
invar/mcp/__main__.py,sha256=ZcIT2U6xUyGOWucl4jq422BDE3lRLjqyxb9pFylRBdk,219
|
|
53
53
|
invar/mcp/handlers.py,sha256=b0LRWKMpu6lnjPV7SozH0cxKYJufVWy3eJhiAu3of-M,15947
|
|
54
54
|
invar/mcp/server.py,sha256=WmVNs2_AcOMbmp3tEgWR57hjqqJkMx3nV3z9fcNuSAA,20109
|
|
55
|
-
invar/node_tools
|
|
55
|
+
invar/node_tools/.gitignore,sha256=Tu_FtBhQTKPl9LHokxUTCTcxPadynDy6VPo0Z1WCBAQ,388
|
|
56
|
+
invar/node_tools/MANIFEST,sha256=2Z2at-27MK8K7DSjOjjtR4faTbt6eCiKQuEfvP_lwH8,145
|
|
56
57
|
invar/node_tools/__init__.py,sha256=HzILh3jtP28Lm2jZwss1SY65ECxbtw2J2uFpXQA6Y94,1740
|
|
57
58
|
invar/node_tools/ts-query.js,sha256=fEc_f0JT_Mb18dEoA4_vJoazvd7Lqv_rsed4eHSAbCg,13303
|
|
59
|
+
invar/node_tools/eslint-plugin/cli.js,sha256=TyBGCIZ0LiGIEjESRCh1VkY5ooLmrRbFY9dd5Vfzw9c,4647
|
|
58
60
|
invar/node_tools/fc-runner/cli.js,sha256=72_gIhvnx2peKITdzdnFWI5fzGaNTS3BcEqyS628cI0,243277
|
|
59
61
|
invar/node_tools/quick-check/cli.js,sha256=dwV3hdJleFQga2cKUn3PPfQDvvujhzKdjQcIvWsKgM0,66196
|
|
60
62
|
invar/node_tools/ts-analyzer/cli.js,sha256=SvZ6HyjmobpP8NAZqXFiy8BwH_t5Hb17Ytar_18udaQ,4092887
|
|
@@ -78,7 +80,7 @@ invar/shell/py_refs.py,sha256=Vjz50lmt9prDBcBv4nkkODdiJ7_DKu5zO4UPZBjAfmM,4638
|
|
|
78
80
|
invar/shell/skill_manager.py,sha256=Mr7Mh9rxPSKSAOTJCAM5ZHiG5nfUf6KQVCuD4LBNHSI,12440
|
|
79
81
|
invar/shell/subprocess_env.py,sha256=9oXl3eMEbzLsFEgMHqobEw6oW_wV0qMEP7pklwm58Pw,11453
|
|
80
82
|
invar/shell/template_engine.py,sha256=eNKMz7R8g9Xp3_1TGx-QH137jf52E0u3KaVcnotu1Tg,12056
|
|
81
|
-
invar/shell/templates.py,sha256=
|
|
83
|
+
invar/shell/templates.py,sha256=ilhGysbUcdkUFqPgv6ySVmKI3imS_cwYNCWTCdyb5cY,15407
|
|
82
84
|
invar/shell/testing.py,sha256=rTNBH0Okh2qtG9ohSXOz487baQ2gXrWT3s_WECW3HJs,11143
|
|
83
85
|
invar/shell/ts_compiler.py,sha256=nA8brnOhThj9J_J3vAEGjDsM4NjbWQ_eX8Yf4pHPOgk,6672
|
|
84
86
|
invar/shell/commands/__init__.py,sha256=MEkKwVyjI9DmkvBpJcuumXo2Pg_FFkfEr-Rr3nrAt7A,284
|
|
@@ -86,7 +88,7 @@ invar/shell/commands/doc.py,sha256=SOLDoCXXGxx_JU0PKXlAIGEF36PzconHmmAtL-rM6D4,1
|
|
|
86
88
|
invar/shell/commands/feedback.py,sha256=lLxEeWW_71US_vlmorFrGXS8IARB9nbV6D0zruLs660,7640
|
|
87
89
|
invar/shell/commands/guard.py,sha256=xTQ8cPp-x1xMCtufKxmMNUSpIpH31uUjziAB8ifCnC0,24837
|
|
88
90
|
invar/shell/commands/hooks.py,sha256=W-SOnT4VQyUvXwipozkJwgEYfiOJGz7wksrbcdWegUg,2356
|
|
89
|
-
invar/shell/commands/init.py,sha256=
|
|
91
|
+
invar/shell/commands/init.py,sha256=rtoPFsfq7xRZ6lfTipWT1OejNK5wfzqu1ncXi1kizU0,23634
|
|
90
92
|
invar/shell/commands/merge.py,sha256=nuvKo8m32-OL-SCQlS4SLKmOZxQ3qj-1nGCx1Pgzifw,8183
|
|
91
93
|
invar/shell/commands/mutate.py,sha256=GwemiO6LlbGCBEQsBFnzZuKhF-wIMEl79GAMnKUWc8U,5765
|
|
92
94
|
invar/shell/commands/perception.py,sha256=Vl6zgxkqtS3QRXBat6U_utNhpViyPFoPh899-OtDLgQ,19493
|
|
@@ -100,7 +102,7 @@ invar/shell/prove/__init__.py,sha256=ZqlbmyMFJf6yAle8634jFuPRv8wNvHps8loMlOJyf8A
|
|
|
100
102
|
invar/shell/prove/accept.py,sha256=cnY_6jzU1EBnpLF8-zWUWcXiSXtCwxPsXEYXsSVPG38,3717
|
|
101
103
|
invar/shell/prove/cache.py,sha256=jbNdrvfLjvK7S0iqugErqeabb4YIbQuwIlcSRyCKbcg,4105
|
|
102
104
|
invar/shell/prove/crosshair.py,sha256=XhJDsQWIriX9SuqeflUYvJgp9gJTDH7I7Uka6zjNzZ0,16734
|
|
103
|
-
invar/shell/prove/guard_ts.py,sha256=
|
|
105
|
+
invar/shell/prove/guard_ts.py,sha256=i0F_56_aIgtqzJF2pfRAYJ2Tyjsuv-xhT8N_ZsBfis8,32567
|
|
104
106
|
invar/shell/prove/hypothesis.py,sha256=QUclOOUg_VB6wbmHw8O2EPiL5qBOeBRqQeM04AVuLw0,9880
|
|
105
107
|
invar/templates/CLAUDE.md.template,sha256=eaGU3SyRO_NEifw5b26k3srgQH4jyeujjCJ-HbM36_w,4913
|
|
106
108
|
invar/templates/__init__.py,sha256=cb3ht8KPK5oBn5oG6HsTznujmo9WriJ_P--fVxJwycc,45
|
|
@@ -181,10 +183,10 @@ invar/templates/skills/invar-reflect/template.md,sha256=Rr5hvbllvmd8jSLf_0ZjyKt6
|
|
|
181
183
|
invar/templates/skills/investigate/SKILL.md.jinja,sha256=cp6TBEixBYh1rLeeHOR1yqEnFqv1NZYePORMnavLkQI,3231
|
|
182
184
|
invar/templates/skills/propose/SKILL.md.jinja,sha256=6BuKiCqO1AEu3VtzMHy1QWGqr_xqG9eJlhbsKT4jev4,3463
|
|
183
185
|
invar/templates/skills/review/SKILL.md.jinja,sha256=ET5mbdSe_eKgJbi2LbgFC-z1aviKcHOBw7J5Q28fr4U,14105
|
|
184
|
-
invar_tools-1.
|
|
185
|
-
invar_tools-1.
|
|
186
|
-
invar_tools-1.
|
|
187
|
-
invar_tools-1.
|
|
188
|
-
invar_tools-1.
|
|
189
|
-
invar_tools-1.
|
|
190
|
-
invar_tools-1.
|
|
186
|
+
invar_tools-1.16.0.dist-info/METADATA,sha256=JUYnszfz8YwiI3iRSXAlSnpVnCtBOtHGT5eeUb7w68w,28595
|
|
187
|
+
invar_tools-1.16.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
188
|
+
invar_tools-1.16.0.dist-info/entry_points.txt,sha256=RwH_EhqgtFPsnO6RcrwrAb70Zyfb8Mh6uUtztWnUxGk,102
|
|
189
|
+
invar_tools-1.16.0.dist-info/licenses/LICENSE,sha256=qeFksp4H4kfTgQxPCIu3OdagXyiZcgBlVfsQ6M5oFyk,10767
|
|
190
|
+
invar_tools-1.16.0.dist-info/licenses/LICENSE-GPL,sha256=IvZfC6ZbP7CLjytoHVzvpDZpD-Z3R_qa1GdMdWlWQ6Q,35157
|
|
191
|
+
invar_tools-1.16.0.dist-info/licenses/NOTICE,sha256=joEyMyFhFY8Vd8tTJ-a3SirI0m2Sd0WjzqYt3sdcglc,2561
|
|
192
|
+
invar_tools-1.16.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|