invar-tools 1.6.0__py3-none-any.whl → 1.7.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.
- invar/core/utils.py +3 -1
- invar/shell/claude_hooks.py +90 -0
- invar/shell/commands/guard.py +2 -0
- invar/shell/commands/init.py +303 -384
- invar/shell/commands/uninstall.py +479 -0
- invar/shell/contract_coverage.py +4 -1
- invar/shell/templates.py +36 -99
- invar/templates/commands/audit.md +6 -0
- invar/templates/commands/guard.md +6 -0
- invar/templates/config/pre-commit.yaml.jinja +2 -0
- {invar_tools-1.6.0.dist-info → invar_tools-1.7.1.dist-info}/METADATA +55 -45
- {invar_tools-1.6.0.dist-info → invar_tools-1.7.1.dist-info}/RECORD +17 -19
- invar/templates/aider.conf.yml.template +0 -31
- invar/templates/cursorrules.template +0 -40
- invar/templates/pre-commit-config.yaml.template +0 -44
- {invar_tools-1.6.0.dist-info → invar_tools-1.7.1.dist-info}/WHEEL +0 -0
- {invar_tools-1.6.0.dist-info → invar_tools-1.7.1.dist-info}/entry_points.txt +0 -0
- {invar_tools-1.6.0.dist-info → invar_tools-1.7.1.dist-info}/licenses/LICENSE +0 -0
- {invar_tools-1.6.0.dist-info → invar_tools-1.7.1.dist-info}/licenses/LICENSE-GPL +0 -0
- {invar_tools-1.6.0.dist-info → invar_tools-1.7.1.dist-info}/licenses/NOTICE +0 -0
invar/shell/templates.py
CHANGED
|
@@ -76,11 +76,18 @@ def copy_template(
|
|
|
76
76
|
|
|
77
77
|
# @shell_complexity: Config addition with existing file detection
|
|
78
78
|
def add_config(path: Path, console) -> Result[bool, str]:
|
|
79
|
-
"""Add configuration to project. Returns Success(True) if added, Success(False) if skipped.
|
|
79
|
+
"""Add configuration to project. Returns Success(True) if added, Success(False) if skipped.
|
|
80
|
+
|
|
81
|
+
DX-70: Creates .invar/config.toml instead of invar.toml for cleaner organization.
|
|
82
|
+
Backward compatible: still reads from invar.toml if it exists.
|
|
83
|
+
"""
|
|
80
84
|
pyproject = path / "pyproject.toml"
|
|
81
|
-
|
|
85
|
+
invar_dir = path / ".invar"
|
|
86
|
+
invar_config = invar_dir / "config.toml"
|
|
87
|
+
legacy_invar_toml = path / "invar.toml"
|
|
82
88
|
|
|
83
89
|
try:
|
|
90
|
+
# Priority 1: Add to pyproject.toml if it exists
|
|
84
91
|
if pyproject.exists():
|
|
85
92
|
content = pyproject.read_text()
|
|
86
93
|
if "[tool.invar]" not in content:
|
|
@@ -90,9 +97,15 @@ def add_config(path: Path, console) -> Result[bool, str]:
|
|
|
90
97
|
return Success(True)
|
|
91
98
|
return Success(False)
|
|
92
99
|
|
|
93
|
-
if
|
|
94
|
-
|
|
95
|
-
|
|
100
|
+
# Skip if legacy invar.toml exists (backward compatibility)
|
|
101
|
+
if legacy_invar_toml.exists():
|
|
102
|
+
return Success(False)
|
|
103
|
+
|
|
104
|
+
# Create .invar/config.toml (DX-70: new default location)
|
|
105
|
+
if not invar_config.exists():
|
|
106
|
+
invar_dir.mkdir(exist_ok=True)
|
|
107
|
+
invar_config.write_text(_DEFAULT_INVAR_TOML)
|
|
108
|
+
console.print("[green]Created[/green] .invar/config.toml")
|
|
96
109
|
return Success(True)
|
|
97
110
|
|
|
98
111
|
return Success(False)
|
|
@@ -187,30 +200,17 @@ def copy_skills_directory(dest: Path, console) -> Result[bool, str]:
|
|
|
187
200
|
return Failure(f"Failed to copy skills: {e}")
|
|
188
201
|
|
|
189
202
|
|
|
190
|
-
# Agent configuration
|
|
203
|
+
# Agent configuration - Claude Code only (DX-69: simplified, cursor/aider removed)
|
|
191
204
|
AGENT_CONFIGS = {
|
|
192
205
|
"claude": {
|
|
193
206
|
"file": "CLAUDE.md",
|
|
194
207
|
"template": "CLAUDE.md.template",
|
|
195
|
-
"reference": '> **Protocol:** Follow [INVAR.md](./INVAR.md) for the Invar development methodology.\n',
|
|
196
|
-
"check_pattern": "INVAR.md",
|
|
197
|
-
},
|
|
198
|
-
"cursor": {
|
|
199
|
-
"file": ".cursorrules",
|
|
200
|
-
"template": "cursorrules.template",
|
|
201
|
-
"reference": "Follow the Invar Protocol in INVAR.md.\n\n",
|
|
202
|
-
"check_pattern": "INVAR.md",
|
|
203
|
-
},
|
|
204
|
-
"aider": {
|
|
205
|
-
"file": ".aider.conf.yml",
|
|
206
|
-
"template": "aider.conf.yml.template",
|
|
207
|
-
"reference": "# Follow the Invar Protocol in INVAR.md\nread:\n - INVAR.md\n",
|
|
208
208
|
"check_pattern": "INVAR.md",
|
|
209
209
|
},
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
|
|
213
|
-
# @shell_complexity:
|
|
213
|
+
# @shell_complexity: Multi-agent config detection with file existence checks
|
|
214
214
|
def detect_agent_configs(path: Path) -> Result[dict[str, str], str]:
|
|
215
215
|
"""
|
|
216
216
|
Detect existing agent configuration files.
|
|
@@ -244,61 +244,6 @@ def detect_agent_configs(path: Path) -> Result[dict[str, str], str]:
|
|
|
244
244
|
return Failure(f"Failed to detect agent configs: {e}")
|
|
245
245
|
|
|
246
246
|
|
|
247
|
-
# @shell_complexity: Reference addition with existing check
|
|
248
|
-
def add_invar_reference(path: Path, agent: str, console) -> Result[bool, str]:
|
|
249
|
-
"""Add Invar reference to an existing agent config file."""
|
|
250
|
-
if agent not in AGENT_CONFIGS:
|
|
251
|
-
return Failure(f"Unknown agent: {agent}")
|
|
252
|
-
|
|
253
|
-
config = AGENT_CONFIGS[agent]
|
|
254
|
-
config_path = path / config["file"]
|
|
255
|
-
|
|
256
|
-
if not config_path.exists():
|
|
257
|
-
return Failure(f"Config file not found: {config['file']}")
|
|
258
|
-
|
|
259
|
-
try:
|
|
260
|
-
content = config_path.read_text()
|
|
261
|
-
if config["check_pattern"] in content:
|
|
262
|
-
return Success(False) # Already configured
|
|
263
|
-
|
|
264
|
-
# Prepend reference
|
|
265
|
-
new_content = config["reference"] + content
|
|
266
|
-
config_path.write_text(new_content)
|
|
267
|
-
console.print(f"[green]Updated[/green] {config['file']} (added Invar reference)")
|
|
268
|
-
return Success(True)
|
|
269
|
-
except OSError as e:
|
|
270
|
-
return Failure(f"Failed to update {config['file']}: {e}")
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
# @shell_complexity: Config creation with template selection
|
|
274
|
-
def create_agent_config(path: Path, agent: str, console) -> Result[bool, str]:
|
|
275
|
-
"""
|
|
276
|
-
Create agent config from template (DX-17).
|
|
277
|
-
|
|
278
|
-
Creates full template file for agents that don't have an existing config.
|
|
279
|
-
"""
|
|
280
|
-
if agent not in AGENT_CONFIGS:
|
|
281
|
-
return Failure(f"Unknown agent: {agent}")
|
|
282
|
-
|
|
283
|
-
config = AGENT_CONFIGS[agent]
|
|
284
|
-
config_path = path / config["file"]
|
|
285
|
-
|
|
286
|
-
if config_path.exists():
|
|
287
|
-
return Success(False) # Already exists
|
|
288
|
-
|
|
289
|
-
# Use template if available
|
|
290
|
-
template_name = config.get("template")
|
|
291
|
-
if template_name:
|
|
292
|
-
result = copy_template(template_name, path, config["file"])
|
|
293
|
-
if isinstance(result, Success) and result.unwrap():
|
|
294
|
-
console.print(f"[green]Created[/green] {config['file']} (Invar workflow enforcement)")
|
|
295
|
-
return Success(True)
|
|
296
|
-
elif isinstance(result, Failure):
|
|
297
|
-
return result
|
|
298
|
-
|
|
299
|
-
return Success(False)
|
|
300
|
-
|
|
301
|
-
|
|
302
247
|
# @shell_complexity: MCP server config with JSON manipulation
|
|
303
248
|
def configure_mcp_server(path: Path, console) -> Result[list[str], str]:
|
|
304
249
|
"""
|
|
@@ -461,36 +406,28 @@ The server communicates via stdio and should be managed by your AI agent.
|
|
|
461
406
|
|
|
462
407
|
# @shell_complexity: Git hooks installation with backup
|
|
463
408
|
def install_hooks(path: Path, console) -> Result[bool, str]:
|
|
464
|
-
"""
|
|
409
|
+
"""Run 'pre-commit install' if config exists (file created by sync_templates)."""
|
|
465
410
|
import subprocess
|
|
466
411
|
|
|
467
412
|
pre_commit_config = path / ".pre-commit-config.yaml"
|
|
468
413
|
|
|
469
|
-
if pre_commit_config.exists():
|
|
470
|
-
|
|
414
|
+
if not pre_commit_config.exists():
|
|
415
|
+
# File should be created by sync_templates; skip if missing
|
|
471
416
|
return Success(False)
|
|
472
417
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
subprocess.run(
|
|
483
|
-
["pre-commit", "install"],
|
|
484
|
-
cwd=path,
|
|
485
|
-
check=True,
|
|
486
|
-
capture_output=True,
|
|
487
|
-
)
|
|
488
|
-
console.print("[green]Installed[/green] pre-commit hooks")
|
|
489
|
-
except FileNotFoundError:
|
|
490
|
-
console.print("[dim]Run: pre-commit install (pre-commit not in PATH)[/dim]")
|
|
491
|
-
except subprocess.CalledProcessError:
|
|
492
|
-
console.print("[dim]Run: pre-commit install (not a git repo?)[/dim]")
|
|
493
|
-
|
|
418
|
+
# Auto-install hooks (Automatic > Opt-in)
|
|
419
|
+
try:
|
|
420
|
+
subprocess.run(
|
|
421
|
+
["pre-commit", "install"],
|
|
422
|
+
cwd=path,
|
|
423
|
+
check=True,
|
|
424
|
+
capture_output=True,
|
|
425
|
+
)
|
|
426
|
+
console.print("[green]Installed[/green] pre-commit hooks")
|
|
494
427
|
return Success(True)
|
|
428
|
+
except FileNotFoundError:
|
|
429
|
+
console.print("[dim]Run: pre-commit install (pre-commit not in PATH)[/dim]")
|
|
430
|
+
except subprocess.CalledProcessError:
|
|
431
|
+
console.print("[dim]Run: pre-commit install (not a git repo?)[/dim]")
|
|
495
432
|
|
|
496
433
|
return Success(False)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: invar-tools
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.7.1
|
|
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
|
|
@@ -28,6 +28,7 @@ Requires-Dist: jinja2>=3.0
|
|
|
28
28
|
Requires-Dist: mcp>=1.0
|
|
29
29
|
Requires-Dist: pre-commit>=3.0
|
|
30
30
|
Requires-Dist: pydantic>=2.0
|
|
31
|
+
Requires-Dist: questionary>=2.0
|
|
31
32
|
Requires-Dist: returns>=0.20
|
|
32
33
|
Requires-Dist: rich>=13.0
|
|
33
34
|
Requires-Dist: typer>=0.9
|
|
@@ -129,35 +130,24 @@ Guard passed.
|
|
|
129
130
|
|
|
130
131
|
**Why uvx?** Always uses latest version, doesn't pollute project dependencies, auto-detects your project's venv.
|
|
131
132
|
|
|
132
|
-
###
|
|
133
|
+
### 🎯 Setup
|
|
133
134
|
|
|
134
135
|
```bash
|
|
135
|
-
# 1. Enter your project directory
|
|
136
136
|
cd your-project
|
|
137
137
|
|
|
138
|
-
#
|
|
138
|
+
# Interactive mode - choose what to install
|
|
139
|
+
uvx invar-tools init
|
|
140
|
+
|
|
141
|
+
# Or quick setup for Claude Code (skip prompts)
|
|
139
142
|
uvx invar-tools init --claude
|
|
140
143
|
|
|
141
|
-
#
|
|
144
|
+
# Add runtime contracts to your project
|
|
142
145
|
pip install invar-runtime
|
|
143
|
-
# Or add to pyproject.toml: dependencies = ["invar-runtime"]
|
|
144
|
-
|
|
145
|
-
# 4. Start coding with AI
|
|
146
146
|
```
|
|
147
147
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
```bash
|
|
151
|
-
cd your-project
|
|
152
|
-
|
|
153
|
-
# Update managed files, preserve your customizations
|
|
154
|
-
uvx invar-tools init --claude
|
|
155
|
-
|
|
156
|
-
# Or without Claude Code integration
|
|
157
|
-
uvx invar-tools init
|
|
158
|
-
```
|
|
148
|
+
**Safe and idempotent** — Run `invar init` anytime. It always **merges** with existing files, preserving your content.
|
|
159
149
|
|
|
160
|
-
|
|
150
|
+
> 💡 **After `claude /init`?** Just run `invar init` again to restore Invar configuration.
|
|
161
151
|
|
|
162
152
|
### 💬 Example Interaction
|
|
163
153
|
|
|
@@ -375,39 +365,57 @@ AlphaCodium · Parsel · Reflexion · Clover
|
|
|
375
365
|
|
|
376
366
|
---
|
|
377
367
|
|
|
378
|
-
## 🖥️
|
|
368
|
+
## 🖥️ Agent Support
|
|
369
|
+
|
|
370
|
+
| Agent | Status | Setup |
|
|
371
|
+
|-------|--------|-------|
|
|
372
|
+
| **Claude Code** | ✅ Full | `invar init` → select Claude Code |
|
|
373
|
+
| **Pi / Cursor** | 🚧 In progress | `invar init` → select Other, include `AGENT.md` in prompt |
|
|
374
|
+
| **Other** | 📝 Manual | `invar init` → select Other, include `AGENT.md` in prompt |
|
|
379
375
|
|
|
380
|
-
|
|
381
|
-
|---------|-------------|---------------|
|
|
382
|
-
| CLI verification (`invar guard`) | ✅ | ✅ |
|
|
383
|
-
| Protocol document (INVAR.md) | ✅ | ✅ |
|
|
384
|
-
| MCP tool integration | ✅ Auto-configured | Manual setup possible |
|
|
385
|
-
| Workflow skills | ✅ Auto-configured | Include in system prompt |
|
|
386
|
-
| Pre-commit hooks | ✅ | ✅ |
|
|
387
|
-
| Sub-agent review | ✅ | — |
|
|
376
|
+
### Claude Code (Full Experience)
|
|
388
377
|
|
|
389
|
-
|
|
378
|
+
All features auto-configured:
|
|
379
|
+
- MCP tools (`invar_guard`, `invar_sig`, `invar_map`)
|
|
380
|
+
- Workflow skills (`/develop`, `/review`, `/investigate`, `/propose`)
|
|
381
|
+
- Claude Code hooks (tool guidance, verification reminders)
|
|
382
|
+
- Pre-commit hooks
|
|
390
383
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
384
|
+
### Pi / Cursor (In Progress)
|
|
385
|
+
|
|
386
|
+
Currently available:
|
|
387
|
+
- Protocol document (INVAR.md)
|
|
388
|
+
- CLI verification (`invar guard`)
|
|
389
|
+
- Pre-commit hooks
|
|
390
|
+
- MCP server (manual configuration)
|
|
391
|
+
|
|
392
|
+
### Other Editors (Manual)
|
|
393
|
+
|
|
394
|
+
1. Run `invar init` → select "Other (AGENT.md)"
|
|
395
|
+
2. Include generated `AGENT.md` in your agent's prompt
|
|
396
|
+
3. Configure MCP server if supported
|
|
397
|
+
4. Use CLI commands (`invar guard`) for verification
|
|
395
398
|
|
|
396
399
|
---
|
|
397
400
|
|
|
398
401
|
## 📂 What Gets Installed
|
|
399
402
|
|
|
400
|
-
`invar init
|
|
403
|
+
`invar init` creates (select in interactive mode):
|
|
404
|
+
|
|
405
|
+
| File/Directory | Purpose | Category |
|
|
406
|
+
|----------------|---------|----------|
|
|
407
|
+
| `INVAR.md` | Protocol for AI agents | Required |
|
|
408
|
+
| `.invar/` | Config, context, examples | Required |
|
|
409
|
+
| `.pre-commit-config.yaml` | Verification before commit | Optional |
|
|
410
|
+
| `src/core/`, `src/shell/` | Recommended structure | Optional |
|
|
411
|
+
| `CLAUDE.md` | Agent instructions | Claude Code |
|
|
412
|
+
| `.claude/skills/` | Workflow automation | Claude Code |
|
|
413
|
+
| `.claude/commands/` | User commands (/audit, /guard) | Claude Code |
|
|
414
|
+
| `.claude/hooks/` | Tool guidance | Claude Code |
|
|
415
|
+
| `.mcp.json` | MCP server config | Claude Code |
|
|
416
|
+
| `AGENT.md` | Universal agent instructions | Other agents |
|
|
401
417
|
|
|
402
|
-
|
|
403
|
-
|----------------|---------|-----------|
|
|
404
|
-
| `INVAR.md` | Protocol for AI agents | No (managed) |
|
|
405
|
-
| `CLAUDE.md` | Project configuration | Yes |
|
|
406
|
-
| `.claude/skills/` | Workflow skills | Yes |
|
|
407
|
-
| `.claude/hooks/` | Tool call interception | Yes |
|
|
408
|
-
| `.invar/examples/` | Reference patterns | No (managed) |
|
|
409
|
-
| `.invar/context.md` | Project state, lessons | Yes |
|
|
410
|
-
| `pyproject.toml` | `[tool.invar]` section | Yes |
|
|
418
|
+
**Note:** If `pyproject.toml` exists, Guard configuration goes there as `[tool.invar.guard]` instead of `.invar/config.toml`.
|
|
411
419
|
|
|
412
420
|
**Recommended structure:**
|
|
413
421
|
|
|
@@ -473,7 +481,9 @@ rules = ["missing_contract", "shell_result"]
|
|
|
473
481
|
| `invar guard` | Full verification (static + doctest + property + symbolic) |
|
|
474
482
|
| `invar guard --changed` | Only git-modified files |
|
|
475
483
|
| `invar guard --static` | Static analysis only (~0.5s) |
|
|
476
|
-
| `invar init` | Initialize or update project |
|
|
484
|
+
| `invar init` | Initialize or update project (interactive) |
|
|
485
|
+
| `invar init --claude` | Quick setup for Claude Code |
|
|
486
|
+
| `invar uninstall` | Remove Invar from project (preserves user content) |
|
|
477
487
|
| `invar sig <file>` | Show signatures and contracts |
|
|
478
488
|
| `invar map` | Symbol map with reference counts |
|
|
479
489
|
| `invar rules` | List all rules |
|
|
@@ -30,7 +30,7 @@ invar/core/tautology.py,sha256=Pmn__a0Bt55W0lAQo1G5q8Ory9KuE23dRknKw45xxbs,9221
|
|
|
30
30
|
invar/core/template_parser.py,sha256=vH3H8OX55scZ1hWh3xoA8oJMhgleKufCOhkTvsSuu_4,14730
|
|
31
31
|
invar/core/timeout_inference.py,sha256=BS2fJGmwOrLpYZUku4qrizgNDSIXVLFBslW-6sRAvpc,3451
|
|
32
32
|
invar/core/trivial_detection.py,sha256=KYP8jJb7QDeusAxFdX5NAML_H0NL5wLgMeBWDQmNqfU,6086
|
|
33
|
-
invar/core/utils.py,sha256=
|
|
33
|
+
invar/core/utils.py,sha256=PyW8dcTLUEFD81xcvkz-LNnCwjIQefn08OUh23fM_Po,14266
|
|
34
34
|
invar/core/verification_routing.py,sha256=_jXi1txFCcUdnB3-Yavtuyk8N-XhEO_Vu_051Vuz27Y,5020
|
|
35
35
|
invar/core/patterns/__init__.py,sha256=79a3ucN0BI54RnIOe49lngKASpADygs1hll9ROCrP6s,1429
|
|
36
36
|
invar/core/patterns/detector.py,sha256=lZ2HPtDJDiGps8Y3e7jds3naZa1oGqDDscHRSX5Vv0s,8297
|
|
@@ -45,9 +45,9 @@ invar/mcp/__init__.py,sha256=n3S7QwMjSMqOMT8cI2jf9E0yZPjKmBOJyIYhq4WZ8TQ,226
|
|
|
45
45
|
invar/mcp/__main__.py,sha256=ZcIT2U6xUyGOWucl4jq422BDE3lRLjqyxb9pFylRBdk,219
|
|
46
46
|
invar/mcp/server.py,sha256=ay-w2YfSa1kTmBFx3x3jEgmNRC3NFEW0EYuZRt7M39w,12244
|
|
47
47
|
invar/shell/__init__.py,sha256=FFw1mNbh_97PeKPcHIqQpQ7mw-JoIvyLM1yOdxLw5uk,204
|
|
48
|
-
invar/shell/claude_hooks.py,sha256=
|
|
48
|
+
invar/shell/claude_hooks.py,sha256=KJAQ-a7-mvabJ2fgsC9wPMakvi7J43GCU6ZcpWwKYFg,16180
|
|
49
49
|
invar/shell/config.py,sha256=6-kbo6--SxfROXoyU-v7InSLR8f_U1Mar_xEOdCXFkY,17633
|
|
50
|
-
invar/shell/contract_coverage.py,sha256=
|
|
50
|
+
invar/shell/contract_coverage.py,sha256=UPn-lEqrAFu00fl7v9PnSvNwS7KX3_SV1K_GhynQ9cw,12023
|
|
51
51
|
invar/shell/coverage.py,sha256=m01o898IFIdBztEBQLwwL1Vt5PWrpUntO4lv4nWEkls,11344
|
|
52
52
|
invar/shell/fs.py,sha256=wVD7DPWsCIJXuTyY_pi-5_LS82mXRdn_grJCOLn9zpU,3699
|
|
53
53
|
invar/shell/git.py,sha256=s6RQxEDQuLrmK3mru88EoYP8__4hiFW8AozlcxmY47E,2784
|
|
@@ -59,18 +59,19 @@ invar/shell/pattern_integration.py,sha256=pRcjfq3NvMW_tvQCnaXZnD1k5AVEWK8CYOE2jN
|
|
|
59
59
|
invar/shell/property_tests.py,sha256=N9JreyH5PqR89oF5yLcX7ZAV-Koyg5BKo-J05-GUPsA,9109
|
|
60
60
|
invar/shell/subprocess_env.py,sha256=9oXl3eMEbzLsFEgMHqobEw6oW_wV0qMEP7pklwm58Pw,11453
|
|
61
61
|
invar/shell/template_engine.py,sha256=IzOiGsKVFo0lDUdtg27wMzIJJKToclv151RDZuDnHHo,11027
|
|
62
|
-
invar/shell/templates.py,sha256=
|
|
62
|
+
invar/shell/templates.py,sha256=30eT61HXPA6DmsgUyUqljZNGGtB9TSR-aAaI4fmKAco,13722
|
|
63
63
|
invar/shell/testing.py,sha256=rTNBH0Okh2qtG9ohSXOz487baQ2gXrWT3s_WECW3HJs,11143
|
|
64
64
|
invar/shell/commands/__init__.py,sha256=MEkKwVyjI9DmkvBpJcuumXo2Pg_FFkfEr-Rr3nrAt7A,284
|
|
65
|
-
invar/shell/commands/guard.py,sha256=
|
|
65
|
+
invar/shell/commands/guard.py,sha256=vDBGOFb9mQ1D8eXrMvQB505GpjO1XLeCLrv2ig9-6dU,21718
|
|
66
66
|
invar/shell/commands/hooks.py,sha256=W-SOnT4VQyUvXwipozkJwgEYfiOJGz7wksrbcdWegUg,2356
|
|
67
|
-
invar/shell/commands/init.py,sha256=
|
|
67
|
+
invar/shell/commands/init.py,sha256=wAPPIDpoJyNOhrD09LldRg8w76mWv0r5qTcqlPWc920,13411
|
|
68
68
|
invar/shell/commands/merge.py,sha256=nuvKo8m32-OL-SCQlS4SLKmOZxQ3qj-1nGCx1Pgzifw,8183
|
|
69
69
|
invar/shell/commands/mutate.py,sha256=GwemiO6LlbGCBEQsBFnzZuKhF-wIMEl79GAMnKUWc8U,5765
|
|
70
70
|
invar/shell/commands/perception.py,sha256=TyH_HpqyKkmE3-zcU4YyBG8ghwJaSFeRC-OQMVBDTbQ,3837
|
|
71
71
|
invar/shell/commands/sync_self.py,sha256=nmqBry7V2_enKwy2zzHg8UoedZNicLe3yKDhjmBeZ68,3880
|
|
72
72
|
invar/shell/commands/template_sync.py,sha256=wVZ-UvJ1wpN2UBcWMfbei0n46XHYx-zRbMA2oX6FSi4,13723
|
|
73
73
|
invar/shell/commands/test.py,sha256=goMf-ovvzEyWQMheq4YlJ-mwK5-w3lDj0cq0IA_1-_c,4205
|
|
74
|
+
invar/shell/commands/uninstall.py,sha256=u1fqE2jCod2KxFMEYbtC4UFK1zuxzoaQKQzZdAjQcDE,17368
|
|
74
75
|
invar/shell/commands/update.py,sha256=0V5F8vxQ6PHPHPVYDmxdRD7xXeQEFypiJMYpY5ryiek,1349
|
|
75
76
|
invar/shell/prove/__init__.py,sha256=ZqlbmyMFJf6yAle8634jFuPRv8wNvHps8loMlOJyf8A,240
|
|
76
77
|
invar/shell/prove/accept.py,sha256=cnY_6jzU1EBnpLF8-zWUWcXiSXtCwxPsXEYXsSVPG38,3717
|
|
@@ -79,17 +80,14 @@ invar/shell/prove/crosshair.py,sha256=4Z_iIYBlkp-I6FqSYZa89wWB09V4Ouw2PduYhTn6rf
|
|
|
79
80
|
invar/shell/prove/hypothesis.py,sha256=QUclOOUg_VB6wbmHw8O2EPiL5qBOeBRqQeM04AVuLw0,9880
|
|
80
81
|
invar/templates/CLAUDE.md.template,sha256=eaGU3SyRO_NEifw5b26k3srgQH4jyeujjCJ-HbM36_w,4913
|
|
81
82
|
invar/templates/__init__.py,sha256=cb3ht8KPK5oBn5oG6HsTznujmo9WriJ_P--fVxJwycc,45
|
|
82
|
-
invar/templates/aider.conf.yml.template,sha256=4xzSs3BXzFJvwdhnWbmzSY0yCbfx5oxqnV8ZjehqHBg,853
|
|
83
83
|
invar/templates/context.md.template,sha256=FKyI1ghpqcf4wftyv9-auIFHor8Nm8lETN45Ja-L8Og,2386
|
|
84
|
-
invar/templates/cursorrules.template,sha256=N6AiEJRJHGkHm2tswh3PnZ_07ozeyQQI8iEOGK5Aqoc,1023
|
|
85
84
|
invar/templates/manifest.toml,sha256=cEe7yEOOeaLmOF-PrwZXxiPGjHhsSJYkWBKRHDmSbac,4268
|
|
86
|
-
invar/templates/pre-commit-config.yaml.template,sha256=2qWY3E8iDUqi85jE_X7y0atE88YOlL5IZ93wkjCgQGo,1737
|
|
87
85
|
invar/templates/proposal.md.template,sha256=UP7SpQ7gk8jVlHGLQCSQ5c-kCj1DBQEz8M-vEStK77I,1573
|
|
88
|
-
invar/templates/commands/audit.md,sha256=
|
|
89
|
-
invar/templates/commands/guard.md,sha256=
|
|
86
|
+
invar/templates/commands/audit.md,sha256=OrotO8420zTKnlNyAyL1Eos0VIaihzEU4AHdfDv68Oc,4162
|
|
87
|
+
invar/templates/commands/guard.md,sha256=N_C_AXd9kI85W1B0aTEycjiDp_jdaP8eeq8O0FQ_WQ8,1227
|
|
90
88
|
invar/templates/config/CLAUDE.md.jinja,sha256=VbtDWxn3H8qiE9-DV1hlG3DJ-GcBQU4ZiUHbFh6Bxxk,7814
|
|
91
89
|
invar/templates/config/context.md.jinja,sha256=_kJ8erEQNJMLDCKrv4BXWkO6OaGzE-zW9biCf7144aY,3103
|
|
92
|
-
invar/templates/config/pre-commit.yaml.jinja,sha256=
|
|
90
|
+
invar/templates/config/pre-commit.yaml.jinja,sha256=nUPxLxkTHAgZwhFAuOMDbZ8v0NQV9FlQPbr2MDEOsoA,1778
|
|
93
91
|
invar/templates/examples/README.md,sha256=xMcJZ1KEcfLJi5Ope_4FIbqDWKK3mRleAgllvgeNT6I,572
|
|
94
92
|
invar/templates/examples/conftest.py,sha256=uKA4NR7nyZWeSzY0URdZtw5zCcJpU32jNcaSKrI1Mxc,152
|
|
95
93
|
invar/templates/examples/contracts.py,sha256=uqJ6Y1GADo246MjFKoLY-_2E74cfBQsLO4vTqYcR81c,3241
|
|
@@ -105,10 +103,10 @@ invar/templates/skills/develop/SKILL.md.jinja,sha256=3coPSZGh1-YKN9Xc_xcEkfEP3S0
|
|
|
105
103
|
invar/templates/skills/investigate/SKILL.md.jinja,sha256=bOLdLMH5WUVBYOo4NpsfyvI6xx7I1lCNr_X-8bMe_kg,2744
|
|
106
104
|
invar/templates/skills/propose/SKILL.md.jinja,sha256=_iDLYN6-cfzA8n0_8sv-Dnpm1xq9IIpcDyM10mU2WUA,2420
|
|
107
105
|
invar/templates/skills/review/SKILL.md.jinja,sha256=e7HULz1jjLOlk2LYejQMk2F-cu7dDIwvh6lWNjx3j-Q,14123
|
|
108
|
-
invar_tools-1.
|
|
109
|
-
invar_tools-1.
|
|
110
|
-
invar_tools-1.
|
|
111
|
-
invar_tools-1.
|
|
112
|
-
invar_tools-1.
|
|
113
|
-
invar_tools-1.
|
|
114
|
-
invar_tools-1.
|
|
106
|
+
invar_tools-1.7.1.dist-info/METADATA,sha256=dBk4N2qRISfYrc6Rr66eY08_me9Rqfyq34RDBCaEj1s,17600
|
|
107
|
+
invar_tools-1.7.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
108
|
+
invar_tools-1.7.1.dist-info/entry_points.txt,sha256=RwH_EhqgtFPsnO6RcrwrAb70Zyfb8Mh6uUtztWnUxGk,102
|
|
109
|
+
invar_tools-1.7.1.dist-info/licenses/LICENSE,sha256=qeFksp4H4kfTgQxPCIu3OdagXyiZcgBlVfsQ6M5oFyk,10767
|
|
110
|
+
invar_tools-1.7.1.dist-info/licenses/LICENSE-GPL,sha256=IvZfC6ZbP7CLjytoHVzvpDZpD-Z3R_qa1GdMdWlWQ6Q,35157
|
|
111
|
+
invar_tools-1.7.1.dist-info/licenses/NOTICE,sha256=joEyMyFhFY8Vd8tTJ-a3SirI0m2Sd0WjzqYt3sdcglc,2561
|
|
112
|
+
invar_tools-1.7.1.dist-info/RECORD,,
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# Invar Protocol Configuration for Aider
|
|
2
|
-
# Follow the Invar Protocol in INVAR.md
|
|
3
|
-
|
|
4
|
-
# Auto-read protocol files at session start
|
|
5
|
-
read:
|
|
6
|
-
- INVAR.md
|
|
7
|
-
- .invar/examples/contracts.py
|
|
8
|
-
- .invar/examples/core_shell.py
|
|
9
|
-
- .invar/context.md
|
|
10
|
-
|
|
11
|
-
# System prompt addition
|
|
12
|
-
system-prompt: |
|
|
13
|
-
Follow the Invar Protocol in INVAR.md.
|
|
14
|
-
|
|
15
|
-
## Check-In
|
|
16
|
-
Your first message MUST display:
|
|
17
|
-
✓ Check-In: [project] | [branch] | [clean/dirty]
|
|
18
|
-
|
|
19
|
-
Read .invar/context.md first. Do NOT run guard/map at Check-In.
|
|
20
|
-
This is your sign-in. No visible check-in = Session not started.
|
|
21
|
-
|
|
22
|
-
## Final
|
|
23
|
-
Your last message MUST display:
|
|
24
|
-
✓ Final: guard PASS | 0 errors, 2 warnings
|
|
25
|
-
|
|
26
|
-
Execute: invar guard
|
|
27
|
-
This is your sign-out. Completes the Check-In/Final pair.
|
|
28
|
-
|
|
29
|
-
## Workflow (USBV)
|
|
30
|
-
Understand → Specify → Build → Validate
|
|
31
|
-
Inspect before Contract. Depth varies naturally.
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# Invar Protocol
|
|
2
|
-
|
|
3
|
-
Follow the Invar Protocol in INVAR.md — includes Check-In, USBV workflow, and Task Completion requirements.
|
|
4
|
-
|
|
5
|
-
## Check-In
|
|
6
|
-
|
|
7
|
-
Your first message MUST display:
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
✓ Check-In: [project] | [branch] | [clean/dirty]
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
Actions:
|
|
14
|
-
1. Read `.invar/context.md` (Key Rules + Current State + Lessons Learned)
|
|
15
|
-
2. Show one-line status
|
|
16
|
-
|
|
17
|
-
**Do NOT execute guard or map at Check-In.**
|
|
18
|
-
Guard is for VALIDATE phase and Final only.
|
|
19
|
-
|
|
20
|
-
This is your sign-in. The user sees it immediately.
|
|
21
|
-
No visible check-in = Session not started.
|
|
22
|
-
|
|
23
|
-
## Final
|
|
24
|
-
|
|
25
|
-
Your last message for an implementation task MUST display:
|
|
26
|
-
|
|
27
|
-
```
|
|
28
|
-
✓ Final: guard PASS | 0 errors, 2 warnings
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Execute `invar guard` and show this one-line summary.
|
|
32
|
-
|
|
33
|
-
This is your sign-out. Completes the Check-In/Final pair.
|
|
34
|
-
|
|
35
|
-
## Quick Reference
|
|
36
|
-
|
|
37
|
-
- Core (`**/core/**`): @pre/@post contracts, doctests, pure (no I/O)
|
|
38
|
-
- Shell (`**/shell/**`): Result[T, E] return type
|
|
39
|
-
- Workflow: Understand → Specify → Build → Validate (USBV)
|
|
40
|
-
- Inspect before Contract. Depth varies naturally.
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# Invar Pre-commit Hooks
|
|
2
|
-
# Install: pre-commit install
|
|
3
|
-
#
|
|
4
|
-
# Default runs full verification (static + doctests + CrossHair + Hypothesis).
|
|
5
|
-
# Incremental mode makes this fast: ~5s first commit, ~2s subsequent (cached).
|
|
6
|
-
#
|
|
7
|
-
# Smart Guard: Detects rule-affecting file changes and runs full guard when needed.
|
|
8
|
-
# Structure Protection: Warns if INVAR.md is modified directly.
|
|
9
|
-
|
|
10
|
-
repos:
|
|
11
|
-
- repo: local
|
|
12
|
-
hooks:
|
|
13
|
-
# Warn if INVAR.md is modified directly (use --no-verify if intentional)
|
|
14
|
-
- id: invar-md-protected
|
|
15
|
-
name: INVAR.md Protection
|
|
16
|
-
entry: bash -c 'if git diff --cached --name-only | grep -q "^INVAR.md$"; then echo "Warning - INVAR.md was modified directly. Use git commit --no-verify if intentional."; exit 1; fi'
|
|
17
|
-
language: system
|
|
18
|
-
pass_filenames: false
|
|
19
|
-
stages: [pre-commit]
|
|
20
|
-
|
|
21
|
-
# Invar Guard (full verification by default)
|
|
22
|
-
# Uses incremental mode: only verifies changed files, caches results
|
|
23
|
-
# Smart mode: runs full guard when rule files change, --changed otherwise
|
|
24
|
-
- id: invar-guard
|
|
25
|
-
name: Invar Guard
|
|
26
|
-
entry: bash -c '
|
|
27
|
-
RULE_FILES="rule_meta.py rules.py contracts.py purity.py pyproject.toml"
|
|
28
|
-
STAGED=$(git diff --cached --name-only)
|
|
29
|
-
FULL=false
|
|
30
|
-
for f in $RULE_FILES; do
|
|
31
|
-
if echo "$STAGED" | grep -q "$f"; then FULL=true; break; fi
|
|
32
|
-
done
|
|
33
|
-
if [ "$FULL" = true ]; then
|
|
34
|
-
echo "⚠️ Rule change detected - running FULL guard"
|
|
35
|
-
invar guard
|
|
36
|
-
else
|
|
37
|
-
invar guard --changed
|
|
38
|
-
fi
|
|
39
|
-
'
|
|
40
|
-
language: python
|
|
41
|
-
additional_dependencies: ['invar-tools']
|
|
42
|
-
pass_filenames: false
|
|
43
|
-
stages: [pre-commit]
|
|
44
|
-
types: [python]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|