claude-code-autoconfig 1.0.110 → 1.0.111
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.
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
<!-- @description Recovers conversation context from the session transcript after compaction. -->
|
|
2
|
+
Recover recent conversation context from the raw session transcript on disk.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
- `/recover-context -60` — last 60 minutes of conversation
|
|
6
|
+
- `/recover-context -30` — last 30 minutes
|
|
7
|
+
- `/recover-context -120` — last 2 hours
|
|
8
|
+
- `/recover-context -60 --show` — same as above, but also opens the filtered transcript in default editor
|
|
9
|
+
|
|
10
|
+
The negative number means "go back N minutes from now." The minutes argument is **required**.
|
|
11
|
+
|
|
12
|
+
## Step 1: Parse the arguments
|
|
13
|
+
|
|
14
|
+
The arguments are: $ARGUMENTS
|
|
15
|
+
|
|
16
|
+
- If empty or missing, ask the user: "How many minutes back? (e.g., -60)"
|
|
17
|
+
- Strip the leading `-` from the number and treat it as the number of minutes to look back
|
|
18
|
+
- Check if `--show` flag is present
|
|
19
|
+
|
|
20
|
+
## Step 2: Find the transcript file
|
|
21
|
+
|
|
22
|
+
Find the current session's transcript by looking for the most recently modified `.jsonl` file in the Claude projects directory:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
ls -t ~/.claude/projects/*/*.jsonl 2>/dev/null | head -1
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
If no transcript is found, tell the user and stop.
|
|
29
|
+
|
|
30
|
+
## Step 3: Extract conversation context
|
|
31
|
+
|
|
32
|
+
Run this Python script to extract the stripped-down conversation. Substitute `$MINUTES` with the resolved minutes value and `$TRANSCRIPT_PATH` with the path from Step 2:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
python3 -c "
|
|
36
|
+
import json, os, sys, tempfile
|
|
37
|
+
from datetime import datetime, timezone, timedelta
|
|
38
|
+
|
|
39
|
+
minutes = '$MINUTES'
|
|
40
|
+
path = '$TRANSCRIPT_PATH'
|
|
41
|
+
|
|
42
|
+
cutoff = datetime.now(timezone.utc) - timedelta(minutes=int(minutes))
|
|
43
|
+
|
|
44
|
+
results = []
|
|
45
|
+
with open(path, encoding='utf-8', errors='replace') as f:
|
|
46
|
+
for line in f:
|
|
47
|
+
line = line.strip()
|
|
48
|
+
if not line:
|
|
49
|
+
continue
|
|
50
|
+
try:
|
|
51
|
+
obj = json.loads(line)
|
|
52
|
+
except:
|
|
53
|
+
continue
|
|
54
|
+
|
|
55
|
+
t = obj.get('type')
|
|
56
|
+
if t not in ('user', 'assistant'):
|
|
57
|
+
continue
|
|
58
|
+
|
|
59
|
+
ts = obj.get('timestamp')
|
|
60
|
+
if not ts:
|
|
61
|
+
continue
|
|
62
|
+
|
|
63
|
+
# Parse timestamp
|
|
64
|
+
parsed_ts = datetime.fromisoformat(ts.replace('Z', '+00:00'))
|
|
65
|
+
if parsed_ts < cutoff:
|
|
66
|
+
continue
|
|
67
|
+
|
|
68
|
+
parent = obj.get('parentUuid', '')
|
|
69
|
+
msg = obj.get('message', {})
|
|
70
|
+
|
|
71
|
+
# Extract text content
|
|
72
|
+
text = ''
|
|
73
|
+
if t == 'user':
|
|
74
|
+
content = msg.get('content', '')
|
|
75
|
+
if isinstance(content, str):
|
|
76
|
+
text = content
|
|
77
|
+
elif isinstance(content, list):
|
|
78
|
+
# Skip tool_result messages
|
|
79
|
+
if any(isinstance(c, dict) and c.get('type') == 'tool_result' for c in content):
|
|
80
|
+
continue
|
|
81
|
+
text = ' '.join(c.get('text', '') for c in content if isinstance(c, dict) and c.get('type') == 'text')
|
|
82
|
+
elif t == 'assistant':
|
|
83
|
+
content = msg.get('content', [])
|
|
84
|
+
if isinstance(content, list):
|
|
85
|
+
texts = [c.get('text', '') for c in content if isinstance(c, dict) and c.get('type') == 'text']
|
|
86
|
+
text = '\n'.join(texts)
|
|
87
|
+
|
|
88
|
+
if not text.strip():
|
|
89
|
+
continue
|
|
90
|
+
|
|
91
|
+
results.append({
|
|
92
|
+
'parentUuid': parent,
|
|
93
|
+
'type': t,
|
|
94
|
+
'timestamp': ts,
|
|
95
|
+
'text': text.strip()
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
# Write to temp file
|
|
99
|
+
tmp = os.path.join(tempfile.gettempdir(), 'recovered-context.json')
|
|
100
|
+
with open(tmp, 'w', encoding='utf-8') as f:
|
|
101
|
+
json.dump(results, f, indent=2, ensure_ascii=False)
|
|
102
|
+
|
|
103
|
+
# Output stats
|
|
104
|
+
total_bytes = os.path.getsize(tmp)
|
|
105
|
+
print(json.dumps({
|
|
106
|
+
'messages': len(results),
|
|
107
|
+
'bytes': total_bytes,
|
|
108
|
+
'tempFile': tmp
|
|
109
|
+
}))
|
|
110
|
+
"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Step 4: Confirm recovery
|
|
114
|
+
|
|
115
|
+
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
|
+
|
|
117
|
+
Then display a confirmation message:
|
|
118
|
+
|
|
119
|
+
> **{bytes} of transcript recovered and persisted into context ({N} messages, last {minutes} minutes).** Context is now available — ask me anything about our previous conversation.
|
|
120
|
+
>
|
|
121
|
+
> To see the specific context restored to this session, run `/recover-context -{minutes} --show`
|
|
122
|
+
|
|
123
|
+
## Step 5: Open transcript (if --show flag)
|
|
124
|
+
|
|
125
|
+
If the `--show` flag was provided, open the temp file in the default editor. Detect the OS and run the appropriate command:
|
|
126
|
+
|
|
127
|
+
- **Windows:** `start "" "$TEMP_FILE"`
|
|
128
|
+
- **macOS:** `open "$TEMP_FILE"`
|
|
129
|
+
- **Linux:** `xdg-open "$TEMP_FILE"`
|
|
130
|
+
|
|
131
|
+
## Step 6: Resume work
|
|
132
|
+
|
|
133
|
+
Tell the user:
|
|
134
|
+
|
|
135
|
+
> What would you like to continue working on?
|
|
136
|
+
|
|
137
|
+
Do NOT take any action — wait for the user to direct you.
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
<!-- @title Recover Context -->
|
|
2
|
+
<!-- @type feature -->
|
|
3
|
+
<!-- @description Slash command to recover conversation context from session transcript after compaction -->
|
|
4
|
+
<!-- @files .claude/commands/recover-context.md -->
|
|
5
|
+
|
|
6
|
+
# Apply Recover Context Update
|
|
7
|
+
|
|
8
|
+
Create the file `.claude/commands/recover-context.md` with the following content:
|
|
9
|
+
|
|
10
|
+
````markdown
|
|
11
|
+
<!-- @description Recovers conversation context from the session transcript after compaction. -->
|
|
12
|
+
Recover recent conversation context from the raw session transcript on disk.
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
- `/recover-context -60` — last 60 minutes of conversation
|
|
16
|
+
- `/recover-context -30` — last 30 minutes
|
|
17
|
+
- `/recover-context -120` — last 2 hours
|
|
18
|
+
- `/recover-context -60 --show` — same as above, but also opens the filtered transcript in default editor
|
|
19
|
+
|
|
20
|
+
The negative number means "go back N minutes from now." The minutes argument is **required**.
|
|
21
|
+
|
|
22
|
+
## Step 1: Parse the arguments
|
|
23
|
+
|
|
24
|
+
The arguments are: $ARGUMENTS
|
|
25
|
+
|
|
26
|
+
- If empty or missing, ask the user: "How many minutes back? (e.g., -60)"
|
|
27
|
+
- Strip the leading `-` from the number and treat it as the number of minutes to look back
|
|
28
|
+
- Check if `--show` flag is present
|
|
29
|
+
|
|
30
|
+
## Step 2: Find the transcript file
|
|
31
|
+
|
|
32
|
+
Find the current session's transcript by looking for the most recently modified `.jsonl` file in the Claude projects directory:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
ls -t ~/.claude/projects/*/*.jsonl 2>/dev/null | head -1
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
If no transcript is found, tell the user and stop.
|
|
39
|
+
|
|
40
|
+
## Step 3: Extract conversation context
|
|
41
|
+
|
|
42
|
+
Run this Python script to extract the stripped-down conversation. Substitute `$MINUTES` with the resolved minutes value and `$TRANSCRIPT_PATH` with the path from Step 2:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
python3 -c "
|
|
46
|
+
import json, os, sys, tempfile
|
|
47
|
+
from datetime import datetime, timezone, timedelta
|
|
48
|
+
|
|
49
|
+
minutes = '$MINUTES'
|
|
50
|
+
path = '$TRANSCRIPT_PATH'
|
|
51
|
+
|
|
52
|
+
cutoff = datetime.now(timezone.utc) - timedelta(minutes=int(minutes))
|
|
53
|
+
|
|
54
|
+
results = []
|
|
55
|
+
with open(path, encoding='utf-8', errors='replace') as f:
|
|
56
|
+
for line in f:
|
|
57
|
+
line = line.strip()
|
|
58
|
+
if not line:
|
|
59
|
+
continue
|
|
60
|
+
try:
|
|
61
|
+
obj = json.loads(line)
|
|
62
|
+
except:
|
|
63
|
+
continue
|
|
64
|
+
|
|
65
|
+
t = obj.get('type')
|
|
66
|
+
if t not in ('user', 'assistant'):
|
|
67
|
+
continue
|
|
68
|
+
|
|
69
|
+
ts = obj.get('timestamp')
|
|
70
|
+
if not ts:
|
|
71
|
+
continue
|
|
72
|
+
|
|
73
|
+
# Parse timestamp
|
|
74
|
+
parsed_ts = datetime.fromisoformat(ts.replace('Z', '+00:00'))
|
|
75
|
+
if parsed_ts < cutoff:
|
|
76
|
+
continue
|
|
77
|
+
|
|
78
|
+
parent = obj.get('parentUuid', '')
|
|
79
|
+
msg = obj.get('message', {})
|
|
80
|
+
|
|
81
|
+
# Extract text content
|
|
82
|
+
text = ''
|
|
83
|
+
if t == 'user':
|
|
84
|
+
content = msg.get('content', '')
|
|
85
|
+
if isinstance(content, str):
|
|
86
|
+
text = content
|
|
87
|
+
elif isinstance(content, list):
|
|
88
|
+
# Skip tool_result messages
|
|
89
|
+
if any(isinstance(c, dict) and c.get('type') == 'tool_result' for c in content):
|
|
90
|
+
continue
|
|
91
|
+
text = ' '.join(c.get('text', '') for c in content if isinstance(c, dict) and c.get('type') == 'text')
|
|
92
|
+
elif t == 'assistant':
|
|
93
|
+
content = msg.get('content', [])
|
|
94
|
+
if isinstance(content, list):
|
|
95
|
+
texts = [c.get('text', '') for c in content if isinstance(c, dict) and c.get('type') == 'text']
|
|
96
|
+
text = '\n'.join(texts)
|
|
97
|
+
|
|
98
|
+
if not text.strip():
|
|
99
|
+
continue
|
|
100
|
+
|
|
101
|
+
results.append({
|
|
102
|
+
'parentUuid': parent,
|
|
103
|
+
'type': t,
|
|
104
|
+
'timestamp': ts,
|
|
105
|
+
'text': text.strip()
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
# Write to temp file
|
|
109
|
+
tmp = os.path.join(tempfile.gettempdir(), 'recovered-context.json')
|
|
110
|
+
with open(tmp, 'w', encoding='utf-8') as f:
|
|
111
|
+
json.dump(results, f, indent=2, ensure_ascii=False)
|
|
112
|
+
|
|
113
|
+
# Output stats
|
|
114
|
+
total_bytes = os.path.getsize(tmp)
|
|
115
|
+
print(json.dumps({
|
|
116
|
+
'messages': len(results),
|
|
117
|
+
'bytes': total_bytes,
|
|
118
|
+
'tempFile': tmp
|
|
119
|
+
}))
|
|
120
|
+
"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Step 4: Confirm recovery
|
|
124
|
+
|
|
125
|
+
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.
|
|
126
|
+
|
|
127
|
+
Then display a confirmation message:
|
|
128
|
+
|
|
129
|
+
> **{bytes} of transcript recovered and persisted into context ({N} messages, last {minutes} minutes).** Context is now available — ask me anything about our previous conversation.
|
|
130
|
+
>
|
|
131
|
+
> To see the specific context restored to this session, run `/recover-context -{minutes} --show`
|
|
132
|
+
|
|
133
|
+
## Step 5: Open transcript (if --show flag)
|
|
134
|
+
|
|
135
|
+
If the `--show` flag was provided, open the temp file in the default editor. Detect the OS and run the appropriate command:
|
|
136
|
+
|
|
137
|
+
- **Windows:** `start "" "$TEMP_FILE"`
|
|
138
|
+
- **macOS:** `open "$TEMP_FILE"`
|
|
139
|
+
- **Linux:** `xdg-open "$TEMP_FILE"`
|
|
140
|
+
|
|
141
|
+
## Step 6: Resume work
|
|
142
|
+
|
|
143
|
+
Tell the user:
|
|
144
|
+
|
|
145
|
+
> What would you like to continue working on?
|
|
146
|
+
|
|
147
|
+
Do NOT take any action — wait for the user to direct you.
|
|
148
|
+
````
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-code-autoconfig",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.111",
|
|
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",
|