elliot-stack 1.0.28 → 1.0.30
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.
package/README.md
CHANGED
|
@@ -20,13 +20,14 @@ This installs skills to `~/.agents/skills/` and symlinks them into `~/.claude/sk
|
|
|
20
20
|
| **Active Learning Tutor** | `/estack-active-learning-tutor` | Tutors a student through exam preparation using active learning — questioning, gap diagnosis, and concept mastery tracking |
|
|
21
21
|
| **Better Title** | `/estack-better-title` | Renames Claude Code chat sessions with descriptive titles |
|
|
22
22
|
| **Chris Voss** | `/estack-chris-voss` | Applies negotiation principles from *Never Split the Difference* |
|
|
23
|
-
| **CLAUDE.md Optimizer** | `/estack-claude-md-optimizer` | Creates, refines, and maintains CLAUDE.md / AGENTS.md files as short hand-authored letters of intent |
|
|
23
|
+
| **CLAUDE.md Optimizer** | `/estack-claude-md-optimizer` | Creates, refines, and maintains CLAUDE.md / AGENTS.md files as short hand-authored letters of intent — welcomes first-time users with the why behind the format and coaches through pushback instead of enforcing rules |
|
|
24
24
|
| **Customer Discovery** | `/estack-customer-discovery` | Guides through customer discovery — validating ideas, outreach, interviews, and analysis |
|
|
25
25
|
| **Flight Planner** | `/estack-flight-planner` | Finds and ranks flights between two airports with config-driven preferences and optional ground-shuttle pairing |
|
|
26
26
|
| **GitHub Issue Tracker** | `/estack-github-issue-tracker` | Tracks and manages GitHub issues across repos |
|
|
27
27
|
| **Prompt Builder Coach** | `/estack-prompt-builder-coach` | Four-part kit for shaping, building, auditing, and scoping prompts for AI agents |
|
|
28
28
|
| **Read Claude Session History** | `/estack-read-claude-session-history` | Searches, reads, recovers, and compares Claude Code session history across sessions, projects, and backups |
|
|
29
29
|
| **Repo Search** | `/estack-repo-search` | Clones and searches external GitHub repos to answer questions about their code |
|
|
30
|
+
| **VS Code File Recovery** | `/estack-vscode-file-recovery` | Recovers permanently deleted files from VS Code or Cursor Local History, Claude session transcripts, or Windows Shadow Copies |
|
|
30
31
|
|
|
31
32
|
## Hooks
|
|
32
33
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: estack-claude-md-optimizer
|
|
3
|
-
version: 1.0
|
|
3
|
+
version: 1.2.0
|
|
4
4
|
description: >-
|
|
5
5
|
(claude-md-optimizer) Create, refine, and maintain CLAUDE.md / AGENTS.md files
|
|
6
6
|
as short hand-authored letters of intent. Use whenever the user asks to create,
|
|
@@ -18,33 +18,82 @@ their intent, mental model, and the "why" — not a spec, not a rulebook, not an
|
|
|
18
18
|
encyclopedia. This skill helps them write and keep that letter. It is a router:
|
|
19
19
|
triage below, then read exactly one route file and follow it.
|
|
20
20
|
|
|
21
|
-
## Opening message —
|
|
21
|
+
## Opening message — welcome and teach first
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
Assume the user has never used this skill before. Your first message is a
|
|
24
|
+
letter addressed directly to the user — warm, second-person, personal — not
|
|
25
|
+
a doc page, not a feature list. It teaches the same core ideas but reads like
|
|
26
|
+
someone explaining something they care about, not a manual. After the letter,
|
|
27
|
+
a routing table shows exactly what's happening in this session.
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
- **Why it works that way:** bloated context files measurably make models worse
|
|
30
|
-
— the model isn't dumb, it's drowning. Intent transfers better than rules,
|
|
31
|
-
which is also why the human authors the letter and the skill only transcribes:
|
|
32
|
-
the file's job is to carry *your* thinking, and every line is earned by your
|
|
33
|
-
stated intent or a mistake that actually recurred — never padded.
|
|
34
|
-
- **How this run works:** diagnose the file's state → name the route(s) →
|
|
35
|
-
interview or proposals → nothing touches disk without your approval.
|
|
29
|
+
Structure the opening exactly like this (fill in the session plan table based
|
|
30
|
+
on your triage — see the Triage section below for how to pick routes):
|
|
36
31
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
Hey — welcome to the CLAUDE.md Optimizer.
|
|
35
|
+
|
|
36
|
+
Before we start, here's what you should know about how this works and why.
|
|
37
|
+
|
|
38
|
+
**Your `CLAUDE.md` is a letter, not a rulebook.** When you hand an agent
|
|
39
|
+
the *why* behind your decisions, it can generalize to situations no rule
|
|
40
|
+
anticipated. When you hand it a rulebook, it follows the rules off a cliff.
|
|
41
|
+
The file's only job is to carry your thinking — so you author it, and I
|
|
42
|
+
transcribe.
|
|
43
|
+
|
|
44
|
+
**It has to stay short.** Every line in that file competes with your actual
|
|
45
|
+
task for the model's attention. Bloated context files measurably make models
|
|
46
|
+
worse — not because the model is dumb, but because it's drowning. Every line
|
|
47
|
+
has to be earned: either by something you've told me you care about, or by a
|
|
48
|
+
mistake that actually recurred. Never padded.
|
|
49
|
+
|
|
50
|
+
**You start with a letter. Routing comes later, only if it's earned.** Most
|
|
51
|
+
projects don't need a routing section — a tight letter plus model intelligence
|
|
52
|
+
gets there. Structure added before the project demands it is just bloat with
|
|
53
|
+
good posture.
|
|
54
|
+
|
|
55
|
+
**No commands, paths, or stack details in the file.** The agent finds those
|
|
56
|
+
itself, faster and more accurately than a file can stay current. Stale paths
|
|
57
|
+
don't just not help — they actively mislead.
|
|
58
|
+
|
|
59
|
+
Here's what we're doing today:
|
|
60
|
+
|
|
61
|
+
| Step | What's happening | Why |
|
|
62
|
+
|------|-----------------|-----|
|
|
63
|
+
| **Diagnose** | I read your current file (or confirm there isn't one) | Can't plan without knowing where we're starting |
|
|
64
|
+
| **Route** | I name which flow(s) apply and tell you why | So you can correct me before anything starts |
|
|
65
|
+
| **[Route-specific steps]** | Interview, proposals, line-by-line review — depends on the route | See below |
|
|
66
|
+
| **Approve & write** | Nothing touches disk until you've signed off on every line | The file is yours |
|
|
67
|
+
|
|
68
|
+
*(I'll replace [Route-specific steps] with the actual steps once I've triaged
|
|
69
|
+
the file and named the route — usually 2–3 more rows.)*
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
Two exceptions skip the full welcome: quick capture (triage #3) skips the
|
|
74
|
+
opening entirely, and a mid-session "add X to my CLAUDE.md" gets a one-line
|
|
75
|
+
greeting at most — they're in the middle of work, not onboarding.
|
|
76
|
+
|
|
77
|
+
After writing the letter and table above, immediately move into the triage
|
|
78
|
+
announcement — one or two sentences naming which route(s) you're entering and
|
|
79
|
+
why, then pause for them to correct you.
|
|
40
80
|
|
|
41
81
|
## Progress header — every message, every step
|
|
42
82
|
|
|
43
|
-
After the opening message, start every subsequent output with a one-line
|
|
44
|
-
where we are in the flow, roughly what's left, and — most important —
|
|
45
|
-
the flow is DONE or NOT DONE.
|
|
83
|
+
After the opening message, start every subsequent output with a one-line status
|
|
84
|
+
header: where we are in the flow, roughly what's left, and — most important —
|
|
85
|
+
whether the flow is DONE or NOT DONE. Render it inside a fenced code block
|
|
86
|
+
drawn as a box, so it reads as a status instrument visually separate from the
|
|
87
|
+
message itself, verbatim format:
|
|
46
88
|
|
|
47
|
-
|
|
89
|
+
```
|
|
90
|
+
┌──────────────────────────────────────────────────────────────
|
|
91
|
+
│ Create · step 2 of 4 (interview) · ~2 steps left · NOT DONE — next: draft
|
|
92
|
+
└──────────────────────────────────────────────────────────────
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
(The right edge stays open — never fiddle with padding to close the box. Keep
|
|
96
|
+
the border lines exactly that width regardless of the status text's length.)
|
|
48
97
|
|
|
49
98
|
Estimates are allowed to be rough (an incomplete answer can keep a step alive an
|
|
50
99
|
extra turn — fine, don't apologize, just keep the count honest). What is not
|
|
@@ -148,6 +197,31 @@ session-capture first.
|
|
|
148
197
|
and won't follow a pointer into AGENTS.md, so that direction is the only one
|
|
149
198
|
that works for every tool.
|
|
150
199
|
|
|
200
|
+
## Coaching on pushback — teach, don't enforce
|
|
201
|
+
|
|
202
|
+
When the user pushes back at any point — questioning a deletion, wanting to
|
|
203
|
+
keep commands or file paths, arguing the cap is arbitrary, wanting routing
|
|
204
|
+
structure up front — treat it as a coaching moment, never a rule violation.
|
|
205
|
+
Read the relevant reference in `references/` and explain the why behind the
|
|
206
|
+
principle in plain language, grounded in the source mentality, not just
|
|
207
|
+
restated as the rule. Then genuinely weigh their point — they might be right:
|
|
208
|
+
|
|
209
|
+
1. **Their point is about their file** and they state a live reason after
|
|
210
|
+
hearing the why (e.g. a path the agent genuinely can't find, a rule earned
|
|
211
|
+
by real recurring pain): that stated reason *is* a trace under hard rule 3.
|
|
212
|
+
Their call wins — note the trace and apply it. The user authors; you
|
|
213
|
+
transcribe.
|
|
214
|
+
2. **Their point indicts the skill itself** — a principle that seems wrong, a
|
|
215
|
+
flow that fights them, a missing capability: say so plainly ("that's
|
|
216
|
+
feedback on the skill, and it's worth filing") and run the Skill Feedback
|
|
217
|
+
flow at the bottom of this file to capture it, then continue the run.
|
|
218
|
+
3. **The pushback dissolves once the why lands** — most do. Explain once, then
|
|
219
|
+
defer to their decision. Never lecture twice on the same point.
|
|
220
|
+
|
|
221
|
+
The hard rules still hold their shape — the cap, approval before disk, the
|
|
222
|
+
footer — but the path through them is persuasion and traced exceptions, not
|
|
223
|
+
refusal.
|
|
224
|
+
|
|
151
225
|
## References — the source mentalities
|
|
152
226
|
|
|
153
227
|
The full syntheses this skill is built from live in `references/`. Read them on
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: estack-vscode-file-recovery
|
|
3
|
+
version: 1.2.0
|
|
4
|
+
description: >
|
|
5
|
+
(vscode-file-recovery) Recover files that were permanently deleted (via rm, bash delete, or any method that bypasses the Recycle Bin) using VS Code's or Cursor's Local History snapshots, or from Claude session transcripts.
|
|
6
|
+
Use this skill immediately whenever: a file was deleted and git can't recover it (untracked or not committed), the user says "get it back", "restore that file", "I lost that file", "can you undo that delete", or any variation of wanting a deleted file recovered. Also use proactively after any rm or bash delete of files that weren't committed to git.
|
|
7
|
+
VS Code and Cursor silently save a snapshot every time you open or edit a file in the editor — this is often the only recovery path when git and Recycle Bin both fail.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# VS Code / Cursor File Recovery
|
|
11
|
+
|
|
12
|
+
When a file is deleted outside of git (with `rm`, bash, or any method that bypasses the Recycle Bin), this skill recovers it from editor Local History or Claude session transcripts.
|
|
13
|
+
|
|
14
|
+
## Recovery Sources — Try in Order
|
|
15
|
+
|
|
16
|
+
1. **Editor Local History** (VS Code or Cursor) — covered below
|
|
17
|
+
2. **Claude session transcript** — if Claude read the file in a prior session, its content may be in the JSONL. Use `/read-transcript` to search session history.
|
|
18
|
+
3. **Git** — only if the file was ever committed
|
|
19
|
+
4. **Cloud sync** (OneDrive, Dropbox) — check the cloud recycle bin / version history
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## How Editor Local History Works
|
|
24
|
+
|
|
25
|
+
VS Code and Cursor automatically save timestamped snapshots of every file opened in the editor. These live at:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
VS Code (Windows): C:\Users\[username]\AppData\Roaming\Code\User\History\
|
|
29
|
+
Cursor (Windows): C:\Users\[username]\AppData\Roaming\Cursor\User\History\
|
|
30
|
+
VS Code (Mac): ~/Library/Application Support/Code/User/History/
|
|
31
|
+
Cursor (Mac): ~/Library/Application Support/Cursor/User/History/
|
|
32
|
+
VS Code (Linux): ~/.config/Code/User/History/
|
|
33
|
+
Cursor (Linux): ~/.config/Cursor/User/History/
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Each file gets a hash-named folder containing:
|
|
37
|
+
- `entries.json` — maps the original file path to snapshot IDs and timestamps
|
|
38
|
+
- `[id].[ext]` — the actual snapshot content (e.g., `dtgz.md`, `F9gm.txt`)
|
|
39
|
+
|
|
40
|
+
**Critical limitation:** VS Code only snapshots files that were actually *opened as a tab in the editor*. Files visible only in the sidebar Explorer are not captured.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Recovery Steps
|
|
45
|
+
|
|
46
|
+
### Step 1: Identify what to search for
|
|
47
|
+
|
|
48
|
+
Collect from the user (or from the deletion event):
|
|
49
|
+
- The filename (e.g., `Untitled-1.md`)
|
|
50
|
+
- The full path if known (e.g., `C:\Users\2supe\All Coding\akiflow-mcp\Untitled-1.md`)
|
|
51
|
+
- Any partial path segments (folder name, project name)
|
|
52
|
+
|
|
53
|
+
### Step 2: Search editor history for the file
|
|
54
|
+
|
|
55
|
+
Search `entries.json` files in both VS Code and Cursor History directories.
|
|
56
|
+
|
|
57
|
+
**Windows (PowerShell) — searches both editors:**
|
|
58
|
+
```powershell
|
|
59
|
+
@("Code", "Cursor") | ForEach-Object {
|
|
60
|
+
$histPath = "$env:APPDATA\$_\User\History"
|
|
61
|
+
if (Test-Path $histPath) {
|
|
62
|
+
Get-ChildItem $histPath -Recurse |
|
|
63
|
+
Where-Object { $_.Name -eq "entries.json" } |
|
|
64
|
+
ForEach-Object {
|
|
65
|
+
$content = Get-Content $_.FullName -Raw -ErrorAction SilentlyContinue
|
|
66
|
+
if ($content -like "*FILENAME_OR_PATH_PATTERN*") {
|
|
67
|
+
$_.FullName
|
|
68
|
+
$content
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Replace `FILENAME_OR_PATH_PATTERN` with the filename or path fragment. **Use `-like "*filename*"` rather than `-match "filename"` to avoid regex metacharacter issues** (`.`, `(`, `)`, `+` in filenames break `-match`).
|
|
76
|
+
|
|
77
|
+
If matching a full path, note that editors URL-encode it in `entries.json`: drive colons become `%3A`, backslashes become `/`, and spaces become `%20`. Example: `C:\Users\2supe\My App (v2).md` → `file:///c%3A/Users/2supe/My%20App%20%28v2%29.md`. **Searching by filename alone is simpler and usually sufficient.**
|
|
78
|
+
|
|
79
|
+
**Mac (bash) — searches both editors:**
|
|
80
|
+
```bash
|
|
81
|
+
for app in "Code" "Cursor"; do
|
|
82
|
+
grep -rl "FILENAME_OR_PATH_PATTERN" "$HOME/Library/Application Support/$app/User/History/" 2>/dev/null
|
|
83
|
+
done
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Step 3: Read the entries.json to find the latest snapshot
|
|
87
|
+
|
|
88
|
+
The `entries.json` looks like:
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"version": 1,
|
|
92
|
+
"resource": "file:///c%3A/Users/2supe/path/to/Untitled-1.md",
|
|
93
|
+
"entries": [
|
|
94
|
+
{"id": "F9gm.md", "source": "Workspace Edit", "timestamp": 1776196985353},
|
|
95
|
+
{"id": "U4ha.md", "source": "Workspace Edit", "timestamp": 1776197058059},
|
|
96
|
+
{"id": "dtgz.md", "source": "Workspace Edit", "timestamp": 1776197128275}
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The **last entry** in the array is the most recent snapshot. Take its `id` field.
|
|
102
|
+
|
|
103
|
+
### Step 4: Read the snapshot content
|
|
104
|
+
|
|
105
|
+
```powershell
|
|
106
|
+
Get-Content "C:\Users\[username]\AppData\Roaming\Code\User\History\[hash-folder]\[id]"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Or use the Read tool with the full path.
|
|
110
|
+
|
|
111
|
+
### Step 5: Restore the file
|
|
112
|
+
|
|
113
|
+
Write the content back to the original location using the Write tool.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## When Editor History Won't Help
|
|
118
|
+
|
|
119
|
+
- **File was never opened as an editor tab** — files only visible in the sidebar Explorer are not snapshotted.
|
|
120
|
+
- **History was cleared** — default retention is 30 days / 50 entries per file.
|
|
121
|
+
|
|
122
|
+
If editor history doesn't have the file, fall back to:
|
|
123
|
+
1. **`/read-transcript`** — if Claude read the file in a prior session, the content is in the session JSONL. Use `--mode search --query "filename"` to find it. Note: you need to point it at the right project's sessions — if the file lived in a different project folder, search that project's transcript directory instead.
|
|
124
|
+
2. **Windows Shadow Copies** (last resort, requires admin) — Windows VSS may have a snapshot of the volume. Check if any exist first:
|
|
125
|
+
```powershell
|
|
126
|
+
vssadmin list shadows
|
|
127
|
+
```
|
|
128
|
+
If a shadow copy exists, mount it and browse (**requires an elevated/admin shell**; the trailing backslash on the device path is required or `mklink` fails silently):
|
|
129
|
+
```powershell
|
|
130
|
+
cmd /c mklink /d C:\shadow \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy3\
|
|
131
|
+
```
|
|
132
|
+
Replace the device path with the one from `vssadmin list shadows`. Browse `C:\shadow\` like a normal drive to find and copy the file back. Clean up after: `cmd /c rmdir C:\shadow`.
|
|
133
|
+
3. **File recovery software** (Recuva on Windows) — only works if the disk blocks haven't been overwritten yet.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Example
|
|
138
|
+
|
|
139
|
+
**Scenario:** `rm` deleted `Untitled-1.md` which was untracked by git.
|
|
140
|
+
|
|
141
|
+
```powershell
|
|
142
|
+
# Search
|
|
143
|
+
Get-ChildItem "$env:APPDATA\Code\User\History" -Recurse |
|
|
144
|
+
Where-Object { $_.Name -eq "entries.json" } |
|
|
145
|
+
ForEach-Object {
|
|
146
|
+
$content = Get-Content $_.FullName -Raw -ErrorAction SilentlyContinue
|
|
147
|
+
if ($content -like "*Untitled-1*") { $_.FullName; $content }
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
# Result shows: C:\...\History\-6e228c75\entries.json
|
|
151
|
+
# entries.json has latest id: "dtgz.md"
|
|
152
|
+
|
|
153
|
+
# Read snapshot
|
|
154
|
+
Get-Content "C:\Users\2supe\AppData\Roaming\Code\User\History\-6e228c75\dtgz.md"
|
|
155
|
+
|
|
156
|
+
# Restore
|
|
157
|
+
# (Use Write tool to recreate the file at original path)
|
|
158
|
+
```
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Skill Feedback
|
|
162
|
+
|
|
163
|
+
If the user shares feedback about this skill — a bug, something confusing, a missing feature, or a suggestion — ask them to describe it in a bit more detail (what they expected, what happened, and any relevant context). Then file the issue using whichever method is available:
|
|
164
|
+
|
|
165
|
+
**If `gh` is installed** (`gh --version` succeeds), create the issue directly:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
gh issue create \
|
|
169
|
+
--repo ElliotDrel/e-stack \
|
|
170
|
+
--title "estack-vscode-file-recovery: <concise summary>" \
|
|
171
|
+
--body "<description from user feedback — expected vs. actual behavior and context>"
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**If `gh` is not installed**, build a pre-filled URL:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
python3 -c "
|
|
178
|
+
import urllib.parse
|
|
179
|
+
title = 'estack-vscode-file-recovery: <concise summary>'
|
|
180
|
+
body = '<description from user feedback — expected vs. actual behavior and context>'
|
|
181
|
+
base = 'https://github.com/ElliotDrel/e-stack/issues/new'
|
|
182
|
+
print(base + '?title=' + urllib.parse.quote(title) + '&body=' + urllib.parse.quote(body))
|
|
183
|
+
"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Share the printed URL with the user and offer to open it in their browser.
|
|
187
|
+
|
|
188
|
+
They can also click it directly, review the pre-filled title and body, and click **Submit new issue**.
|