invar-tools 1.12.0__py3-none-any.whl → 1.14.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/feedback.py +110 -0
- invar/shell/claude_hooks.py +49 -0
- invar/shell/commands/feedback.py +258 -0
- invar/shell/commands/guard.py +9 -1
- invar/shell/commands/init.py +51 -1
- invar/templates/claude-md/universal/tool-selection.md +110 -0
- invar/templates/config/CLAUDE.md.jinja +2 -0
- invar/templates/manifest.toml +8 -0
- invar/templates/protocol/python/tools.md +5 -2
- invar/templates/protocol/typescript/tools.md +5 -2
- invar/templates/skills/invar-reflect/CONFIG.md +355 -0
- invar/templates/skills/invar-reflect/SKILL.md +466 -0
- invar/templates/skills/invar-reflect/template.md +343 -0
- {invar_tools-1.12.0.dist-info → invar_tools-1.14.0.dist-info}/METADATA +1 -1
- {invar_tools-1.12.0.dist-info → invar_tools-1.14.0.dist-info}/RECORD +20 -14
- {invar_tools-1.12.0.dist-info → invar_tools-1.14.0.dist-info}/WHEEL +0 -0
- {invar_tools-1.12.0.dist-info → invar_tools-1.14.0.dist-info}/entry_points.txt +0 -0
- {invar_tools-1.12.0.dist-info → invar_tools-1.14.0.dist-info}/licenses/LICENSE +0 -0
- {invar_tools-1.12.0.dist-info → invar_tools-1.14.0.dist-info}/licenses/LICENSE-GPL +0 -0
- {invar_tools-1.12.0.dist-info → invar_tools-1.14.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
## Commands (Python)
|
|
2
2
|
|
|
3
3
|
```bash
|
|
4
|
-
invar guard #
|
|
4
|
+
invar guard # Check git-modified files (fast, default)
|
|
5
|
+
invar guard --all # Check entire project (CI, release)
|
|
5
6
|
invar guard --static # Static only (quick debug, ~0.5s)
|
|
6
|
-
invar guard --changed # Modified files only
|
|
7
7
|
invar guard --coverage # Collect branch coverage
|
|
8
8
|
invar guard -c # Contract coverage only (DX-63)
|
|
9
9
|
invar sig <file> # Show contracts + signatures
|
|
@@ -11,6 +11,9 @@ invar map --top 10 # Most-referenced symbols
|
|
|
11
11
|
invar rules # List all rules with detection/hints (JSON)
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
+
**Default behavior**: Checks git-modified files for fast feedback during development.
|
|
15
|
+
Use `--all` for comprehensive checks before release.
|
|
16
|
+
|
|
14
17
|
## Configuration (Python)
|
|
15
18
|
|
|
16
19
|
```toml
|
|
@@ -2,15 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
```bash
|
|
4
4
|
# Verification (Python CLI - works for TypeScript)
|
|
5
|
-
invar guard #
|
|
5
|
+
invar guard # Check git-modified files (fast, default)
|
|
6
|
+
invar guard --all # Check entire project (CI, release)
|
|
6
7
|
invar guard --json # Agent-friendly v2.0 JSON output
|
|
7
|
-
invar guard --changed # Modified files only
|
|
8
8
|
|
|
9
9
|
# Analysis
|
|
10
10
|
invar sig <file> # Show function signatures
|
|
11
11
|
invar map --top 10 # Most-referenced symbols
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
+
**Default behavior**: Checks git-modified files for fast feedback during development.
|
|
15
|
+
Use `--all` for comprehensive checks before release.
|
|
16
|
+
|
|
14
17
|
## Guard Output (v2.0 JSON)
|
|
15
18
|
|
|
16
19
|
```json
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# /invar-reflect Configuration
|
|
2
|
+
|
|
3
|
+
**Status**: Phase B - Hook Integration (Proposed)
|
|
4
|
+
|
|
5
|
+
This document describes the configuration for automatic feedback collection using the `/invar-reflect` skill.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
The `/invar-reflect` skill can be triggered:
|
|
12
|
+
1. **Manually**: User calls `/invar-reflect`
|
|
13
|
+
2. **Automatically** (Phase B): Via `PostTaskCompletion` hook when conditions are met
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Proposed Hook Schema
|
|
18
|
+
|
|
19
|
+
### PostTaskCompletion Hook (Waiting for Claude Code Support)
|
|
20
|
+
|
|
21
|
+
**Proposed configuration in `.claude/settings.json`**:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"hooks": {
|
|
26
|
+
"PostTaskCompletion": [
|
|
27
|
+
{
|
|
28
|
+
"hooks": [
|
|
29
|
+
{
|
|
30
|
+
"type": "skill",
|
|
31
|
+
"skill": "invar-reflect",
|
|
32
|
+
"mode": "silent",
|
|
33
|
+
"conditions": {
|
|
34
|
+
"min_messages": 30,
|
|
35
|
+
"min_duration_hours": 2
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"feedback": {
|
|
43
|
+
"enabled": true,
|
|
44
|
+
"auto_trigger": true,
|
|
45
|
+
"retention_days": 90
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Hook Parameters**:
|
|
51
|
+
|
|
52
|
+
| Parameter | Type | Default | Description |
|
|
53
|
+
|-----------|------|---------|-------------|
|
|
54
|
+
| `type` | string | - | Must be `"skill"` |
|
|
55
|
+
| `skill` | string | - | Skill name: `"invar-reflect"` |
|
|
56
|
+
| `mode` | string | `"silent"` | Silent mode (no user interruption) |
|
|
57
|
+
| `conditions.min_messages` | number | 30 | Minimum messages in session |
|
|
58
|
+
| `conditions.min_duration_hours` | number | 2 | Minimum session duration |
|
|
59
|
+
|
|
60
|
+
**Feedback Config**:
|
|
61
|
+
|
|
62
|
+
| Parameter | Type | Default | Description |
|
|
63
|
+
|-----------|------|---------|-------------|
|
|
64
|
+
| `enabled` | boolean | true | Enable feedback collection |
|
|
65
|
+
| `auto_trigger` | boolean | true | Auto-run via hook |
|
|
66
|
+
| `retention_days` | number | 90 | Auto-cleanup old files |
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Triggering Conditions
|
|
71
|
+
|
|
72
|
+
The hook triggers when **ALL** conditions are met:
|
|
73
|
+
|
|
74
|
+
1. ✅ **Task completed** - User finished major work (natural stopping point)
|
|
75
|
+
2. ✅ **Message count >= 30** - Sufficient context for meaningful feedback
|
|
76
|
+
3. ✅ **Duration >= 2 hours** - Non-trivial session (avoids quick fixes)
|
|
77
|
+
|
|
78
|
+
**No hard frequency cap**: Same-day sessions merge into single file (see SKILL.md for merge logic).
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Silent Mode
|
|
83
|
+
|
|
84
|
+
When `mode: "silent"`:
|
|
85
|
+
- Feedback generation runs in background
|
|
86
|
+
- No interruption to current conversation
|
|
87
|
+
- User sees notification only: `✓ Feedback saved to .invar/feedback/feedback-{date}.md`
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## User Control
|
|
92
|
+
|
|
93
|
+
### Enable/Disable
|
|
94
|
+
|
|
95
|
+
**During init** (Phase C):
|
|
96
|
+
```bash
|
|
97
|
+
$ invar init
|
|
98
|
+
...
|
|
99
|
+
Enable automatic feedback collection? [Y/n]: n
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**After init**:
|
|
103
|
+
```json
|
|
104
|
+
// .claude/settings.json
|
|
105
|
+
{
|
|
106
|
+
"feedback": {
|
|
107
|
+
"enabled": false // Disable feedback collection
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Or disable auto-trigger only (manual `/invar-reflect` still works):
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"feedback": {
|
|
116
|
+
"enabled": true,
|
|
117
|
+
"auto_trigger": false // Manual only
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### File Management
|
|
123
|
+
|
|
124
|
+
Feedback files location:
|
|
125
|
+
```
|
|
126
|
+
.invar/feedback/
|
|
127
|
+
├── feedback-2026-01-03.md # All sessions from Jan 3
|
|
128
|
+
├── feedback-2026-01-04.md # All sessions from Jan 4
|
|
129
|
+
└── feedback-2026-01-10.md # Jan 10 (gaps are OK)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Auto-cleanup**: Files older than `retention_days` are automatically deleted.
|
|
133
|
+
|
|
134
|
+
**Manual cleanup**:
|
|
135
|
+
```bash
|
|
136
|
+
# Delete all feedback
|
|
137
|
+
rm -rf .invar/feedback/
|
|
138
|
+
|
|
139
|
+
# Delete specific file
|
|
140
|
+
rm .invar/feedback/feedback-2026-01-03.md
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Workaround: Using Stop Hook (Until PostTaskCompletion is Available)
|
|
146
|
+
|
|
147
|
+
Since Claude Code doesn't yet support `PostTaskCompletion` hook, you can use the `Stop` hook as a temporary workaround.
|
|
148
|
+
|
|
149
|
+
### Stop Hook Implementation
|
|
150
|
+
|
|
151
|
+
Create `.claude/hooks/invar.FeedbackTrigger.sh`:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
#!/bin/bash
|
|
155
|
+
# Invar Feedback Trigger (Stop Hook Workaround)
|
|
156
|
+
# DX-79 Phase B: Auto-trigger /invar-reflect on session end
|
|
157
|
+
|
|
158
|
+
# Read feedback config
|
|
159
|
+
FEEDBACK_ENABLED=$(jq -r '.feedback.enabled // true' .claude/settings.local.json 2>/dev/null)
|
|
160
|
+
AUTO_TRIGGER=$(jq -r '.feedback.auto_trigger // true' .claude/settings.local.json 2>/dev/null)
|
|
161
|
+
|
|
162
|
+
if [[ "$FEEDBACK_ENABLED" != "true" ]] || [[ "$AUTO_TRIGGER" != "true" ]]; then
|
|
163
|
+
exit 0 # Feedback disabled
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
# Check session conditions (requires session state tracking)
|
|
167
|
+
STATE_DIR="${CLAUDE_STATE_DIR:-/tmp/invar_hooks_$(id -u)}"
|
|
168
|
+
SESSION_START_FILE="$STATE_DIR/session_start"
|
|
169
|
+
MESSAGE_COUNT_FILE="$STATE_DIR/message_count"
|
|
170
|
+
|
|
171
|
+
# Calculate duration
|
|
172
|
+
if [[ -f "$SESSION_START_FILE" ]]; then
|
|
173
|
+
SESSION_START=$(cat "$SESSION_START_FILE")
|
|
174
|
+
SESSION_END=$(date +%s)
|
|
175
|
+
DURATION_HOURS=$(( (SESSION_END - SESSION_START) / 3600 ))
|
|
176
|
+
else
|
|
177
|
+
DURATION_HOURS=0
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
# Read message count
|
|
181
|
+
MESSAGE_COUNT=$(cat "$MESSAGE_COUNT_FILE" 2>/dev/null || echo 0)
|
|
182
|
+
|
|
183
|
+
# Check conditions
|
|
184
|
+
if [[ $MESSAGE_COUNT -ge 30 ]] && [[ $DURATION_HOURS -ge 2 ]]; then
|
|
185
|
+
echo ""
|
|
186
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
187
|
+
echo "📊 Invar: Generating usage feedback..."
|
|
188
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
189
|
+
echo ""
|
|
190
|
+
echo "Session complete: $MESSAGE_COUNT messages, ${DURATION_HOURS}h duration"
|
|
191
|
+
echo "Feedback will be saved to .invar/feedback/feedback-$(date +%Y-%m-%d).md"
|
|
192
|
+
echo ""
|
|
193
|
+
echo "To review or share: cat .invar/feedback/feedback-$(date +%Y-%m-%d).md"
|
|
194
|
+
echo "To disable: Set feedback.auto_trigger=false in .claude/settings.local.json"
|
|
195
|
+
fi
|
|
196
|
+
|
|
197
|
+
# Cleanup session state
|
|
198
|
+
rm -rf "$STATE_DIR" 2>/dev/null
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Note**: This workaround provides notification but doesn't actually generate feedback automatically. Full auto-generation requires:
|
|
202
|
+
1. Claude Code to support skill invocation from hooks, OR
|
|
203
|
+
2. Hook to write state file that triggers `/invar-reflect` on next user interaction
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Configuration Template (for `invar init`)
|
|
208
|
+
|
|
209
|
+
When Phase C is complete, `invar init` will generate this configuration:
|
|
210
|
+
|
|
211
|
+
```json
|
|
212
|
+
{
|
|
213
|
+
"permissions": {
|
|
214
|
+
"allow": [
|
|
215
|
+
// ... existing permissions ...
|
|
216
|
+
]
|
|
217
|
+
},
|
|
218
|
+
"hooks": {
|
|
219
|
+
"PostTaskCompletion": [
|
|
220
|
+
{
|
|
221
|
+
"hooks": [
|
|
222
|
+
{
|
|
223
|
+
"type": "skill",
|
|
224
|
+
"skill": "invar-reflect",
|
|
225
|
+
"mode": "silent",
|
|
226
|
+
"conditions": {
|
|
227
|
+
"min_messages": 30,
|
|
228
|
+
"min_duration_hours": 2
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
]
|
|
232
|
+
}
|
|
233
|
+
],
|
|
234
|
+
// ... existing hooks ...
|
|
235
|
+
},
|
|
236
|
+
"feedback": {
|
|
237
|
+
"enabled": true,
|
|
238
|
+
"auto_trigger": true,
|
|
239
|
+
"retention_days": 90
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Init prompt** (Phase C):
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
248
|
+
📊 Usage Feedback (Optional)
|
|
249
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
250
|
+
|
|
251
|
+
Invar can automatically reflect on tool usage to help improve
|
|
252
|
+
the framework. Feedback is:
|
|
253
|
+
- Stored locally in .invar/feedback/
|
|
254
|
+
- Never sent automatically
|
|
255
|
+
- You decide what (if anything) to share
|
|
256
|
+
|
|
257
|
+
Enable automatic feedback collection? [Y/n]:
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Privacy & Security
|
|
263
|
+
|
|
264
|
+
**What's stored**:
|
|
265
|
+
- Tool usage statistics (counts, success/failure)
|
|
266
|
+
- Error types (NO error messages)
|
|
267
|
+
- Session metadata (duration, message count)
|
|
268
|
+
- User's subjective experience (generated by AI)
|
|
269
|
+
|
|
270
|
+
**What's NOT stored**:
|
|
271
|
+
- Source code
|
|
272
|
+
- File paths (anonymized)
|
|
273
|
+
- Error messages (might contain code)
|
|
274
|
+
- Project-specific details
|
|
275
|
+
|
|
276
|
+
**All data stays local** in `.invar/feedback/`. User reviews before sharing.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Testing (Phase B Acceptance Criteria)
|
|
281
|
+
|
|
282
|
+
### Manual Testing
|
|
283
|
+
|
|
284
|
+
1. **Test manual invocation**:
|
|
285
|
+
```bash
|
|
286
|
+
# In Claude Code session
|
|
287
|
+
/invar-reflect
|
|
288
|
+
```
|
|
289
|
+
- ✅ Generates feedback file
|
|
290
|
+
- ✅ Saves to `.invar/feedback/feedback-{today}.md`
|
|
291
|
+
- ✅ No errors
|
|
292
|
+
|
|
293
|
+
2. **Test config disable**:
|
|
294
|
+
```json
|
|
295
|
+
// .claude/settings.local.json
|
|
296
|
+
{ "feedback": { "enabled": false } }
|
|
297
|
+
```
|
|
298
|
+
- ✅ `/invar-reflect` still works (manual override)
|
|
299
|
+
- ✅ Hook doesn't trigger (when implemented)
|
|
300
|
+
|
|
301
|
+
3. **Test same-day merge**:
|
|
302
|
+
```bash
|
|
303
|
+
# Session 1: Morning
|
|
304
|
+
/invar-reflect
|
|
305
|
+
# Creates feedback-2026-01-03.md
|
|
306
|
+
|
|
307
|
+
# Session 2: Afternoon (same day)
|
|
308
|
+
/invar-reflect
|
|
309
|
+
# Updates feedback-2026-01-03.md (not create new file)
|
|
310
|
+
```
|
|
311
|
+
- ✅ Single file per day
|
|
312
|
+
- ✅ Intelligent merging (semantic understanding)
|
|
313
|
+
- ✅ Daily summary regenerated
|
|
314
|
+
|
|
315
|
+
### Automated Testing (when hook is implemented)
|
|
316
|
+
|
|
317
|
+
1. **Test condition thresholds**:
|
|
318
|
+
- Session < 30 messages: Hook doesn't trigger
|
|
319
|
+
- Session < 2 hours: Hook doesn't trigger
|
|
320
|
+
- Session >= 30 messages AND >= 2 hours: Hook triggers
|
|
321
|
+
|
|
322
|
+
2. **Test silent mode**:
|
|
323
|
+
- Hook triggers in background
|
|
324
|
+
- No interruption to conversation
|
|
325
|
+
- Notification shown only
|
|
326
|
+
|
|
327
|
+
3. **Test retention**:
|
|
328
|
+
- Files older than 90 days auto-deleted
|
|
329
|
+
- Configurable via `retention_days`
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## Phase B Status
|
|
334
|
+
|
|
335
|
+
**Completed**:
|
|
336
|
+
- ✅ Hook schema designed
|
|
337
|
+
- ✅ Configuration structure defined
|
|
338
|
+
- ✅ User control mechanism specified
|
|
339
|
+
- ✅ Stop hook workaround documented
|
|
340
|
+
|
|
341
|
+
**Waiting for Claude Code Support**:
|
|
342
|
+
- ⏸️ PostTaskCompletion hook type
|
|
343
|
+
- ⏸️ Skill invocation from hooks
|
|
344
|
+
- ⏸️ Session state tracking (message count, duration)
|
|
345
|
+
|
|
346
|
+
**Next Steps**:
|
|
347
|
+
- Implement Phase C: Init Integration (can be done independently)
|
|
348
|
+
- Submit feature request to Claude Code for PostTaskCompletion hook
|
|
349
|
+
- Test manual `/invar-reflect` invocation thoroughly
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
**Version**: 1.0 (Phase B - Proposed)
|
|
354
|
+
**Updated**: 2026-01-03
|
|
355
|
+
**Related**: DX-79 Invar Usage Feedback Collection
|