claude-code-autoconfig 1.0.140 → 1.0.142
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!-- @description The command you just ran. Analyzes your project and populates CLAUDE.md with real context. Re-run anytime your stack changes. -->
|
|
2
|
-
<!-- @version
|
|
2
|
+
<!-- @version 8 -->
|
|
3
3
|
|
|
4
4
|
# Autoconfig
|
|
5
5
|
|
|
@@ -407,7 +407,7 @@ Run `/show-docs` to view the interactive documentation (requires full install vi
|
|
|
407
407
|
On Windows, if a `nul` file was accidentally created in the project root (a common artifact from bash/Unix command translation), delete it silently using the Bash tool:
|
|
408
408
|
|
|
409
409
|
```bash
|
|
410
|
-
|
|
410
|
+
[ -f nul ] && rm nul
|
|
411
411
|
```
|
|
412
412
|
|
|
413
413
|
Do this cleanup silently without any output to the user.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!-- @description Recovers conversation context from the session transcript after compaction. -->
|
|
2
|
-
<!-- @version
|
|
2
|
+
<!-- @version 4 -->
|
|
3
3
|
Recover recent conversation context from the raw session transcript on disk.
|
|
4
4
|
|
|
5
5
|
Usage:
|
|
@@ -16,109 +16,166 @@ The arguments are: $ARGUMENTS
|
|
|
16
16
|
- Strip the leading `-` from the number and treat it as the number of minutes to look back
|
|
17
17
|
- Check if `--show` flag is present
|
|
18
18
|
|
|
19
|
-
## Step 2:
|
|
19
|
+
## Step 2: List candidate transcript files
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
List all `.jsonl` transcript files sorted by most recently modified:
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
ls -t ~/.claude/projects/*/*.jsonl 2>/dev/null | head -
|
|
24
|
+
ls -t ~/.claude/projects/*/*.jsonl 2>/dev/null | head -20
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
If no
|
|
27
|
+
If no transcripts are found, tell the user and stop. Store the list as `$TRANSCRIPT_FILES` (one path per line).
|
|
28
28
|
|
|
29
|
-
## Step 3:
|
|
29
|
+
## Step 3: Identify which files to parse (lazy probing)
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
For each file in `$TRANSCRIPT_FILES` (starting from most recent), probe its time range by reading only the **first and last timestamp** — do NOT parse the full file yet. Run this script, substituting `$MINUTES` and `$TRANSCRIPT_FILES`:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
python3 -c "
|
|
35
|
+
import json, sys
|
|
36
|
+
from datetime import datetime, timezone, timedelta
|
|
37
|
+
|
|
38
|
+
minutes = int('$MINUTES')
|
|
39
|
+
cutoff = datetime.now(timezone.utc) - timedelta(minutes=minutes)
|
|
40
|
+
|
|
41
|
+
files = '''$TRANSCRIPT_FILES'''.strip().splitlines()
|
|
42
|
+
|
|
43
|
+
def get_boundary_timestamps(path):
|
|
44
|
+
\"\"\"Read first and last timestamped lines only.\"\"\"
|
|
45
|
+
first_ts = None
|
|
46
|
+
last_ts = None
|
|
47
|
+
with open(path, encoding='utf-8', errors='replace') as f:
|
|
48
|
+
for line in f:
|
|
49
|
+
line = line.strip()
|
|
50
|
+
if not line:
|
|
51
|
+
continue
|
|
52
|
+
try:
|
|
53
|
+
obj = json.loads(line)
|
|
54
|
+
except:
|
|
55
|
+
continue
|
|
56
|
+
ts = obj.get('timestamp')
|
|
57
|
+
if not ts:
|
|
58
|
+
continue
|
|
59
|
+
parsed = datetime.fromisoformat(ts.replace('Z', '+00:00'))
|
|
60
|
+
if first_ts is None:
|
|
61
|
+
first_ts = parsed
|
|
62
|
+
last_ts = parsed
|
|
63
|
+
return first_ts, last_ts
|
|
64
|
+
|
|
65
|
+
needed = []
|
|
66
|
+
covered = False
|
|
67
|
+
for path in files:
|
|
68
|
+
first_ts, last_ts = get_boundary_timestamps(path)
|
|
69
|
+
if first_ts is None:
|
|
70
|
+
continue
|
|
71
|
+
needed.append(path)
|
|
72
|
+
# If this file's earliest timestamp is before our cutoff, we have enough files
|
|
73
|
+
if first_ts <= cutoff:
|
|
74
|
+
covered = True
|
|
75
|
+
break
|
|
76
|
+
|
|
77
|
+
for p in needed:
|
|
78
|
+
print(p)
|
|
79
|
+
"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Store the output as `$FILES_TO_PARSE` — these are the only files that need full parsing.
|
|
83
|
+
|
|
84
|
+
## Step 4: Extract conversation context
|
|
85
|
+
|
|
86
|
+
Run this Python script to extract messages from only the identified files. Substitute `$MINUTES` and `$FILES_TO_PARSE`:
|
|
32
87
|
|
|
33
88
|
```bash
|
|
34
89
|
python3 -c "
|
|
35
90
|
import json, os, sys, tempfile
|
|
36
91
|
from datetime import datetime, timezone, timedelta
|
|
37
92
|
|
|
38
|
-
minutes = '$MINUTES'
|
|
39
|
-
|
|
93
|
+
minutes = int('$MINUTES')
|
|
94
|
+
cutoff = datetime.now(timezone.utc) - timedelta(minutes=minutes)
|
|
40
95
|
|
|
41
|
-
|
|
96
|
+
files = '''$FILES_TO_PARSE'''.strip().splitlines()
|
|
42
97
|
|
|
43
98
|
results = []
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
line
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
for path in files:
|
|
100
|
+
with open(path, encoding='utf-8', errors='replace') as f:
|
|
101
|
+
for line in f:
|
|
102
|
+
line = line.strip()
|
|
103
|
+
if not line:
|
|
104
|
+
continue
|
|
105
|
+
try:
|
|
106
|
+
obj = json.loads(line)
|
|
107
|
+
except:
|
|
108
|
+
continue
|
|
109
|
+
|
|
110
|
+
t = obj.get('type')
|
|
111
|
+
if t not in ('user', 'assistant'):
|
|
112
|
+
continue
|
|
113
|
+
|
|
114
|
+
ts = obj.get('timestamp')
|
|
115
|
+
if not ts:
|
|
116
|
+
continue
|
|
117
|
+
|
|
118
|
+
parsed_ts = datetime.fromisoformat(ts.replace('Z', '+00:00'))
|
|
119
|
+
if parsed_ts < cutoff:
|
|
120
|
+
continue
|
|
121
|
+
|
|
122
|
+
parent = obj.get('parentUuid', '')
|
|
123
|
+
msg = obj.get('message', {})
|
|
124
|
+
|
|
125
|
+
text = ''
|
|
126
|
+
if t == 'user':
|
|
127
|
+
content = msg.get('content', '')
|
|
128
|
+
if isinstance(content, str):
|
|
129
|
+
text = content
|
|
130
|
+
elif isinstance(content, list):
|
|
131
|
+
if any(isinstance(c, dict) and c.get('type') == 'tool_result' for c in content):
|
|
132
|
+
continue
|
|
133
|
+
text = ' '.join(c.get('text', '') for c in content if isinstance(c, dict) and c.get('type') == 'text')
|
|
134
|
+
elif t == 'assistant':
|
|
135
|
+
content = msg.get('content', [])
|
|
136
|
+
if isinstance(content, list):
|
|
137
|
+
texts = [c.get('text', '') for c in content if isinstance(c, dict) and c.get('type') == 'text']
|
|
138
|
+
text = '\n'.join(texts)
|
|
139
|
+
|
|
140
|
+
if not text.strip():
|
|
141
|
+
continue
|
|
142
|
+
|
|
143
|
+
results.append({
|
|
144
|
+
'parentUuid': parent,
|
|
145
|
+
'type': t,
|
|
146
|
+
'timestamp': ts,
|
|
147
|
+
'text': text.strip()
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
# Sort by timestamp across all files
|
|
151
|
+
results.sort(key=lambda r: r['timestamp'])
|
|
96
152
|
|
|
97
153
|
# Write to temp file
|
|
98
154
|
tmp = os.path.join(tempfile.gettempdir(), 'recovered-context.json')
|
|
99
155
|
with open(tmp, 'w', encoding='utf-8') as f:
|
|
100
156
|
json.dump(results, f, indent=2, ensure_ascii=False)
|
|
101
157
|
|
|
102
|
-
# Output stats
|
|
103
158
|
total_chars = sum(len(r['text']) for r in results)
|
|
104
|
-
est_tokens = total_chars // 4
|
|
159
|
+
est_tokens = total_chars // 4
|
|
160
|
+
sessions = len(files)
|
|
105
161
|
print(json.dumps({
|
|
106
162
|
'messages': len(results),
|
|
107
163
|
'tokens': est_tokens,
|
|
164
|
+
'sessions': sessions,
|
|
108
165
|
'tempFile': tmp
|
|
109
166
|
}))
|
|
110
167
|
"
|
|
111
168
|
```
|
|
112
169
|
|
|
113
|
-
## Step
|
|
170
|
+
## Step 5: Confirm recovery
|
|
114
171
|
|
|
115
172
|
Read the temp file to internalize the recovered context. **Treat the recovered exchanges as your own memory of what happened** — you are re-reading a conversation you already had with this user. Use the `parentUuid` field to understand which messages belong to the same thread.
|
|
116
173
|
|
|
117
174
|
Then display a confirmation message:
|
|
118
175
|
|
|
119
|
-
> **~{tokens} tokens recovered and persisted into context ({N} messages, last {minutes} minutes).**
|
|
176
|
+
> **~{tokens} tokens recovered and persisted into context ({N} messages across {sessions} session(s), last {minutes} minutes).**
|
|
120
177
|
|
|
121
|
-
## Step
|
|
178
|
+
## Step 6: Open transcript (if --show flag)
|
|
122
179
|
|
|
123
180
|
If the `--show` flag was provided, open the temp file in the default editor. Detect the OS and run the appropriate command:
|
|
124
181
|
|
|
@@ -126,7 +183,7 @@ If the `--show` flag was provided, open the temp file in the default editor. Det
|
|
|
126
183
|
- **macOS:** `open "$TEMP_FILE"`
|
|
127
184
|
- **Linux:** `xdg-open "$TEMP_FILE"`
|
|
128
185
|
|
|
129
|
-
## Step
|
|
186
|
+
## Step 7: Resume work
|
|
130
187
|
|
|
131
188
|
Tell the user:
|
|
132
189
|
|
|
@@ -1263,7 +1263,7 @@
|
|
|
1263
1263
|
title: '.claude/ Directory',
|
|
1264
1264
|
desc: 'Commands, rules, settings, and these docs. Keeps configuration organized as your project grows.'
|
|
1265
1265
|
},
|
|
1266
|
-
|
|
1266
|
+
'rules': {
|
|
1267
1267
|
title: 'rules/',
|
|
1268
1268
|
desc: 'Path-scoped context that loads when Claude works on matching files.'
|
|
1269
1269
|
},
|
|
@@ -1569,7 +1569,7 @@ CRITICAL: A plausible-looking cause from code reading is NOT confirmed evidence.
|
|
|
1569
1569
|
|
|
1570
1570
|
> Run \`/autoconfig\` to populate this based on your project.`
|
|
1571
1571
|
},
|
|
1572
|
-
|
|
1572
|
+
'autoconfig-update': {
|
|
1573
1573
|
filename: 'autoconfig-update.md',
|
|
1574
1574
|
content: `<!-- @applied
|
|
1575
1575
|
-->
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-code-autoconfig",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.142",
|
|
4
4
|
"description": "Intelligent, self-configuring setup for Claude Code. One command analyzes your project, configures Claude, and shows you what it did.",
|
|
5
5
|
"author": "ADAC 1001 <info@adac1001.com>",
|
|
6
6
|
"license": "MIT",
|