invar-tools 1.7.0__py3-none-any.whl → 1.8.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/core/template_helpers.py +32 -0
- invar/core/utils.py +3 -1
- invar/shell/claude_hooks.py +90 -0
- invar/shell/commands/init.py +348 -311
- invar/shell/commands/uninstall.py +162 -7
- invar/shell/contract_coverage.py +4 -1
- invar/shell/pi_hooks.py +207 -0
- invar/shell/templates.py +35 -29
- invar/templates/config/AGENT.md.jinja +198 -0
- invar/templates/config/pre-commit.yaml.jinja +2 -0
- invar/templates/hooks/pi/invar.ts.jinja +73 -0
- invar/templates/manifest.toml +1 -0
- invar/templates/skills/develop/SKILL.md.jinja +59 -0
- invar/templates/skills/investigate/SKILL.md.jinja +15 -0
- invar/templates/skills/propose/SKILL.md.jinja +33 -0
- invar/templates/skills/review/SKILL.md.jinja +15 -0
- {invar_tools-1.7.0.dist-info → invar_tools-1.8.0.dist-info}/METADATA +71 -46
- {invar_tools-1.7.0.dist-info → invar_tools-1.8.0.dist-info}/RECORD +23 -20
- invar/templates/pre-commit-config.yaml.template +0 -46
- {invar_tools-1.7.0.dist-info → invar_tools-1.8.0.dist-info}/WHEEL +0 -0
- {invar_tools-1.7.0.dist-info → invar_tools-1.8.0.dist-info}/entry_points.txt +0 -0
- {invar_tools-1.7.0.dist-info → invar_tools-1.8.0.dist-info}/licenses/LICENSE +0 -0
- {invar_tools-1.7.0.dist-info → invar_tools-1.8.0.dist-info}/licenses/LICENSE-GPL +0 -0
- {invar_tools-1.7.0.dist-info → invar_tools-1.8.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
<!--invar:critical-->
|
|
2
|
+
## ⚡ Critical Rules
|
|
3
|
+
|
|
4
|
+
| Always | Remember |
|
|
5
|
+
|--------|----------|
|
|
6
|
+
{% if syntax == "mcp" -%}
|
|
7
|
+
| **Verify** | `invar_guard` — NOT pytest, NOT crosshair |
|
|
8
|
+
{% else -%}
|
|
9
|
+
| **Verify** | `invar guard` — NOT pytest, NOT crosshair |
|
|
10
|
+
{% endif -%}
|
|
11
|
+
| **Core** | `@pre/@post` + doctests, NO I/O imports |
|
|
12
|
+
| **Shell** | Returns `Result[T, E]` from `returns` library |
|
|
13
|
+
| **Flow** | USBV: Understand → Specify → Build → Validate |
|
|
14
|
+
|
|
15
|
+
### Contract Rules (CRITICAL)
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
# ❌ WRONG: Lambda must include ALL parameters
|
|
19
|
+
@pre(lambda x: x >= 0)
|
|
20
|
+
def calc(x: int, y: int = 0): ...
|
|
21
|
+
|
|
22
|
+
# ✅ CORRECT: Include defaults too
|
|
23
|
+
@pre(lambda x, y=0: x >= 0)
|
|
24
|
+
def calc(x: int, y: int = 0): ...
|
|
25
|
+
|
|
26
|
+
# ❌ WRONG: @post cannot access parameters
|
|
27
|
+
@post(lambda result: result > x) # 'x' not available!
|
|
28
|
+
|
|
29
|
+
# ✅ CORRECT: @post only sees 'result'
|
|
30
|
+
@post(lambda result: result >= 0)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
<!--/invar:critical-->
|
|
34
|
+
|
|
35
|
+
<!--invar:managed version="{{ version }}"-->
|
|
36
|
+
# Project Development Guide
|
|
37
|
+
|
|
38
|
+
> **Protocol:** Follow [INVAR.md](./INVAR.md) — includes Check-In, USBV workflow, and Task Completion requirements.
|
|
39
|
+
|
|
40
|
+
## Check-In
|
|
41
|
+
|
|
42
|
+
> See [INVAR.md#check-in](./INVAR.md#check-in-required) for full protocol.
|
|
43
|
+
|
|
44
|
+
**Your first message MUST display:** `✓ Check-In: [project] | [branch] | [clean/dirty]`
|
|
45
|
+
|
|
46
|
+
**Actions:** Read `.invar/context.md`, then show status. Do NOT run guard at Check-In.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Final
|
|
51
|
+
|
|
52
|
+
Your last message for an implementation task MUST display:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
✓ Final: guard PASS | 0 errors, 2 warnings
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
{% if syntax == "mcp" -%}
|
|
59
|
+
Execute `invar_guard()` and show this one-line summary.
|
|
60
|
+
{% else -%}
|
|
61
|
+
Execute `invar guard` and show this one-line summary.
|
|
62
|
+
{% endif %}
|
|
63
|
+
|
|
64
|
+
This is your sign-out. Completes the Check-In/Final pair.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Project Structure
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
src/{project}/
|
|
72
|
+
├── core/ # Pure logic (@pre/@post, doctests, no I/O)
|
|
73
|
+
└── shell/ # I/O operations (Result[T, E] return type)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Key insight:** Core receives data (strings), Shell handles I/O (paths, files).
|
|
77
|
+
|
|
78
|
+
## Quick Reference
|
|
79
|
+
|
|
80
|
+
| Zone | Requirements |
|
|
81
|
+
|------|-------------|
|
|
82
|
+
| Core | `@pre`/`@post` + doctests, pure (no I/O) |
|
|
83
|
+
| Shell | Returns `Result[T, E]` from `returns` library |
|
|
84
|
+
|
|
85
|
+
### Core vs Shell (Edge Cases)
|
|
86
|
+
|
|
87
|
+
- File/network/env vars → **Shell**
|
|
88
|
+
- `datetime.now()`, `random` → **Inject param** OR Shell
|
|
89
|
+
- Pure logic → **Core**
|
|
90
|
+
|
|
91
|
+
> Full decision tree: [INVAR.md#core-shell](./INVAR.md#decision-tree-core-vs-shell)
|
|
92
|
+
|
|
93
|
+
## Documentation Structure
|
|
94
|
+
|
|
95
|
+
| File | Owner | Edit? | Purpose |
|
|
96
|
+
|------|-------|-------|---------|
|
|
97
|
+
| INVAR.md | Invar | No | Protocol (`invar update` to sync) |
|
|
98
|
+
| AGENT.md | User | Yes | Project customization (this file) |
|
|
99
|
+
| .invar/context.md | User | Yes | Project state, lessons learned |
|
|
100
|
+
| .invar/examples/ | Invar | No | **Must read:** Core/Shell patterns, workflow |
|
|
101
|
+
|
|
102
|
+
> **Before writing code:** Check Task Router in `.invar/context.md`
|
|
103
|
+
|
|
104
|
+
## USBV Workflow
|
|
105
|
+
|
|
106
|
+
For complex tasks (3+ functions), follow these phases:
|
|
107
|
+
|
|
108
|
+
### 1. UNDERSTAND
|
|
109
|
+
|
|
110
|
+
- **Intent:** What exactly needs to be done?
|
|
111
|
+
{% if syntax == "mcp" -%}
|
|
112
|
+
- **Inspect:** Use `invar_sig` to see existing contracts
|
|
113
|
+
{% else -%}
|
|
114
|
+
- **Inspect:** Use `invar sig` to see existing contracts
|
|
115
|
+
{% endif -%}
|
|
116
|
+
- **Context:** Read relevant code, understand patterns
|
|
117
|
+
- **Constraints:** What must NOT change?
|
|
118
|
+
|
|
119
|
+
### 2. SPECIFY
|
|
120
|
+
|
|
121
|
+
- **Contracts FIRST:** Write `@pre`/`@post` before implementation
|
|
122
|
+
- **Doctests:** Add examples for expected behavior
|
|
123
|
+
- **Design:** Decompose complex tasks into sub-functions
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
# SPECIFY before BUILD:
|
|
127
|
+
@pre(lambda x: x > 0)
|
|
128
|
+
@post(lambda result: result >= 0)
|
|
129
|
+
def calculate(x: int) -> int:
|
|
130
|
+
"""
|
|
131
|
+
>>> calculate(10)
|
|
132
|
+
100
|
|
133
|
+
"""
|
|
134
|
+
... # Implementation comes in BUILD
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### 3. BUILD
|
|
138
|
+
|
|
139
|
+
- Follow the contracts written in SPECIFY
|
|
140
|
+
{% if syntax == "mcp" -%}
|
|
141
|
+
- Run `invar_guard(changed=true)` frequently
|
|
142
|
+
{% else -%}
|
|
143
|
+
- Run `invar guard --changed` frequently
|
|
144
|
+
{% endif -%}
|
|
145
|
+
- Commit after each logical unit
|
|
146
|
+
|
|
147
|
+
### 4. VALIDATE
|
|
148
|
+
|
|
149
|
+
{% if syntax == "mcp" -%}
|
|
150
|
+
- Run `invar_guard()` (full verification)
|
|
151
|
+
{% else -%}
|
|
152
|
+
- Run `invar guard` (full verification)
|
|
153
|
+
{% endif -%}
|
|
154
|
+
- Integration works (if applicable)
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Tool Selection
|
|
159
|
+
|
|
160
|
+
| I want to... | Use |
|
|
161
|
+
|--------------|-----|
|
|
162
|
+
{% if syntax == "mcp" -%}
|
|
163
|
+
| See contracts | `invar_sig(target="<file>")` |
|
|
164
|
+
| Find entry points | `invar_map(top=10)` |
|
|
165
|
+
| Verify code | `invar_guard()` |
|
|
166
|
+
{% else -%}
|
|
167
|
+
| See contracts | `invar sig <file>` |
|
|
168
|
+
| Find entry points | `invar map --top 10` |
|
|
169
|
+
| Verify code | `invar guard` |
|
|
170
|
+
{% endif -%}
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Task Completion
|
|
175
|
+
|
|
176
|
+
A task is complete only when ALL conditions are met:
|
|
177
|
+
- Check-In displayed: `✓ Check-In: [project] | [branch] | [clean/dirty]`
|
|
178
|
+
- Intent explicitly stated
|
|
179
|
+
- Contract written before implementation
|
|
180
|
+
- Final displayed: `✓ Final: guard PASS | <errors>, <warnings>`
|
|
181
|
+
- User requirement satisfied
|
|
182
|
+
|
|
183
|
+
**Missing any = Task incomplete.**
|
|
184
|
+
|
|
185
|
+
<!--/invar:managed-->
|
|
186
|
+
<!--invar:project-->
|
|
187
|
+
<!--/invar:project-->
|
|
188
|
+
<!--invar:user-->
|
|
189
|
+
<!-- ========================================================================
|
|
190
|
+
USER REGION - EDITABLE
|
|
191
|
+
Add your team conventions and project-specific rules below.
|
|
192
|
+
This section is preserved across `invar update` and `invar dev sync`.
|
|
193
|
+
======================================================================== -->
|
|
194
|
+
<!--/invar:user-->
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
*Generated by `invar init` v{{ version }}. Customize the user section freely.*
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Invar Pi Hook
|
|
3
|
+
* Protocol: v{{ protocol_version }} | Generated: {{ generated_date }}
|
|
4
|
+
* LX-04: Full feature parity with Claude Code hooks
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - pytest/crosshair blocking via tool_call
|
|
8
|
+
* - Protocol injection via pi.send() for long conversations
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { HookAPI } from "@mariozechner/pi-coding-agent/hooks";
|
|
12
|
+
|
|
13
|
+
// Blocked commands (same as Claude Code)
|
|
14
|
+
const BLOCKED_CMDS = [/^pytest\b/, /^python\s+-m\s+pytest/, /^crosshair\b/];
|
|
15
|
+
const ALLOWED_FLAGS = [/--pdb/, /--cov/, /--debug/];
|
|
16
|
+
|
|
17
|
+
// Protocol content for injection (escaped for JS)
|
|
18
|
+
const INVAR_PROTOCOL = `{{ invar_protocol_escaped }}`;
|
|
19
|
+
|
|
20
|
+
export default function (pi: HookAPI) {
|
|
21
|
+
let msgCount = 0;
|
|
22
|
+
|
|
23
|
+
// ============================================
|
|
24
|
+
// Session Management
|
|
25
|
+
// ============================================
|
|
26
|
+
pi.on("session", async (event) => {
|
|
27
|
+
// Reset count on session start/restore
|
|
28
|
+
if (event.reason === "start" || event.reason === "branch") {
|
|
29
|
+
msgCount = 0;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// ============================================
|
|
34
|
+
// Long Conversation Protocol Refresh
|
|
35
|
+
// ============================================
|
|
36
|
+
pi.on("agent_start", async () => {
|
|
37
|
+
msgCount++;
|
|
38
|
+
|
|
39
|
+
// Message 15: Lightweight checkpoint
|
|
40
|
+
if (msgCount === 15) {
|
|
41
|
+
pi.send(
|
|
42
|
+
"<system-reminder>Checkpoint: guard=verify, sig=contracts, USBV workflow.</system-reminder>"
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Message 25+: Full protocol injection every 10 messages
|
|
47
|
+
if (msgCount >= 25 && msgCount % 10 === 0) {
|
|
48
|
+
pi.send(`<system-reminder>
|
|
49
|
+
=== Protocol Refresh (message ${msgCount}) ===
|
|
50
|
+
${INVAR_PROTOCOL}
|
|
51
|
+
</system-reminder>`);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// ============================================
|
|
56
|
+
// pytest/crosshair Blocking
|
|
57
|
+
// ============================================
|
|
58
|
+
pi.on("tool_call", async (event) => {
|
|
59
|
+
if (event.toolName !== "bash") return;
|
|
60
|
+
const cmd = ((event.input as Record<string, unknown>).command as string || "").trim();
|
|
61
|
+
|
|
62
|
+
// Skip if not a blocked command
|
|
63
|
+
if (!BLOCKED_CMDS.some((p) => p.test(cmd))) return;
|
|
64
|
+
|
|
65
|
+
// Allow if has debug/test flags
|
|
66
|
+
if (ALLOWED_FLAGS.some((p) => p.test(cmd))) return;
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
block: true,
|
|
70
|
+
reason: "Use `{{ guard_cmd }}` instead of pytest/crosshair.",
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
}
|
invar/templates/manifest.toml
CHANGED
|
@@ -54,6 +54,7 @@ extensions = { action = "preserve" }
|
|
|
54
54
|
|
|
55
55
|
# Config files (Jinja2 templates)
|
|
56
56
|
"CLAUDE.md" = { src = "config/CLAUDE.md.jinja", type = "jinja" }
|
|
57
|
+
"AGENT.md" = { src = "config/AGENT.md.jinja", type = "jinja" }
|
|
57
58
|
".invar/context.md" = { src = "config/context.md.jinja", type = "jinja" }
|
|
58
59
|
".pre-commit-config.yaml" = { src = "config/pre-commit.yaml.jinja", type = "jinja" }
|
|
59
60
|
|
|
@@ -10,9 +10,49 @@ _invar:
|
|
|
10
10
|
# Development Mode
|
|
11
11
|
|
|
12
12
|
> **Purpose:** Implement solution following USBV workflow with verification.
|
|
13
|
+
> **Mindset:** CONTRACTS before code — no exceptions.
|
|
14
|
+
|
|
15
|
+
## Scope Boundaries
|
|
16
|
+
|
|
17
|
+
**This skill IS for:**
|
|
18
|
+
- Implementing features ("add", "create", "build")
|
|
19
|
+
- Fixing bugs ("fix", "resolve")
|
|
20
|
+
- Modifying existing code ("update", "change")
|
|
21
|
+
- Writing tests and contracts
|
|
22
|
+
|
|
23
|
+
**This skill is NOT for:**
|
|
24
|
+
- Exploring unclear requirements → switch to `/investigate`
|
|
25
|
+
- Choosing between approaches → switch to `/propose`
|
|
26
|
+
- Reviewing completed work → switch to `/review`
|
|
27
|
+
|
|
28
|
+
**Drift detection:** If requirements are unclear → STOP, exit to `/investigate` first.
|
|
13
29
|
|
|
14
30
|
## Entry Actions (REQUIRED)
|
|
15
31
|
|
|
32
|
+
### Session Restore (if continuing from summary)
|
|
33
|
+
|
|
34
|
+
When conversation begins with a previous session summary:
|
|
35
|
+
|
|
36
|
+
1. **ALWAYS display Check-In first** — even when continuing
|
|
37
|
+
2. **Determine current phase** from todo items:
|
|
38
|
+
| Todo keywords | Phase |
|
|
39
|
+
|---------------|-------|
|
|
40
|
+
| "research", "understand", "analyze" | UNDERSTAND |
|
|
41
|
+
| "contract", "design", "specify" | SPECIFY |
|
|
42
|
+
| "implement", "code", "build" | BUILD |
|
|
43
|
+
| "verify", "test", "guard" | VALIDATE |
|
|
44
|
+
3. **Display phase header** before resuming work
|
|
45
|
+
4. **Re-read context.md** for project state
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
# Example session restore:
|
|
49
|
+
✓ Check-In: Invar | Main | dirty
|
|
50
|
+
|
|
51
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
52
|
+
📍 /develop → BUILD (3/4) [resumed]
|
|
53
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
54
|
+
```
|
|
55
|
+
|
|
16
56
|
### Context Refresh (DX-54)
|
|
17
57
|
|
|
18
58
|
Before any workflow action:
|
|
@@ -123,6 +163,25 @@ If any NO → Stop. Write contract first.
|
|
|
123
163
|
|
|
124
164
|
### 3. BUILD
|
|
125
165
|
|
|
166
|
+
#### New Function Gate (MANDATORY)
|
|
167
|
+
|
|
168
|
+
**Before writing ANY new Core function, STOP and verify:**
|
|
169
|
+
|
|
170
|
+
| Check | If NO → Action |
|
|
171
|
+
|-------|----------------|
|
|
172
|
+
| Contract shown in SPECIFY phase? | ⛔ STOP. Return to SPECIFY. |
|
|
173
|
+
| Doctest written? | ⛔ STOP. Write doctest first. |
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
⛔ GATE VIOLATION: Writing new function without prior contract.
|
|
177
|
+
→ Return to SPECIFY phase. Show contract first.
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Exempt from gate:**
|
|
181
|
+
- Shell functions (no @pre/@post required)
|
|
182
|
+
- Editing existing functions (contract already exists)
|
|
183
|
+
- Non-Python files
|
|
184
|
+
|
|
126
185
|
**For complex tasks:** Enter Plan Mode first, get user approval.
|
|
127
186
|
|
|
128
187
|
**Implementation rules:**
|
|
@@ -11,6 +11,21 @@ _invar:
|
|
|
11
11
|
|
|
12
12
|
> **Purpose:** Understand before acting. Gather information, analyze code, report findings.
|
|
13
13
|
|
|
14
|
+
## Scope Boundaries
|
|
15
|
+
|
|
16
|
+
**This skill IS for:**
|
|
17
|
+
- Understanding vague or unclear tasks
|
|
18
|
+
- Analyzing existing code and architecture
|
|
19
|
+
- Researching before implementation
|
|
20
|
+
- Answering "why", "what", "how does" questions
|
|
21
|
+
|
|
22
|
+
**This skill is NOT for:**
|
|
23
|
+
- Writing or modifying code → switch to `/develop`
|
|
24
|
+
- Making design decisions → switch to `/propose`
|
|
25
|
+
- Reviewing code quality → switch to `/review`
|
|
26
|
+
|
|
27
|
+
**Drift detection:** If you find yourself wanting to edit files → STOP, exit to `/develop`.
|
|
28
|
+
|
|
14
29
|
## Constraints
|
|
15
30
|
|
|
16
31
|
**FORBIDDEN in this phase:**
|
|
@@ -10,6 +10,39 @@ _invar:
|
|
|
10
10
|
# Proposal Mode
|
|
11
11
|
|
|
12
12
|
> **Purpose:** Facilitate human decision-making with clear options and trade-offs.
|
|
13
|
+
> **Mindset:** OPTIONS, not decisions — human chooses.
|
|
14
|
+
|
|
15
|
+
## Scope Boundaries
|
|
16
|
+
|
|
17
|
+
**This skill IS for:**
|
|
18
|
+
- Presenting design choices with trade-offs
|
|
19
|
+
- Facilitating architectural decisions
|
|
20
|
+
- Comparing approaches (A vs B)
|
|
21
|
+
- Creating formal proposals for complex decisions
|
|
22
|
+
|
|
23
|
+
**This skill is NOT for:**
|
|
24
|
+
- Implementing the chosen option → switch to `/develop`
|
|
25
|
+
- Researching to understand the problem → switch to `/investigate`
|
|
26
|
+
- Reviewing existing code → switch to `/review`
|
|
27
|
+
|
|
28
|
+
**Drift detection:** If you find yourself writing implementation code → STOP, wait for user choice, then exit to `/develop`.
|
|
29
|
+
|
|
30
|
+
## Constraints
|
|
31
|
+
|
|
32
|
+
**FORBIDDEN in this phase:**
|
|
33
|
+
- Writing implementation code (beyond examples)
|
|
34
|
+
- Making decisions for the user
|
|
35
|
+
- Creating files other than proposals
|
|
36
|
+
- Committing changes
|
|
37
|
+
|
|
38
|
+
**ALLOWED:**
|
|
39
|
+
- Read, Glob, Grep (research for options)
|
|
40
|
+
{% if syntax == "mcp" -%}
|
|
41
|
+
- invar_sig, invar_map (understand current state)
|
|
42
|
+
{% else -%}
|
|
43
|
+
- invar sig, invar map (understand current state)
|
|
44
|
+
{% endif -%}
|
|
45
|
+
- Creating proposal documents in `docs/proposals/`
|
|
13
46
|
|
|
14
47
|
## Entry Actions
|
|
15
48
|
|
|
@@ -14,6 +14,21 @@ _invar:
|
|
|
14
14
|
> **Success Metric:** Issues FOUND, not code approved. Zero issues = you failed to look hard enough.
|
|
15
15
|
> **Workflow:** AUTOMATIC Reviewer↔Fixer loop until quality_met or max_rounds (no human confirmation).
|
|
16
16
|
|
|
17
|
+
## Scope Boundaries
|
|
18
|
+
|
|
19
|
+
**This skill IS for:**
|
|
20
|
+
- Finding bugs and logic errors in existing code
|
|
21
|
+
- Verifying contract semantic value
|
|
22
|
+
- Auditing escape hatches
|
|
23
|
+
- Security review
|
|
24
|
+
|
|
25
|
+
**This skill is NOT for:**
|
|
26
|
+
- Implementing new features → switch to `/develop`
|
|
27
|
+
- Understanding how code works → switch to `/investigate`
|
|
28
|
+
- Deciding on architecture → switch to `/propose`
|
|
29
|
+
|
|
30
|
+
**Drift detection:** If you're writing significant new code (not fixes) → STOP, you're in wrong skill.
|
|
31
|
+
|
|
17
32
|
## Auto-Loop Configuration
|
|
18
33
|
|
|
19
34
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: invar-tools
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.8.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
|
|
@@ -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,25 @@ 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
|
-
#
|
|
139
|
-
uvx invar-tools init
|
|
138
|
+
# Interactive mode - choose what to install
|
|
139
|
+
uvx invar-tools init
|
|
140
140
|
|
|
141
|
-
#
|
|
142
|
-
|
|
143
|
-
|
|
141
|
+
# Or quick setup (skip prompts)
|
|
142
|
+
uvx invar-tools init --claude # Claude Code
|
|
143
|
+
uvx invar-tools init --pi # Pi Coding Agent
|
|
144
144
|
|
|
145
|
-
#
|
|
145
|
+
# Add runtime contracts to your project
|
|
146
|
+
pip install invar-runtime
|
|
146
147
|
```
|
|
147
148
|
|
|
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
|
-
```
|
|
149
|
+
**Safe and idempotent** — Run `invar init` anytime. It always **merges** with existing files, preserving your content.
|
|
159
150
|
|
|
160
|
-
|
|
151
|
+
> 💡 **After `claude /init`?** Just run `invar init` again to restore Invar configuration.
|
|
161
152
|
|
|
162
153
|
### 💬 Example Interaction
|
|
163
154
|
|
|
@@ -375,39 +366,71 @@ AlphaCodium · Parsel · Reflexion · Clover
|
|
|
375
366
|
|
|
376
367
|
---
|
|
377
368
|
|
|
378
|
-
## 🖥️
|
|
369
|
+
## 🖥️ Agent Support
|
|
379
370
|
|
|
380
|
-
|
|
|
381
|
-
|
|
382
|
-
|
|
|
383
|
-
|
|
|
384
|
-
|
|
|
385
|
-
|
|
|
386
|
-
| Pre-commit hooks | ✅ | ✅ |
|
|
387
|
-
| Sub-agent review | ✅ | — |
|
|
371
|
+
| Agent | Status | Setup |
|
|
372
|
+
|-------|--------|-------|
|
|
373
|
+
| **Claude Code** | ✅ Full | `invar init --claude` |
|
|
374
|
+
| **Pi** | ✅ Full | `invar init --pi` |
|
|
375
|
+
| **Cursor** | ✅ MCP | `invar init` → select Other, add MCP config |
|
|
376
|
+
| **Other** | 📝 Manual | `invar init` → select Other, include `AGENT.md` in prompt |
|
|
388
377
|
|
|
389
|
-
|
|
378
|
+
> **See also:** [Multi-Agent Guide](./docs/guides/multi-agent.md) for detailed integration instructions.
|
|
390
379
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
380
|
+
### Claude Code (Full Experience)
|
|
381
|
+
|
|
382
|
+
All features auto-configured:
|
|
383
|
+
- MCP tools (`invar_guard`, `invar_sig`, `invar_map`)
|
|
384
|
+
- Workflow skills (`/develop`, `/review`, `/investigate`, `/propose`)
|
|
385
|
+
- Claude Code hooks (tool guidance, verification reminders)
|
|
386
|
+
- Pre-commit hooks
|
|
387
|
+
|
|
388
|
+
### Pi (Full Support)
|
|
389
|
+
|
|
390
|
+
Pi reads CLAUDE.md and .claude/skills/ directly, sharing configuration with Claude Code:
|
|
391
|
+
- **Same instruction file** — CLAUDE.md (no separate AGENT.md needed)
|
|
392
|
+
- **Same workflow skills** — .claude/skills/ work in Pi
|
|
393
|
+
- **Pi-specific hooks** — .pi/hooks/invar.ts for pytest blocking and protocol refresh
|
|
394
|
+
- **Protocol injection** — Long conversation support via `pi.send()`
|
|
395
|
+
- Pre-commit hooks
|
|
396
|
+
|
|
397
|
+
### Cursor (MCP + Rules)
|
|
398
|
+
|
|
399
|
+
Cursor users get full verification via MCP:
|
|
400
|
+
- MCP tools (`invar_guard`, `invar_sig`, `invar_map`)
|
|
401
|
+
- .cursor/rules/ for USBV workflow guidance
|
|
402
|
+
- Hooks (beta) for pytest blocking
|
|
403
|
+
- Pre-commit hooks
|
|
404
|
+
|
|
405
|
+
> See [Cursor Guide](./docs/guides/cursor.md) for detailed setup.
|
|
406
|
+
|
|
407
|
+
### Other Editors (Manual)
|
|
408
|
+
|
|
409
|
+
1. Run `invar init` → select "Other (AGENT.md)"
|
|
410
|
+
2. Include generated `AGENT.md` in your agent's prompt
|
|
411
|
+
3. Configure MCP server if supported
|
|
412
|
+
4. Use CLI commands (`invar guard`) for verification
|
|
395
413
|
|
|
396
414
|
---
|
|
397
415
|
|
|
398
416
|
## 📂 What Gets Installed
|
|
399
417
|
|
|
400
|
-
`invar init
|
|
418
|
+
`invar init` creates (select in interactive mode):
|
|
419
|
+
|
|
420
|
+
| File/Directory | Purpose | Category |
|
|
421
|
+
|----------------|---------|----------|
|
|
422
|
+
| `INVAR.md` | Protocol for AI agents | Required |
|
|
423
|
+
| `.invar/` | Config, context, examples | Required |
|
|
424
|
+
| `.pre-commit-config.yaml` | Verification before commit | Optional |
|
|
425
|
+
| `src/core/`, `src/shell/` | Recommended structure | Optional |
|
|
426
|
+
| `CLAUDE.md` | Agent instructions | Claude Code |
|
|
427
|
+
| `.claude/skills/` | Workflow automation | Claude Code |
|
|
428
|
+
| `.claude/commands/` | User commands (/audit, /guard) | Claude Code |
|
|
429
|
+
| `.claude/hooks/` | Tool guidance | Claude Code |
|
|
430
|
+
| `.mcp.json` | MCP server config | Claude Code |
|
|
431
|
+
| `AGENT.md` | Universal agent instructions | Other agents |
|
|
401
432
|
|
|
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 |
|
|
433
|
+
**Note:** If `pyproject.toml` exists, Guard configuration goes there as `[tool.invar.guard]` instead of `.invar/config.toml`.
|
|
411
434
|
|
|
412
435
|
**Recommended structure:**
|
|
413
436
|
|
|
@@ -473,7 +496,9 @@ rules = ["missing_contract", "shell_result"]
|
|
|
473
496
|
| `invar guard` | Full verification (static + doctest + property + symbolic) |
|
|
474
497
|
| `invar guard --changed` | Only git-modified files |
|
|
475
498
|
| `invar guard --static` | Static analysis only (~0.5s) |
|
|
476
|
-
| `invar init` | Initialize or update project |
|
|
499
|
+
| `invar init` | Initialize or update project (interactive) |
|
|
500
|
+
| `invar init --claude` | Quick setup for Claude Code |
|
|
501
|
+
| `invar uninstall` | Remove Invar from project (preserves user content) |
|
|
477
502
|
| `invar sig <file>` | Show signatures and contracts |
|
|
478
503
|
| `invar map` | Symbol map with reference counts |
|
|
479
504
|
| `invar rules` | List all rules |
|