ai-session-checkpoint 1.0.0
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/LICENSE +21 -0
- package/README.md +143 -0
- package/bin/init.js +315 -0
- package/editors/claude-code/SKILL.md +52 -0
- package/editors/claude-code/example-CLAUDE.md +3 -0
- package/editors/cursor/example-cursorrules +5 -0
- package/install.sh +300 -0
- package/package.json +33 -0
- package/scripts/link-vault.sh +29 -0
- package/templates/decisions.md +8 -0
- package/templates/problems.md +9 -0
- package/templates/project-state.md +19 -0
- package/templates/sessions/.gitkeep +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 gokks8142
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# ai-session-checkpoint
|
|
2
|
+
|
|
3
|
+
**Never lose AI coding session context again.**
|
|
4
|
+
|
|
5
|
+
When your Claude Code context fills up or your Cursor tab crashes, all the context vanishes. `ai-session-checkpoint` silently saves session state to a folder — so your next session picks up exactly where you left off. Put that folder in Google Drive or iCloud and it syncs across machines automatically.
|
|
6
|
+
|
|
7
|
+
## Quick Start (30 seconds)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
cd ~/my-project
|
|
11
|
+
|
|
12
|
+
# Option 1: Shell script (zero dependencies)
|
|
13
|
+
curl -fsSL https://raw.githubusercontent.com/gokks8142/ai-session-checkpoint/main/install.sh | bash
|
|
14
|
+
|
|
15
|
+
# Option 2: npx (Node.js users)
|
|
16
|
+
npx ai-session-checkpoint init
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
That's it. Open your AI editor, start coding. Checkpoints happen automatically.
|
|
20
|
+
|
|
21
|
+
## What It Does
|
|
22
|
+
|
|
23
|
+
| Feature | How |
|
|
24
|
+
|---------|-----|
|
|
25
|
+
| **Auto-checkpoint** | Background agent saves every 20 min (Claude Code) |
|
|
26
|
+
| **Manual checkpoint** | Say "checkpoint" in any AI editor |
|
|
27
|
+
| **Session recovery** | New sessions read `.checkpoints/` on start — full context |
|
|
28
|
+
| **Cross-editor** | Same `.checkpoints/` folder works in Claude Code + Cursor |
|
|
29
|
+
| **Cross-machine** | Put checkpoint folder in Google Drive / iCloud — syncs automatically |
|
|
30
|
+
| **Change detection** | Skips if no files changed — no noise from read-only work |
|
|
31
|
+
| **Smart retention** | Keeps recent detail, compresses old history, max 50 files |
|
|
32
|
+
|
|
33
|
+
## How It Works
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
my-project/
|
|
37
|
+
├── .checkpoints/ ← symlink to checkpoint storage
|
|
38
|
+
│ ├── project-state.md ← current project state (always up-to-date)
|
|
39
|
+
│ ├── sessions/
|
|
40
|
+
│ │ ├── 2026-03-21-10-30.md ← auto-checkpoint
|
|
41
|
+
│ │ └── 2026-03-21-11-15.md ← manual checkpoint
|
|
42
|
+
│ ├── decisions.md ← architecture decisions log
|
|
43
|
+
│ └── problems.md ← open issues / blockers
|
|
44
|
+
├── CLAUDE.md ← tells Claude to read/write .checkpoints/
|
|
45
|
+
└── ... (your code)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
1. **On session start**: AI reads `project-state.md` + latest session file → full context
|
|
49
|
+
2. **Every 20 min**: Background agent checks `git diff`, writes session snapshot if changes detected
|
|
50
|
+
3. **On "checkpoint"**: Immediate save with summary confirmation
|
|
51
|
+
4. **New session**: Reads checkpoints, picks up where you left off
|
|
52
|
+
|
|
53
|
+
## Storage Options
|
|
54
|
+
|
|
55
|
+
### Local folder (default)
|
|
56
|
+
|
|
57
|
+
Checkpoints go to `~/.ai-checkpoints/my-project/`. Works immediately, zero setup.
|
|
58
|
+
|
|
59
|
+
### Cloud sync (Google Drive / iCloud)
|
|
60
|
+
|
|
61
|
+
To sync checkpoints across machines, put the folder in Google Drive or iCloud:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# 1. Create a folder in Google Drive (one time)
|
|
65
|
+
mkdir -p ~/Google\ Drive/My\ Drive/ClaudeCode/
|
|
66
|
+
|
|
67
|
+
# 2. Run install.sh from your project and enter the path when prompted
|
|
68
|
+
cd ~/my-project
|
|
69
|
+
curl -fsSL https://raw.githubusercontent.com/gokks8142/ai-session-checkpoint/main/install.sh | bash
|
|
70
|
+
|
|
71
|
+
# When asked "Where should checkpoints be stored?", enter:
|
|
72
|
+
# ~/Google Drive/My Drive/ClaudeCode/
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
That's it. Checkpoints sync automatically via Google Drive. On your other machine, create the same symlink and you have full context.
|
|
76
|
+
|
|
77
|
+
### Obsidian (optional bonus)
|
|
78
|
+
|
|
79
|
+
If you already use [Obsidian](https://obsidian.md), you can point your vault at the same Google Drive folder. This gives you search, graph view, and backlinks across your checkpoints — but it's purely optional. The tool works identically with or without Obsidian.
|
|
80
|
+
|
|
81
|
+
## Link a Project
|
|
82
|
+
|
|
83
|
+
The installer handles this automatically. If you need to do it manually:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Symlink your project to the checkpoint folder
|
|
87
|
+
ln -s ~/Google\ Drive/My\ Drive/ClaudeCode/my-project ~/my-project/.checkpoints
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
To verify:
|
|
91
|
+
```bash
|
|
92
|
+
ls -la .checkpoints/
|
|
93
|
+
# Should show: project-state.md, sessions/, decisions.md, problems.md
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Supported Editors
|
|
97
|
+
|
|
98
|
+
| Editor | Auto-checkpoint | Manual checkpoint | Config file |
|
|
99
|
+
|--------|:-:|:-:|---|
|
|
100
|
+
| Claude Code | ✅ | ✅ | `CLAUDE.md` |
|
|
101
|
+
| Cursor | — | ✅ | `.cursorrules` |
|
|
102
|
+
|
|
103
|
+
The checkpoint format is editor-agnostic — any AI editor that reads files can use it.
|
|
104
|
+
|
|
105
|
+
## What Gets Saved
|
|
106
|
+
|
|
107
|
+
**Session file** (`sessions/YYYY-MM-DD-HH-MM.md`):
|
|
108
|
+
- Summary of what was accomplished
|
|
109
|
+
- Files changed and why
|
|
110
|
+
- Decisions made
|
|
111
|
+
- Open items and next steps
|
|
112
|
+
|
|
113
|
+
**Project state** (`project-state.md`):
|
|
114
|
+
- What the project is and tech stack
|
|
115
|
+
- What's built and working
|
|
116
|
+
- What's in progress
|
|
117
|
+
- Key files and their purposes
|
|
118
|
+
- Known issues
|
|
119
|
+
|
|
120
|
+
## Smart Retention
|
|
121
|
+
|
|
122
|
+
Checkpoints don't pile up forever:
|
|
123
|
+
|
|
124
|
+
| Time window | Rule |
|
|
125
|
+
|-------------|------|
|
|
126
|
+
| Last 24 hours | Keep all |
|
|
127
|
+
| Last 7 days | Keep 1 per day |
|
|
128
|
+
| Last 30 days | Keep 1 per week |
|
|
129
|
+
| Older | Delete |
|
|
130
|
+
|
|
131
|
+
Hard cap: **50 files max** (configurable). Oldest deleted on rollover.
|
|
132
|
+
|
|
133
|
+
## Uninstall
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
rm .checkpoints # Remove symlink
|
|
137
|
+
# Remove checkpoint lines from CLAUDE.md or .cursorrules
|
|
138
|
+
# Optionally delete ~/.ai-checkpoints/my-project/
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
MIT
|
package/bin/init.js
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ai-session-checkpoint CLI
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* npx ai-session-checkpoint init # Set up checkpoints for current project
|
|
8
|
+
* npx ai-session-checkpoint migrate --to obsidian # Migrate local → Obsidian
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const fs = require("fs");
|
|
12
|
+
const path = require("path");
|
|
13
|
+
const { execSync } = require("child_process");
|
|
14
|
+
const readline = require("readline");
|
|
15
|
+
|
|
16
|
+
const VERSION = "1.0.0";
|
|
17
|
+
|
|
18
|
+
// --- Helpers ---
|
|
19
|
+
function ask(question, defaultAnswer) {
|
|
20
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
const prompt = defaultAnswer ? `${question} (${defaultAnswer}): ` : `${question}: `;
|
|
23
|
+
rl.question(prompt, (answer) => {
|
|
24
|
+
rl.close();
|
|
25
|
+
resolve(answer.trim() || defaultAnswer || "");
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function green(t) { return `\x1b[32m${t}\x1b[0m`; }
|
|
31
|
+
function blue(t) { return `\x1b[34m${t}\x1b[0m`; }
|
|
32
|
+
function cyan(t) { return `\x1b[36m${t}\x1b[0m`; }
|
|
33
|
+
function bold(t) { return `\x1b[1m${t}\x1b[0m`; }
|
|
34
|
+
function dim(t) { return `\x1b[2m${t}\x1b[0m`; }
|
|
35
|
+
|
|
36
|
+
function writeIfMissing(filePath, content, label) {
|
|
37
|
+
if (!fs.existsSync(filePath)) {
|
|
38
|
+
fs.writeFileSync(filePath, content, "utf8");
|
|
39
|
+
console.log(` ${green("✓")} Created: ${dim(label)}`);
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// No Obsidian-specific detection — user provides custom path if needed
|
|
46
|
+
|
|
47
|
+
// --- Templates ---
|
|
48
|
+
const TEMPLATES = {
|
|
49
|
+
"project-state.md": `# Project State
|
|
50
|
+
|
|
51
|
+
## What is this project?
|
|
52
|
+
<!-- Brief description -->
|
|
53
|
+
|
|
54
|
+
## Tech Stack
|
|
55
|
+
<!-- Languages, frameworks, tools -->
|
|
56
|
+
|
|
57
|
+
## What's Built
|
|
58
|
+
<!-- Completed features and components -->
|
|
59
|
+
|
|
60
|
+
## In Progress
|
|
61
|
+
<!-- Current work items -->
|
|
62
|
+
|
|
63
|
+
## Key Files
|
|
64
|
+
<!-- Important files and their purposes -->
|
|
65
|
+
|
|
66
|
+
## Known Issues
|
|
67
|
+
<!-- Bugs, blockers, open questions -->
|
|
68
|
+
`,
|
|
69
|
+
"decisions.md": `# Architecture Decisions
|
|
70
|
+
|
|
71
|
+
<!-- Format:
|
|
72
|
+
## YYYY-MM-DD: Decision Title
|
|
73
|
+
**Context:** Why this decision was needed
|
|
74
|
+
**Decision:** What was decided
|
|
75
|
+
**Alternatives:** What else was considered
|
|
76
|
+
-->
|
|
77
|
+
`,
|
|
78
|
+
"problems.md": `# Open Problems
|
|
79
|
+
|
|
80
|
+
<!-- Format:
|
|
81
|
+
## Problem Title
|
|
82
|
+
**Status:** open | investigating | blocked | resolved
|
|
83
|
+
**Description:** What's happening
|
|
84
|
+
**Impact:** Why it matters
|
|
85
|
+
**Notes:** Investigation progress
|
|
86
|
+
-->
|
|
87
|
+
`,
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const CHECKPOINT_INSTRUCTIONS = `At session start, read \`.checkpoints/project-state.md\` and the latest file in \`.checkpoints/sessions/\` to pick up context from previous sessions.
|
|
91
|
+
|
|
92
|
+
When the user says "checkpoint" or when you complete a feature/fix, write a session summary to \`.checkpoints/sessions/\` (filename: \`YYYY-MM-DD-HH-MM.md\`) and update \`.checkpoints/project-state.md\`.`;
|
|
93
|
+
|
|
94
|
+
const SKILL_CONTENT = `---
|
|
95
|
+
name: ai-session-checkpoint
|
|
96
|
+
description: Automatically save session context, decisions, and progress so no work is lost when sessions crash or context windows fill up.
|
|
97
|
+
triggers:
|
|
98
|
+
- "checkpoint"
|
|
99
|
+
- "save progress"
|
|
100
|
+
- "save context"
|
|
101
|
+
- "save session"
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
# ai-session-checkpoint
|
|
105
|
+
|
|
106
|
+
## On Session Start
|
|
107
|
+
|
|
108
|
+
Read \`.checkpoints/project-state.md\` and the latest file in \`.checkpoints/sessions/\` to pick up context from previous sessions. Briefly summarize what you found so the user knows you have context.
|
|
109
|
+
|
|
110
|
+
## On "checkpoint" / "save progress" / "save context"
|
|
111
|
+
|
|
112
|
+
1. **Check for changes**: Run \`git diff --stat\` to see if any files changed. If no changes and no significant decisions were made, tell the user "No changes to checkpoint" and skip.
|
|
113
|
+
|
|
114
|
+
2. **Write session file**: Create \`.checkpoints/sessions/YYYY-MM-DD-HH-MM.md\` with:
|
|
115
|
+
\`\`\`
|
|
116
|
+
# Session: YYYY-MM-DD HH:MM
|
|
117
|
+
|
|
118
|
+
## Summary
|
|
119
|
+
- What was accomplished this session (2-5 bullet points)
|
|
120
|
+
|
|
121
|
+
## Files Changed
|
|
122
|
+
- path/to/file.ts — what changed and why
|
|
123
|
+
|
|
124
|
+
## Decisions Made
|
|
125
|
+
- Key decisions with brief rationale
|
|
126
|
+
|
|
127
|
+
## Open Items
|
|
128
|
+
- What's left to do, blockers, next steps
|
|
129
|
+
\`\`\`
|
|
130
|
+
|
|
131
|
+
3. **Update project state**: Rewrite \`.checkpoints/project-state.md\` with current reality:
|
|
132
|
+
- What the project is
|
|
133
|
+
- Tech stack
|
|
134
|
+
- What's built and working
|
|
135
|
+
- What's in progress
|
|
136
|
+
- Key files and their purposes
|
|
137
|
+
- Known issues
|
|
138
|
+
|
|
139
|
+
4. **Retention sweep**: Count files in \`.checkpoints/sessions/\`. If more than 50, delete the oldest file(s) to stay at 50.
|
|
140
|
+
|
|
141
|
+
5. **Confirm**: Tell the user what was saved with a brief summary.
|
|
142
|
+
|
|
143
|
+
## On Feature/Fix Completion
|
|
144
|
+
|
|
145
|
+
When you complete a significant feature or fix, proactively offer: "Want me to checkpoint this progress?"
|
|
146
|
+
`;
|
|
147
|
+
|
|
148
|
+
// --- Commands ---
|
|
149
|
+
async function init() {
|
|
150
|
+
const projectDir = process.cwd();
|
|
151
|
+
const projectName = path.basename(projectDir);
|
|
152
|
+
const homedir = require("os").homedir();
|
|
153
|
+
const defaultCheckpointDir = path.join(homedir, ".ai-checkpoints");
|
|
154
|
+
|
|
155
|
+
console.log("");
|
|
156
|
+
console.log(`${blue(bold("ai-session-checkpoint"))} ${dim(`v${VERSION}`)}`);
|
|
157
|
+
console.log("");
|
|
158
|
+
|
|
159
|
+
// Step 1: Storage
|
|
160
|
+
let checkpointBase;
|
|
161
|
+
console.log(cyan("? Where should checkpoints be stored?"));
|
|
162
|
+
console.log(` ${bold("1)")} Local folder ${dim(`(${defaultCheckpointDir}/)`)}`);
|
|
163
|
+
console.log(` ${bold("2)")} Custom path ${dim("(Google Drive, iCloud, Dropbox, etc.)")}`);
|
|
164
|
+
const choice = await ask(" Choose [1/2]", "1");
|
|
165
|
+
if (choice === "2") {
|
|
166
|
+
const customPath = await ask(" Enter path", "");
|
|
167
|
+
if (customPath) {
|
|
168
|
+
const resolved = customPath.replace(/^~/, homedir);
|
|
169
|
+
fs.mkdirSync(resolved, { recursive: true });
|
|
170
|
+
checkpointBase = resolved;
|
|
171
|
+
} else {
|
|
172
|
+
checkpointBase = defaultCheckpointDir;
|
|
173
|
+
}
|
|
174
|
+
} else {
|
|
175
|
+
checkpointBase = defaultCheckpointDir;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Step 2: Project name
|
|
179
|
+
const name = await ask(cyan("? Project name?"), projectName);
|
|
180
|
+
const checkpointDir = path.join(checkpointBase, name);
|
|
181
|
+
|
|
182
|
+
// Step 3: Detect editor
|
|
183
|
+
let editorType = "claude-code";
|
|
184
|
+
if (fs.existsSync(path.join(projectDir, ".cursorrules")) && !fs.existsSync(path.join(projectDir, "CLAUDE.md"))) {
|
|
185
|
+
editorType = "cursor";
|
|
186
|
+
}
|
|
187
|
+
console.log(`${dim(" Editor detected: " + editorType)}`);
|
|
188
|
+
console.log("");
|
|
189
|
+
|
|
190
|
+
// Step 4: Create checkpoint folder + templates
|
|
191
|
+
fs.mkdirSync(path.join(checkpointDir, "sessions"), { recursive: true });
|
|
192
|
+
|
|
193
|
+
for (const [filename, content] of Object.entries(TEMPLATES)) {
|
|
194
|
+
writeIfMissing(path.join(checkpointDir, filename), content, filename);
|
|
195
|
+
}
|
|
196
|
+
console.log(` ${green("✓")} Templates: ${dim("project-state.md, decisions.md, problems.md, sessions/")}`);
|
|
197
|
+
|
|
198
|
+
// Step 5: Symlink
|
|
199
|
+
const symlinkPath = path.join(projectDir, ".checkpoints");
|
|
200
|
+
if (fs.existsSync(symlinkPath)) {
|
|
201
|
+
const stat = fs.lstatSync(symlinkPath);
|
|
202
|
+
if (stat.isSymbolicLink()) fs.unlinkSync(symlinkPath);
|
|
203
|
+
}
|
|
204
|
+
if (!fs.existsSync(symlinkPath)) {
|
|
205
|
+
fs.symlinkSync(checkpointDir, symlinkPath);
|
|
206
|
+
console.log(` ${green("✓")} Symlink: ${dim(`.checkpoints → ${checkpointDir}`)}`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Step 6: Editor config
|
|
210
|
+
if (editorType === "claude-code" || editorType === "both") {
|
|
211
|
+
const claudeMd = path.join(projectDir, "CLAUDE.md");
|
|
212
|
+
if (fs.existsSync(claudeMd)) {
|
|
213
|
+
const existing = fs.readFileSync(claudeMd, "utf8");
|
|
214
|
+
if (!existing.includes(".checkpoints/project-state.md")) {
|
|
215
|
+
fs.appendFileSync(claudeMd, "\n" + CHECKPOINT_INSTRUCTIONS + "\n");
|
|
216
|
+
console.log(` ${green("✓")} CLAUDE.md: ${dim("Added checkpoint instructions")}`);
|
|
217
|
+
}
|
|
218
|
+
} else {
|
|
219
|
+
fs.writeFileSync(claudeMd, CHECKPOINT_INSTRUCTIONS + "\n");
|
|
220
|
+
console.log(` ${green("✓")} CLAUDE.md: ${dim("Created with checkpoint instructions")}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (editorType === "cursor" || editorType === "both") {
|
|
225
|
+
const cursorrules = path.join(projectDir, ".cursorrules");
|
|
226
|
+
if (fs.existsSync(cursorrules)) {
|
|
227
|
+
const existing = fs.readFileSync(cursorrules, "utf8");
|
|
228
|
+
if (!existing.includes(".checkpoints/project-state.md")) {
|
|
229
|
+
fs.appendFileSync(cursorrules, "\n" + CHECKPOINT_INSTRUCTIONS + "\n");
|
|
230
|
+
console.log(` ${green("✓")} .cursorrules: ${dim("Added checkpoint instructions")}`);
|
|
231
|
+
}
|
|
232
|
+
} else {
|
|
233
|
+
fs.writeFileSync(cursorrules, CHECKPOINT_INSTRUCTIONS + "\n");
|
|
234
|
+
console.log(` ${green("✓")} .cursorrules: ${dim("Created with checkpoint instructions")}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Step 7: Install skill
|
|
239
|
+
if (editorType === "claude-code" || editorType === "both") {
|
|
240
|
+
const skillDir = path.join(homedir, ".claude", "skills", "ai-session-checkpoint");
|
|
241
|
+
fs.mkdirSync(skillDir, { recursive: true });
|
|
242
|
+
fs.writeFileSync(path.join(skillDir, "SKILL.md"), SKILL_CONTENT);
|
|
243
|
+
console.log(` ${green("✓")} Skill: ${dim("~/.claude/skills/ai-session-checkpoint/")}`);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Step 8: .gitignore
|
|
247
|
+
const gitignorePath = path.join(projectDir, ".gitignore");
|
|
248
|
+
if (fs.existsSync(gitignorePath)) {
|
|
249
|
+
const existing = fs.readFileSync(gitignorePath, "utf8");
|
|
250
|
+
if (!existing.includes(".checkpoints")) {
|
|
251
|
+
fs.appendFileSync(gitignorePath, "\n# ai-session-checkpoint\n.checkpoints\n");
|
|
252
|
+
console.log(` ${green("✓")} .gitignore: ${dim("Added .checkpoints")}`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
console.log("");
|
|
257
|
+
console.log(`${green(bold("Done!"))} Checkpoints stored in: ${dim(checkpointDir)}`);
|
|
258
|
+
console.log("");
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
async function migrate() {
|
|
262
|
+
const args = process.argv.slice(3);
|
|
263
|
+
if (args[0] !== "--to" || !args[1]) {
|
|
264
|
+
console.log("Usage: ai-session-checkpoint migrate --to <path>");
|
|
265
|
+
console.log("Example: ai-session-checkpoint migrate --to ~/Google\\ Drive/My\\ Drive/ClaudeCode");
|
|
266
|
+
process.exit(1);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const projectDir = process.cwd();
|
|
270
|
+
const symlinkPath = path.join(projectDir, ".checkpoints");
|
|
271
|
+
const homedir = require("os").homedir();
|
|
272
|
+
|
|
273
|
+
if (!fs.existsSync(symlinkPath)) {
|
|
274
|
+
console.log("No .checkpoints found in current directory. Run 'init' first.");
|
|
275
|
+
process.exit(1);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const currentTarget = fs.readlinkSync(symlinkPath);
|
|
279
|
+
const newBase = args[1].replace(/^~/, homedir);
|
|
280
|
+
const projectName = path.basename(projectDir);
|
|
281
|
+
const newTarget = path.join(newBase, projectName);
|
|
282
|
+
|
|
283
|
+
if (currentTarget === newTarget) {
|
|
284
|
+
console.log("Already using that path. Nothing to migrate.");
|
|
285
|
+
process.exit(0);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Copy files
|
|
289
|
+
fs.mkdirSync(newTarget, { recursive: true });
|
|
290
|
+
execSync(`cp -r "${currentTarget}/"* "${newTarget}/"`, { stdio: "inherit" });
|
|
291
|
+
|
|
292
|
+
// Update symlink
|
|
293
|
+
fs.unlinkSync(symlinkPath);
|
|
294
|
+
fs.symlinkSync(newTarget, symlinkPath);
|
|
295
|
+
|
|
296
|
+
console.log(`${green("✓")} Migrated: ${dim(currentTarget)} → ${dim(newTarget)}`);
|
|
297
|
+
console.log(`${green("✓")} Symlink updated`);
|
|
298
|
+
console.log(`${green("✓")} All session history preserved`);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// --- Main ---
|
|
302
|
+
const command = process.argv[2] || "init";
|
|
303
|
+
|
|
304
|
+
switch (command) {
|
|
305
|
+
case "init":
|
|
306
|
+
init().catch(console.error);
|
|
307
|
+
break;
|
|
308
|
+
case "migrate":
|
|
309
|
+
migrate().catch(console.error);
|
|
310
|
+
break;
|
|
311
|
+
default:
|
|
312
|
+
console.log(`Unknown command: ${command}`);
|
|
313
|
+
console.log("Usage: ai-session-checkpoint [init|migrate]");
|
|
314
|
+
process.exit(1);
|
|
315
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ai-session-checkpoint
|
|
3
|
+
description: Automatically save session context, decisions, and progress so no work is lost when sessions crash or context windows fill up.
|
|
4
|
+
triggers:
|
|
5
|
+
- "checkpoint"
|
|
6
|
+
- "save progress"
|
|
7
|
+
- "save context"
|
|
8
|
+
- "save session"
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ai-session-checkpoint
|
|
12
|
+
|
|
13
|
+
## On Session Start
|
|
14
|
+
|
|
15
|
+
Read `.checkpoints/project-state.md` and the latest file in `.checkpoints/sessions/` to pick up context from previous sessions. Briefly summarize what you found so the user knows you have context.
|
|
16
|
+
|
|
17
|
+
## On "checkpoint" / "save progress" / "save context"
|
|
18
|
+
|
|
19
|
+
1. **Check for changes**: Run `git diff --stat` to see if any files changed. If no changes and no significant decisions were made, tell the user "No changes to checkpoint" and skip.
|
|
20
|
+
|
|
21
|
+
2. **Write session file**: Create `.checkpoints/sessions/YYYY-MM-DD-HH-MM.md` with:
|
|
22
|
+
```
|
|
23
|
+
# Session: YYYY-MM-DD HH:MM
|
|
24
|
+
|
|
25
|
+
## Summary
|
|
26
|
+
- What was accomplished this session (2-5 bullet points)
|
|
27
|
+
|
|
28
|
+
## Files Changed
|
|
29
|
+
- path/to/file.ts — what changed and why
|
|
30
|
+
|
|
31
|
+
## Decisions Made
|
|
32
|
+
- Key decisions with brief rationale
|
|
33
|
+
|
|
34
|
+
## Open Items
|
|
35
|
+
- What's left to do, blockers, next steps
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
3. **Update project state**: Rewrite `.checkpoints/project-state.md` with current reality:
|
|
39
|
+
- What the project is
|
|
40
|
+
- Tech stack
|
|
41
|
+
- What's built and working
|
|
42
|
+
- What's in progress
|
|
43
|
+
- Key files and their purposes
|
|
44
|
+
- Known issues
|
|
45
|
+
|
|
46
|
+
4. **Retention sweep**: Count files in `.checkpoints/sessions/`. If more than 50, delete the oldest file(s) to stay at 50.
|
|
47
|
+
|
|
48
|
+
5. **Confirm**: Tell the user what was saved with a brief summary.
|
|
49
|
+
|
|
50
|
+
## On Feature/Fix Completion
|
|
51
|
+
|
|
52
|
+
When you complete a significant feature or fix, proactively offer: "Want me to checkpoint this progress?"
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
At session start, read `.checkpoints/project-state.md` and the latest file in `.checkpoints/sessions/` to pick up context from previous sessions.
|
|
2
|
+
|
|
3
|
+
When the user says "checkpoint" or when you complete a feature/fix, write a session summary to `.checkpoints/sessions/` (filename: `YYYY-MM-DD-HH-MM.md`) and update `.checkpoints/project-state.md`.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
At session start, read `.checkpoints/project-state.md` and the latest file in `.checkpoints/sessions/` to pick up context from previous sessions.
|
|
2
|
+
|
|
3
|
+
When the user says "checkpoint" or when you complete a feature/fix, write a session summary to `.checkpoints/sessions/` (filename: `YYYY-MM-DD-HH-MM.md`) and update `.checkpoints/project-state.md`.
|
|
4
|
+
|
|
5
|
+
Before ending a long conversation, offer to checkpoint: "Want me to save this session's progress?"
|
package/install.sh
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# ai-session-checkpoint installer
|
|
4
|
+
# Zero dependencies — works on any Mac/Linux with bash
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# curl -fsSL https://raw.githubusercontent.com/gokks8142/ai-session-checkpoint/main/install.sh | bash
|
|
8
|
+
# OR
|
|
9
|
+
# ./install.sh
|
|
10
|
+
#
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
# --- Colors ---
|
|
14
|
+
RED='\033[0;31m'
|
|
15
|
+
GREEN='\033[0;32m'
|
|
16
|
+
BLUE='\033[0;34m'
|
|
17
|
+
CYAN='\033[0;36m'
|
|
18
|
+
BOLD='\033[1m'
|
|
19
|
+
DIM='\033[2m'
|
|
20
|
+
RESET='\033[0m'
|
|
21
|
+
|
|
22
|
+
# --- Config ---
|
|
23
|
+
VERSION="1.0.0"
|
|
24
|
+
DEFAULT_CHECKPOINT_DIR="$HOME/.ai-checkpoints"
|
|
25
|
+
SKILL_DIR="$HOME/.claude/skills/ai-session-checkpoint"
|
|
26
|
+
|
|
27
|
+
# --- Detect project ---
|
|
28
|
+
PROJECT_DIR="$(pwd)"
|
|
29
|
+
PROJECT_NAME="$(basename "$PROJECT_DIR")"
|
|
30
|
+
|
|
31
|
+
echo ""
|
|
32
|
+
echo -e "${BLUE}${BOLD}ai-session-checkpoint${RESET} ${DIM}v${VERSION}${RESET}"
|
|
33
|
+
echo ""
|
|
34
|
+
|
|
35
|
+
# --- Step 1: Storage location ---
|
|
36
|
+
echo -e "${CYAN}? Where should checkpoints be stored?${RESET}"
|
|
37
|
+
echo -e " ${BOLD}1)${RESET} Local folder (${DIM}${DEFAULT_CHECKPOINT_DIR}/${RESET})"
|
|
38
|
+
echo -e " ${BOLD}2)${RESET} Custom path ${DIM}(Google Drive, iCloud, Dropbox, etc.)${RESET}"
|
|
39
|
+
echo ""
|
|
40
|
+
read -p " Choose [1/2] (default: 1): " STORAGE_CHOICE
|
|
41
|
+
STORAGE_CHOICE="${STORAGE_CHOICE:-1}"
|
|
42
|
+
|
|
43
|
+
if [ "$STORAGE_CHOICE" = "2" ]; then
|
|
44
|
+
read -p " Enter path: " CUSTOM_PATH
|
|
45
|
+
if [ -z "$CUSTOM_PATH" ]; then
|
|
46
|
+
echo -e " ${RED}!${RESET} No path entered. Using local folder."
|
|
47
|
+
CHECKPOINT_BASE="$DEFAULT_CHECKPOINT_DIR"
|
|
48
|
+
else
|
|
49
|
+
# Expand ~ if present
|
|
50
|
+
CUSTOM_PATH="${CUSTOM_PATH/#\~/$HOME}"
|
|
51
|
+
mkdir -p "$CUSTOM_PATH"
|
|
52
|
+
CHECKPOINT_BASE="$CUSTOM_PATH"
|
|
53
|
+
fi
|
|
54
|
+
else
|
|
55
|
+
CHECKPOINT_BASE="$DEFAULT_CHECKPOINT_DIR"
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# --- Step 2: Project name ---
|
|
59
|
+
echo ""
|
|
60
|
+
echo -e "${CYAN}? Project name?${RESET} ${DIM}(${PROJECT_NAME})${RESET}"
|
|
61
|
+
read -p " Name: " INPUT_NAME
|
|
62
|
+
PROJECT_NAME="${INPUT_NAME:-$PROJECT_NAME}"
|
|
63
|
+
|
|
64
|
+
CHECKPOINT_DIR="$CHECKPOINT_BASE/$PROJECT_NAME"
|
|
65
|
+
|
|
66
|
+
# --- Step 3: Detect AI editor ---
|
|
67
|
+
EDITOR_TYPE="unknown"
|
|
68
|
+
if [ -f "$PROJECT_DIR/CLAUDE.md" ] || command -v claude &>/dev/null; then
|
|
69
|
+
EDITOR_TYPE="claude-code"
|
|
70
|
+
elif [ -f "$PROJECT_DIR/.cursorrules" ]; then
|
|
71
|
+
EDITOR_TYPE="cursor"
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
echo ""
|
|
75
|
+
if [ "$EDITOR_TYPE" = "claude-code" ]; then
|
|
76
|
+
echo -e "${CYAN}? AI editor detected: ${BOLD}Claude Code${RESET}"
|
|
77
|
+
elif [ "$EDITOR_TYPE" = "cursor" ]; then
|
|
78
|
+
echo -e "${CYAN}? AI editor detected: ${BOLD}Cursor${RESET}"
|
|
79
|
+
else
|
|
80
|
+
echo -e "${CYAN}? AI editor:${RESET}"
|
|
81
|
+
echo -e " ${BOLD}1)${RESET} Claude Code"
|
|
82
|
+
echo -e " ${BOLD}2)${RESET} Cursor"
|
|
83
|
+
echo -e " ${BOLD}3)${RESET} Both"
|
|
84
|
+
read -p " Choose [1/2/3] (default: 1): " EDITOR_CHOICE
|
|
85
|
+
case "${EDITOR_CHOICE:-1}" in
|
|
86
|
+
2) EDITOR_TYPE="cursor" ;;
|
|
87
|
+
3) EDITOR_TYPE="both" ;;
|
|
88
|
+
*) EDITOR_TYPE="claude-code" ;;
|
|
89
|
+
esac
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
echo ""
|
|
93
|
+
|
|
94
|
+
# --- Step 4: Create checkpoint folder + templates ---
|
|
95
|
+
mkdir -p "$CHECKPOINT_DIR/sessions"
|
|
96
|
+
|
|
97
|
+
# project-state.md
|
|
98
|
+
if [ ! -f "$CHECKPOINT_DIR/project-state.md" ]; then
|
|
99
|
+
cat > "$CHECKPOINT_DIR/project-state.md" << 'TMPL'
|
|
100
|
+
# Project State
|
|
101
|
+
|
|
102
|
+
## What is this project?
|
|
103
|
+
<!-- Brief description -->
|
|
104
|
+
|
|
105
|
+
## Tech Stack
|
|
106
|
+
<!-- Languages, frameworks, tools -->
|
|
107
|
+
|
|
108
|
+
## What's Built
|
|
109
|
+
<!-- Completed features and components -->
|
|
110
|
+
|
|
111
|
+
## In Progress
|
|
112
|
+
<!-- Current work items -->
|
|
113
|
+
|
|
114
|
+
## Key Files
|
|
115
|
+
<!-- Important files and their purposes -->
|
|
116
|
+
|
|
117
|
+
## Known Issues
|
|
118
|
+
<!-- Bugs, blockers, open questions -->
|
|
119
|
+
TMPL
|
|
120
|
+
echo -e " ${GREEN}✓${RESET} Created: ${DIM}project-state.md${RESET}"
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
# decisions.md
|
|
124
|
+
if [ ! -f "$CHECKPOINT_DIR/decisions.md" ]; then
|
|
125
|
+
cat > "$CHECKPOINT_DIR/decisions.md" << 'TMPL'
|
|
126
|
+
# Architecture Decisions
|
|
127
|
+
|
|
128
|
+
<!-- Format:
|
|
129
|
+
## YYYY-MM-DD: Decision Title
|
|
130
|
+
**Context:** Why this decision was needed
|
|
131
|
+
**Decision:** What was decided
|
|
132
|
+
**Alternatives:** What else was considered
|
|
133
|
+
-->
|
|
134
|
+
TMPL
|
|
135
|
+
echo -e " ${GREEN}✓${RESET} Created: ${DIM}decisions.md${RESET}"
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
# problems.md
|
|
139
|
+
if [ ! -f "$CHECKPOINT_DIR/problems.md" ]; then
|
|
140
|
+
cat > "$CHECKPOINT_DIR/problems.md" << 'TMPL'
|
|
141
|
+
# Open Problems
|
|
142
|
+
|
|
143
|
+
<!-- Format:
|
|
144
|
+
## Problem Title
|
|
145
|
+
**Status:** open | investigating | blocked | resolved
|
|
146
|
+
**Description:** What's happening
|
|
147
|
+
**Impact:** Why it matters
|
|
148
|
+
**Notes:** Investigation progress
|
|
149
|
+
-->
|
|
150
|
+
TMPL
|
|
151
|
+
echo -e " ${GREEN}✓${RESET} Created: ${DIM}problems.md${RESET}"
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
echo -e " ${GREEN}✓${RESET} Templates: ${DIM}project-state.md, decisions.md, problems.md, sessions/${RESET}"
|
|
155
|
+
|
|
156
|
+
# --- Step 5: Create symlink ---
|
|
157
|
+
SYMLINK_PATH="$PROJECT_DIR/.checkpoints"
|
|
158
|
+
|
|
159
|
+
if [ -L "$SYMLINK_PATH" ]; then
|
|
160
|
+
rm "$SYMLINK_PATH"
|
|
161
|
+
elif [ -e "$SYMLINK_PATH" ]; then
|
|
162
|
+
echo -e " ${RED}!${RESET} .checkpoints already exists and is not a symlink. Skipping."
|
|
163
|
+
echo ""
|
|
164
|
+
else
|
|
165
|
+
true
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
if [ ! -e "$SYMLINK_PATH" ]; then
|
|
169
|
+
ln -s "$CHECKPOINT_DIR" "$SYMLINK_PATH"
|
|
170
|
+
echo -e " ${GREEN}✓${RESET} Symlink: ${DIM}.checkpoints → ${CHECKPOINT_DIR}${RESET}"
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
# --- Step 6: Configure AI editor ---
|
|
174
|
+
CHECKPOINT_INSTRUCTIONS='At session start, read `.checkpoints/project-state.md` and the latest file in `.checkpoints/sessions/` to pick up context from previous sessions.
|
|
175
|
+
|
|
176
|
+
When the user says "checkpoint" or when you complete a feature/fix, write a session summary to `.checkpoints/sessions/` (filename: `YYYY-MM-DD-HH-MM.md`) and update `.checkpoints/project-state.md`.'
|
|
177
|
+
|
|
178
|
+
# Claude Code: CLAUDE.md
|
|
179
|
+
if [ "$EDITOR_TYPE" = "claude-code" ] || [ "$EDITOR_TYPE" = "both" ]; then
|
|
180
|
+
CLAUDE_MD="$PROJECT_DIR/CLAUDE.md"
|
|
181
|
+
if [ -f "$CLAUDE_MD" ]; then
|
|
182
|
+
# Check if instructions already exist
|
|
183
|
+
if ! grep -q ".checkpoints/project-state.md" "$CLAUDE_MD" 2>/dev/null; then
|
|
184
|
+
echo "" >> "$CLAUDE_MD"
|
|
185
|
+
echo "$CHECKPOINT_INSTRUCTIONS" >> "$CLAUDE_MD"
|
|
186
|
+
echo -e " ${GREEN}✓${RESET} CLAUDE.md: ${DIM}Added checkpoint instructions${RESET}"
|
|
187
|
+
else
|
|
188
|
+
echo -e " ${DIM} CLAUDE.md already has checkpoint instructions${RESET}"
|
|
189
|
+
fi
|
|
190
|
+
else
|
|
191
|
+
echo "$CHECKPOINT_INSTRUCTIONS" > "$CLAUDE_MD"
|
|
192
|
+
echo -e " ${GREEN}✓${RESET} CLAUDE.md: ${DIM}Created with checkpoint instructions${RESET}"
|
|
193
|
+
fi
|
|
194
|
+
fi
|
|
195
|
+
|
|
196
|
+
# Cursor: .cursorrules
|
|
197
|
+
if [ "$EDITOR_TYPE" = "cursor" ] || [ "$EDITOR_TYPE" = "both" ]; then
|
|
198
|
+
CURSORRULES="$PROJECT_DIR/.cursorrules"
|
|
199
|
+
if [ -f "$CURSORRULES" ]; then
|
|
200
|
+
if ! grep -q ".checkpoints/project-state.md" "$CURSORRULES" 2>/dev/null; then
|
|
201
|
+
echo "" >> "$CURSORRULES"
|
|
202
|
+
echo "$CHECKPOINT_INSTRUCTIONS" >> "$CURSORRULES"
|
|
203
|
+
echo -e " ${GREEN}✓${RESET} .cursorrules: ${DIM}Added checkpoint instructions${RESET}"
|
|
204
|
+
else
|
|
205
|
+
echo -e " ${DIM} .cursorrules already has checkpoint instructions${RESET}"
|
|
206
|
+
fi
|
|
207
|
+
else
|
|
208
|
+
echo "$CHECKPOINT_INSTRUCTIONS" > "$CURSORRULES"
|
|
209
|
+
echo -e " ${GREEN}✓${RESET} .cursorrules: ${DIM}Created with checkpoint instructions${RESET}"
|
|
210
|
+
fi
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
# --- Step 7: Install Claude Code skill (if applicable) ---
|
|
214
|
+
if [ "$EDITOR_TYPE" = "claude-code" ] || [ "$EDITOR_TYPE" = "both" ]; then
|
|
215
|
+
mkdir -p "$SKILL_DIR"
|
|
216
|
+
|
|
217
|
+
cat > "$SKILL_DIR/SKILL.md" << 'SKILLEOF'
|
|
218
|
+
---
|
|
219
|
+
name: ai-session-checkpoint
|
|
220
|
+
description: Automatically save session context, decisions, and progress so no work is lost when sessions crash or context windows fill up.
|
|
221
|
+
triggers:
|
|
222
|
+
- "checkpoint"
|
|
223
|
+
- "save progress"
|
|
224
|
+
- "save context"
|
|
225
|
+
- "save session"
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
# ai-session-checkpoint
|
|
229
|
+
|
|
230
|
+
## On Session Start
|
|
231
|
+
|
|
232
|
+
Read `.checkpoints/project-state.md` and the latest file in `.checkpoints/sessions/` to pick up context from previous sessions. Briefly summarize what you found so the user knows you have context.
|
|
233
|
+
|
|
234
|
+
## On "checkpoint" / "save progress" / "save context"
|
|
235
|
+
|
|
236
|
+
1. **Check for changes**: Run `git diff --stat` to see if any files changed. If no changes and no significant decisions were made, tell the user "No changes to checkpoint" and skip.
|
|
237
|
+
|
|
238
|
+
2. **Write session file**: Create `.checkpoints/sessions/YYYY-MM-DD-HH-MM.md` with:
|
|
239
|
+
```
|
|
240
|
+
# Session: YYYY-MM-DD HH:MM
|
|
241
|
+
|
|
242
|
+
## Summary
|
|
243
|
+
- What was accomplished this session (2-5 bullet points)
|
|
244
|
+
|
|
245
|
+
## Files Changed
|
|
246
|
+
- path/to/file.ts — what changed and why
|
|
247
|
+
|
|
248
|
+
## Decisions Made
|
|
249
|
+
- Key decisions with brief rationale
|
|
250
|
+
|
|
251
|
+
## Open Items
|
|
252
|
+
- What's left to do, blockers, next steps
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
3. **Update project state**: Rewrite `.checkpoints/project-state.md` with current reality:
|
|
256
|
+
- What the project is
|
|
257
|
+
- Tech stack
|
|
258
|
+
- What's built and working
|
|
259
|
+
- What's in progress
|
|
260
|
+
- Key files and their purposes
|
|
261
|
+
- Known issues
|
|
262
|
+
|
|
263
|
+
4. **Retention sweep**: Count files in `.checkpoints/sessions/`. If more than 50, delete the oldest file(s) to stay at 50.
|
|
264
|
+
|
|
265
|
+
5. **Confirm**: Tell the user what was saved with a brief summary.
|
|
266
|
+
|
|
267
|
+
## On Feature/Fix Completion
|
|
268
|
+
|
|
269
|
+
When you complete a significant feature or fix, proactively offer: "Want me to checkpoint this progress?"
|
|
270
|
+
SKILLEOF
|
|
271
|
+
|
|
272
|
+
echo -e " ${GREEN}✓${RESET} Skill: ${DIM}Installed to ~/.claude/skills/ai-session-checkpoint/${RESET}"
|
|
273
|
+
fi
|
|
274
|
+
|
|
275
|
+
# --- Step 8: Add .checkpoints to .gitignore ---
|
|
276
|
+
GITIGNORE="$PROJECT_DIR/.gitignore"
|
|
277
|
+
if [ -f "$GITIGNORE" ]; then
|
|
278
|
+
if ! grep -q ".checkpoints" "$GITIGNORE" 2>/dev/null; then
|
|
279
|
+
echo "" >> "$GITIGNORE"
|
|
280
|
+
echo "# ai-session-checkpoint" >> "$GITIGNORE"
|
|
281
|
+
echo ".checkpoints" >> "$GITIGNORE"
|
|
282
|
+
echo -e " ${GREEN}✓${RESET} .gitignore: ${DIM}Added .checkpoints${RESET}"
|
|
283
|
+
fi
|
|
284
|
+
else
|
|
285
|
+
echo "# ai-session-checkpoint" > "$GITIGNORE"
|
|
286
|
+
echo ".checkpoints" >> "$GITIGNORE"
|
|
287
|
+
echo -e " ${GREEN}✓${RESET} .gitignore: ${DIM}Created with .checkpoints${RESET}"
|
|
288
|
+
fi
|
|
289
|
+
|
|
290
|
+
# --- Done ---
|
|
291
|
+
echo ""
|
|
292
|
+
echo -e "${GREEN}${BOLD}Done!${RESET} Checkpoints stored in: ${DIM}${CHECKPOINT_DIR}${RESET}"
|
|
293
|
+
echo ""
|
|
294
|
+
if [ "$EDITOR_TYPE" = "claude-code" ] || [ "$EDITOR_TYPE" = "both" ]; then
|
|
295
|
+
echo -e " Your next Claude Code session will:"
|
|
296
|
+
echo -e " ${DIM} 1. Read .checkpoints/ on start for context${RESET}"
|
|
297
|
+
echo -e " ${DIM} 2. Checkpoint on \"checkpoint\" command${RESET}"
|
|
298
|
+
echo -e " ${DIM} 3. Offer to checkpoint when features are done${RESET}"
|
|
299
|
+
fi
|
|
300
|
+
echo ""
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ai-session-checkpoint",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Never lose AI coding session context again. Auto-checkpoints for Claude Code, Cursor, and any AI editor.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "gokks8142",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/gokks8142/ai-session-checkpoint.git"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"ai-session-checkpoint": "bin/init.js"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"ai",
|
|
16
|
+
"claude",
|
|
17
|
+
"cursor",
|
|
18
|
+
"checkpoint",
|
|
19
|
+
"session",
|
|
20
|
+
"context",
|
|
21
|
+
"obsidian",
|
|
22
|
+
"developer-tools"
|
|
23
|
+
],
|
|
24
|
+
"files": [
|
|
25
|
+
"bin/",
|
|
26
|
+
"editors/",
|
|
27
|
+
"scripts/",
|
|
28
|
+
"templates/",
|
|
29
|
+
"install.sh",
|
|
30
|
+
"LICENSE",
|
|
31
|
+
"README.md"
|
|
32
|
+
]
|
|
33
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Link an existing project to an Obsidian vault checkpoint folder.
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# ./link-vault.sh <vault-path> <project-name> [project-dir]
|
|
7
|
+
#
|
|
8
|
+
# Example:
|
|
9
|
+
# ./link-vault.sh ~/GoogleDrive/.../MyVault/Org/ClaudeCode MyProject ~/vibecode/MyProject
|
|
10
|
+
#
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
VAULT_BASE="${1:?Usage: link-vault.sh <vault-base-path> <project-name> [project-dir]}"
|
|
14
|
+
PROJECT_NAME="${2:?Usage: link-vault.sh <vault-base-path> <project-name> [project-dir]}"
|
|
15
|
+
PROJECT_DIR="${3:-$(pwd)}"
|
|
16
|
+
|
|
17
|
+
CHECKPOINT_DIR="$VAULT_BASE/$PROJECT_NAME"
|
|
18
|
+
SYMLINK_PATH="$PROJECT_DIR/.checkpoints"
|
|
19
|
+
|
|
20
|
+
# Create checkpoint folder if needed
|
|
21
|
+
mkdir -p "$CHECKPOINT_DIR/sessions"
|
|
22
|
+
|
|
23
|
+
# Create symlink
|
|
24
|
+
if [ -L "$SYMLINK_PATH" ]; then
|
|
25
|
+
rm "$SYMLINK_PATH"
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
ln -s "$CHECKPOINT_DIR" "$SYMLINK_PATH"
|
|
29
|
+
echo "✓ Linked: $SYMLINK_PATH → $CHECKPOINT_DIR"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Project State
|
|
2
|
+
|
|
3
|
+
## What is this project?
|
|
4
|
+
<!-- Brief description -->
|
|
5
|
+
|
|
6
|
+
## Tech Stack
|
|
7
|
+
<!-- Languages, frameworks, tools -->
|
|
8
|
+
|
|
9
|
+
## What's Built
|
|
10
|
+
<!-- Completed features and components -->
|
|
11
|
+
|
|
12
|
+
## In Progress
|
|
13
|
+
<!-- Current work items -->
|
|
14
|
+
|
|
15
|
+
## Key Files
|
|
16
|
+
<!-- Important files and their purposes -->
|
|
17
|
+
|
|
18
|
+
## Known Issues
|
|
19
|
+
<!-- Bugs, blockers, open questions -->
|
|
File without changes
|