meridian-dev 1.1.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/BOOTSTRAP_PROMPT.md +110 -0
- package/README.md +344 -0
- package/backup/hooks/session-end.sh +44 -0
- package/backup/hooks/session-start.sh +37 -0
- package/backup/setup.sh +156 -0
- package/bin/meridian.js +100 -0
- package/doctor.sh +173 -0
- package/install.sh +62 -0
- package/journal-summary.sh +577 -0
- package/package.json +42 -0
- package/setup.sh +407 -0
- package/specializations/claude-code/CLAUDE.md-global-fragment.md +52 -0
- package/specializations/claude-code/CLAUDE.md-repo-fragment.md +16 -0
- package/specializations/claude-code/README.md +96 -0
- package/specializations/claude-code/commands/doctor.md +31 -0
- package/specializations/claude-code/commands/init-memory.md +127 -0
- package/specializations/claude-code/commands/init-team.md +335 -0
- package/specializations/claude-code/commands/journal.md +66 -0
- package/specializations/claude-code/hooks/check-global-state.sh +68 -0
- package/specializations/claude-code/settings.json +10 -0
- package/specializations/cursor/README.md +112 -0
- package/specializations/cursor/global-rule.mdc +53 -0
- package/specializations/cursor/repo-rule.mdc +25 -0
- package/specializations/generic/README.md +47 -0
- package/templates/global.md +73 -0
- package/templates/memory-file.md +18 -0
- package/templates/personal-state.md +14 -0
- package/templates/product-state.md +39 -0
- package/templates/repo-state.md +18 -0
- package/templates/session-protocol-fragment.md +46 -0
- package/templates/strategy-state.md +37 -0
- package/templates/team-state.md +29 -0
- package/uninstall.sh +85 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Bootstrap Prompt
|
|
2
|
+
|
|
3
|
+
Copy and paste the block below into a new Claude Code session. That's it.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Please set up Meridian for my Claude Code environment.
|
|
9
|
+
|
|
10
|
+
Run this command:
|
|
11
|
+
npx meridian-dev init
|
|
12
|
+
|
|
13
|
+
Once it completes:
|
|
14
|
+
1. Tell me what was installed and what still needs to be configured
|
|
15
|
+
2. Run /init-memory to initialize memory for the current repo
|
|
16
|
+
3. Ask me what my preferences are (communication style, tool preferences, commit
|
|
17
|
+
conventions, anything I want Claude to always know) so we can fill in
|
|
18
|
+
global-state.md together
|
|
19
|
+
4. Ask me if I want to set up backup (see below) — I will need to provide a
|
|
20
|
+
private GitHub repo URL before you can proceed with that step
|
|
21
|
+
5. Ask me if I want to set up team context (/init-team) for shared journals,
|
|
22
|
+
digests, and product state
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## What happens
|
|
28
|
+
|
|
29
|
+
The install command will:
|
|
30
|
+
- Create `~/.claude/memory/` and `~/.claude/memory/journal/`
|
|
31
|
+
- Install `~/.claude/global-state.md` (your persistent index)
|
|
32
|
+
- Install `~/.claude/hooks/check-global-state.sh` (warns when state is stale)
|
|
33
|
+
- Install slash commands: `/init-memory`, `/init-team`, `/journal`, `/doctor`
|
|
34
|
+
- Register the hook in `~/.claude/settings.json`
|
|
35
|
+
|
|
36
|
+
After the paste, Claude will walk you through filling in your preferences. From
|
|
37
|
+
then on, every session in every repo will start with full context of where you
|
|
38
|
+
left off. You don't need to do anything special — just open Claude Code and
|
|
39
|
+
start working. Claude reads the state files automatically.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Setting up backup (recommended)
|
|
44
|
+
|
|
45
|
+
Your memory files live locally at `~/.claude/`. If you want them backed up and
|
|
46
|
+
synced across machines, you need to provide a **private GitHub repo**.
|
|
47
|
+
|
|
48
|
+
**You must create this repo yourself** — Claude cannot do it for you.
|
|
49
|
+
|
|
50
|
+
Steps:
|
|
51
|
+
1. Go to github.com/new
|
|
52
|
+
2. Create a **private** repo (name it anything — e.g. `claude-memory`)
|
|
53
|
+
3. Copy the repo URL (SSH preferred: `git@github.com:you/claude-memory.git`)
|
|
54
|
+
4. Tell Claude: *"Set up backup using <your-repo-url>"*
|
|
55
|
+
|
|
56
|
+
Claude will then run:
|
|
57
|
+
```
|
|
58
|
+
bash ~/.claude/skip-tissue/backup/setup.sh <your-repo-url>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This will:
|
|
62
|
+
- Clone your backup repo to `~/.claude-backup/`
|
|
63
|
+
- Do an initial sync of your memory files
|
|
64
|
+
- Install hooks that automatically restore at session start and push at session end
|
|
65
|
+
|
|
66
|
+
After that, your memory is backed up silently on every session — no manual steps.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Setting up team context (optional)
|
|
71
|
+
|
|
72
|
+
Once you have the basics working, run `/init-team` in a Claude Code session to set up:
|
|
73
|
+
- A shared team context repo for journals and digests
|
|
74
|
+
- Slack integration for weekly digest posts
|
|
75
|
+
- Notion integration for browseable product state and digest archives
|
|
76
|
+
- Product state for your pilot repo (PM intent, success criteria, constraints)
|
|
77
|
+
|
|
78
|
+
This is the team-level layer — it turns individual session context into shared
|
|
79
|
+
visibility across product, engineering, and strategy.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Per-repo initialization
|
|
84
|
+
|
|
85
|
+
In any repo you work in, run:
|
|
86
|
+
```
|
|
87
|
+
/init-memory
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Claude will create `.claude/team-state.md` (shared) and `.claude/personal-state.md`
|
|
91
|
+
(gitignored), fix your `.gitignore`, and register the repo in your global index.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## For Cursor users
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
npx meridian-dev init-cursor
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Source
|
|
104
|
+
|
|
105
|
+
https://github.com/leizerowicz/skip-tissue
|
|
106
|
+
|
|
107
|
+
To install a specific version:
|
|
108
|
+
```
|
|
109
|
+
npx meridian-dev@1.1.0 init
|
|
110
|
+
```
|
package/README.md
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# Skip Tissue
|
|
2
|
+
## Persistent Cross-Session Context for AI Coding Assistants
|
|
3
|
+
|
|
4
|
+
> **Tool-agnostic.** Works with Claude Code, Cursor, Copilot, or any AI assistant that reads files. See `specializations/` for tool-specific setup.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Give Your AI a Working Model of Your World
|
|
9
|
+
|
|
10
|
+
The most valuable things your AI can know aren't in your codebase. They're the context that takes minutes to re-explain every session:
|
|
11
|
+
|
|
12
|
+
**Team dynamics:**
|
|
13
|
+
> "Jordan (co-founder) is a peer, not a report. Keep Jordan informed; Jordan manages their own workload. Don't suggest assigning tasks to Jordan."
|
|
14
|
+
|
|
15
|
+
**Project status:**
|
|
16
|
+
> "The checkout flow rewrite landed in staging but conversion dropped 3%. We're debugging before GA — don't touch the payment module until this is resolved."
|
|
17
|
+
|
|
18
|
+
**Decision frameworks:**
|
|
19
|
+
> "Build vs. buy: default to buy for non-core infrastructure unless there's significant vendor lock-in risk. We're a 4-person team — operational simplicity beats optimal."
|
|
20
|
+
|
|
21
|
+
These aren't README comments. They're the working model your AI needs to handle your real work — saved once, loaded every session.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Why Not Just Write a Good README?
|
|
26
|
+
|
|
27
|
+
A README is for contributors. Memory files are for your AI — and they contain things you would never put in a README:
|
|
28
|
+
|
|
29
|
+
- Team dynamics and working style notes
|
|
30
|
+
- Personal decision frameworks and context that shifts over time
|
|
31
|
+
- Current status of every active project, updated after each session
|
|
32
|
+
- Solutions to recurring problems and cross-repo architectural decisions
|
|
33
|
+
|
|
34
|
+
A README is static documentation. Memory files are a live operating context.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## The Problem
|
|
39
|
+
|
|
40
|
+
AI coding assistants have no memory between sessions. Every conversation starts from zero. You re-explain the project, re-establish conventions, re-describe where you left off. The AI re-discovers things it already learned last time.
|
|
41
|
+
|
|
42
|
+
This kit solves that with **plain markdown files** that your AI reads at the start of every session. No databases, no proprietary formats, no vendor lock-in — just text files you own and can read yourself.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## How It Works
|
|
47
|
+
|
|
48
|
+
Your AI reads a small set of markdown files at session start to reconstruct context. At session end, it updates those files with what changed. The next session picks up exactly where you left off.
|
|
49
|
+
|
|
50
|
+
> **Note on paths:** The memory directory depends on your tool. Claude Code uses `~/.claude/`. Cursor and generic setups use `~/.ai-memory/`. The setup script handles this automatically — all examples below show the generic path.
|
|
51
|
+
|
|
52
|
+
### The Three-File Pattern
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
~/.ai-memory/
|
|
56
|
+
global.md # Thin index — always loaded. Preferences, project table, file manifest.
|
|
57
|
+
state.md # Admin/non-repo notes (decisions, emails, misc tasks)
|
|
58
|
+
memory/ # Topic files — loaded on demand when the session topic matches
|
|
59
|
+
<topic>.md
|
|
60
|
+
journal/
|
|
61
|
+
YYYY-MM-DD.md # Daily log, append-only
|
|
62
|
+
|
|
63
|
+
<repo>/.ai-memory/
|
|
64
|
+
state.md # Per-repo: branch, status, next steps, gotchas
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**The index stays small** (under 80 lines). Detail lives in `memory/` files and is loaded only when relevant. This keeps every session fast and focused.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Quick Start
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
curl -fsSL https://raw.githubusercontent.com/leizerowicz/skip-tissue/main/install.sh | bash
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Or if you've cloned the repo:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
bash setup.sh
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The setup script will:
|
|
84
|
+
- Create the memory directory structure
|
|
85
|
+
- Install template files
|
|
86
|
+
- Install your chosen tool's specialization
|
|
87
|
+
- Register any hooks or system prompt fragments
|
|
88
|
+
|
|
89
|
+
Then pick up your tool-specific README in `specializations/`.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Manual Setup
|
|
94
|
+
|
|
95
|
+
If you prefer to set up by hand:
|
|
96
|
+
|
|
97
|
+
### 1. Create the directory structure
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
mkdir -p ~/.ai-memory/memory/journal
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 2. Copy and fill in the global index
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
cp templates/global.md ~/.ai-memory/global.md
|
|
107
|
+
# Edit it with your name, preferences, and initial projects
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 3. Add the session protocol to your AI tool
|
|
111
|
+
|
|
112
|
+
Each tool has a different mechanism. See `specializations/` for your tool:
|
|
113
|
+
|
|
114
|
+
| Tool | Specialization |
|
|
115
|
+
|------|---------------|
|
|
116
|
+
| Claude Code | `specializations/claude-code/` |
|
|
117
|
+
| Cursor | `specializations/cursor/` |
|
|
118
|
+
| Any (manual system prompt) | `specializations/generic/` |
|
|
119
|
+
|
|
120
|
+
### 4. Initialize each repo
|
|
121
|
+
|
|
122
|
+
Copy `templates/repo-state.md` to `<repo>/.ai-memory/state.md` and fill it in. Or use the `/init-memory` command if your tool supports custom commands (see specialization).
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## What Your Memory Files Look Like
|
|
127
|
+
|
|
128
|
+
Here are examples of the kinds of content that belong in memory files. These are the entries that make the difference between an AI that re-asks the same questions every session and one that picks up exactly where you left off.
|
|
129
|
+
|
|
130
|
+
**Working style and technical preferences** (`~/.ai-memory/memory/technical-patterns.md`):
|
|
131
|
+
|
|
132
|
+
```markdown
|
|
133
|
+
## Working Style
|
|
134
|
+
- Commit messages: imperative mood, explain why not what
|
|
135
|
+
- Never touch production before local repro
|
|
136
|
+
- Default to TypeScript strict mode
|
|
137
|
+
- Build vs. buy: default buy for non-core infrastructure unless vendor lock-in risk
|
|
138
|
+
- When in doubt, prefer the boring solution over the clever one
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Team context** (`~/.ai-memory/memory/team-context.md`):
|
|
142
|
+
|
|
143
|
+
```markdown
|
|
144
|
+
## Team Context
|
|
145
|
+
- Design Lead: prefers async feedback via Figma, not Slack. Needs 24h heads-up for scope changes.
|
|
146
|
+
- Co-founder: peer, not a report. Keep informed; they manage their own workload.
|
|
147
|
+
- Support team: PST-based. Async decisions logged in Notion, not Slack.
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Active projects** (in `~/.ai-memory/global.md`):
|
|
151
|
+
|
|
152
|
+
```markdown
|
|
153
|
+
## Active Projects
|
|
154
|
+
| Project | Status | Next |
|
|
155
|
+
|---------|--------|------|
|
|
156
|
+
| Checkout flow rewrite | Staging — conversion regression under investigation | Fix promo code edge case, re-run A/B |
|
|
157
|
+
| Notification service | In prod, but email deliverability dropped to 89% | Investigate SPF/DKIM alignment with new domain |
|
|
158
|
+
| Mobile app v2 | Design approved, API contracts drafted | Scaffold React Native nav + auth screens |
|
|
159
|
+
| Billing migration | **ON HOLD** — waiting on Stripe Connect approval | Unblock after Stripe responds (ETA ~1 week) |
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Per-repo state** (`<repo>/.ai-memory/state.md`):
|
|
163
|
+
|
|
164
|
+
```markdown
|
|
165
|
+
## Branch
|
|
166
|
+
feat/webhooks-retry
|
|
167
|
+
|
|
168
|
+
## Status
|
|
169
|
+
Retry logic works for 5xx errors. Stuck on idempotency — duplicate events when
|
|
170
|
+
the upstream acks late and we retry. Need a dedup key in the event payload.
|
|
171
|
+
|
|
172
|
+
## Next
|
|
173
|
+
Add `idempotency_key` to WebhookEvent model, enforce uniqueness in Postgres,
|
|
174
|
+
then re-run the chaos test suite.
|
|
175
|
+
|
|
176
|
+
## Gotchas
|
|
177
|
+
- ngrok tunnel expires every 2 hours — restart before long test runs.
|
|
178
|
+
- The `webhook_events` table in staging has 800K rows of junk. Truncate before
|
|
179
|
+
benchmarking or the index scan will mislead you.
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
These files are plain markdown. You own them, you can read them, and they travel with you across tools.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## What to Store — and What Not To
|
|
187
|
+
|
|
188
|
+
Not everything belongs in AI-readable memory files. These files are transmitted to cloud AI provider APIs on every session. Here's a practical guide:
|
|
189
|
+
|
|
190
|
+
### Tier 1 — Safe to include in any AI session
|
|
191
|
+
- Project status and next steps
|
|
192
|
+
- Technical patterns, gotchas, and architectural decisions
|
|
193
|
+
- Workflow preferences and tool conventions
|
|
194
|
+
- Team communication preferences (using roles, not names where possible)
|
|
195
|
+
|
|
196
|
+
### Tier 2 — Handle with care
|
|
197
|
+
- Named individuals with working style notes — keep factual, avoid psychological characterizations. Use roles ("Design Lead") rather than names when possible.
|
|
198
|
+
- Vendor or client context — include enough to be useful, but not dispute positions or settlement targets
|
|
199
|
+
- Anything you'd be comfortable sharing in a work setting
|
|
200
|
+
|
|
201
|
+
### Tier 3 — Do not store in AI-readable files
|
|
202
|
+
- Active legal dispute positions and settlement targets
|
|
203
|
+
- Salary, compensation, or financial negotiation strategy
|
|
204
|
+
- Named individual characterizations you'd be uncomfortable seeing quoted externally
|
|
205
|
+
- Medical or personal information about anyone
|
|
206
|
+
|
|
207
|
+
> **Guiding principle:** If you would be uncomfortable having this content quoted back in an employment discussion, a legal proceeding, or a vendor negotiation, it should not be in a file transmitted to a cloud AI API.
|
|
208
|
+
|
|
209
|
+
**A practical middle ground:** Pseudonymize sensitive context. "Design Lead prefers async feedback" is useful and carries no personal data risk. "Sarah thinks the PM is incompetent and threatened to quit" should stay in your head.
|
|
210
|
+
|
|
211
|
+
### A note on GDPR
|
|
212
|
+
|
|
213
|
+
European users storing personal data about named third parties (employees, contractors, clients) in files transmitted to a cloud API likely constitute data processing under GDPR Article 4. If this applies to you, treat AI memory files as you would any other data processor relationship — store only what's necessary, and consider pseudonymization.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## What to Store — Examples
|
|
218
|
+
|
|
219
|
+
**Good memory file candidates:**
|
|
220
|
+
- Decisions that span multiple repos or sessions
|
|
221
|
+
- Architectural patterns your team has settled on
|
|
222
|
+
- Solutions to recurring problems
|
|
223
|
+
- Cross-repo conventions
|
|
224
|
+
- Team communication preferences and working style notes
|
|
225
|
+
|
|
226
|
+
**Don't store:**
|
|
227
|
+
- Things already in the codebase (code is the source of truth)
|
|
228
|
+
- Single-session temporary state
|
|
229
|
+
- Anything that duplicates what's in a project README or CLAUDE.md
|
|
230
|
+
- Sensitive negotiation positions or personal information (see tiers above)
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Tool-Specific Setup
|
|
235
|
+
|
|
236
|
+
### Claude Code
|
|
237
|
+
|
|
238
|
+
See `specializations/claude-code/README.md` for:
|
|
239
|
+
- Adding the session protocol to `CLAUDE.md`
|
|
240
|
+
- Registering the `/init-memory` command
|
|
241
|
+
- Session start/end hooks
|
|
242
|
+
|
|
243
|
+
### Cursor
|
|
244
|
+
|
|
245
|
+
See `specializations/cursor/README.md` for:
|
|
246
|
+
- Adding the protocol to `.cursorrules`
|
|
247
|
+
- Cursor-compatible memory file paths
|
|
248
|
+
- Session management without hooks
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Backup
|
|
253
|
+
|
|
254
|
+
Memory files are plain text — back them up like any other important file:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
# Add to an existing private repo, or create one
|
|
258
|
+
cd ~/.ai-memory
|
|
259
|
+
git init
|
|
260
|
+
git remote add origin git@github.com:<you>/ai-memory-private.git
|
|
261
|
+
git add -A && git commit -m "backup"
|
|
262
|
+
git push -u origin main
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Run this periodically or hook it into your session-end workflow.
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## The Protocol
|
|
270
|
+
|
|
271
|
+
### Session Start
|
|
272
|
+
|
|
273
|
+
Your AI will:
|
|
274
|
+
1. Read `~/.ai-memory/global.md` (always)
|
|
275
|
+
2. Read the current repo's `.ai-memory/state.md` (always)
|
|
276
|
+
3. Check the Memory Files table in `global.md` — load any topic files that match the session
|
|
277
|
+
4. Say: **"Resuming [project]: [summary of current state]"**
|
|
278
|
+
5. Ask: **"What's the goal for this session? What does success look like?"**
|
|
279
|
+
|
|
280
|
+
### Mid-Session
|
|
281
|
+
|
|
282
|
+
If the session drifts from the stated goal, the AI flags it:
|
|
283
|
+
|
|
284
|
+
> *"Quick check — we set out to [goal]. This feels like [tangent]. Stay the course or pivot?"*
|
|
285
|
+
|
|
286
|
+
### Session End
|
|
287
|
+
|
|
288
|
+
When you say "stop", "done", "pause", "wrap up", or "tomorrow":
|
|
289
|
+
1. AI updates `.ai-memory/state.md` in the current repo
|
|
290
|
+
2. AI updates the Active Projects row in `~/.ai-memory/global.md`
|
|
291
|
+
3. AI creates/updates any relevant topic memory files
|
|
292
|
+
4. AI appends to `~/.ai-memory/memory/journal/YYYY-MM-DD.md`
|
|
293
|
+
5. AI confirms: **"State saved. Say 'let's continue' next time."**
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Journal Format
|
|
298
|
+
|
|
299
|
+
The journal is a daily append-only log. Each entry follows this structure:
|
|
300
|
+
|
|
301
|
+
```markdown
|
|
302
|
+
## [Project or context] — [Brief title]
|
|
303
|
+
**Why:** [The stated goal for this session]
|
|
304
|
+
**What:** [Bullet list of what was actually done]
|
|
305
|
+
**Outcome:** [Did we hit the goal? Key deliverables]
|
|
306
|
+
**On track?:** [Focused or did we drift? What caused drift?]
|
|
307
|
+
**Lessons:** [Worth remembering cross-session]
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Multiple sessions per day just append more blocks to the same file.
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## File Templates
|
|
315
|
+
|
|
316
|
+
All templates are in `templates/`. See them for copy-paste-ready starting points:
|
|
317
|
+
|
|
318
|
+
| Template | Purpose |
|
|
319
|
+
|----------|---------|
|
|
320
|
+
| `templates/global.md` | Starting `~/.ai-memory/global.md` |
|
|
321
|
+
| `templates/repo-state.md` | Starting `.ai-memory/state.md` for a repo |
|
|
322
|
+
| `templates/memory-file.md` | Starting point for a topic memory file |
|
|
323
|
+
| `templates/session-protocol-fragment.md` | The protocol block to inject into your AI tool |
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Contributing
|
|
328
|
+
|
|
329
|
+
### Adding a Specialization
|
|
330
|
+
|
|
331
|
+
To add support for a new tool:
|
|
332
|
+
1. Create `specializations/<tool-name>/README.md` following the pattern in `specializations/claude-code/README.md`
|
|
333
|
+
2. Include any config files, hook scripts, or command files needed
|
|
334
|
+
3. Document the install steps clearly — assume no prior context
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## Critical Rules
|
|
339
|
+
|
|
340
|
+
1. **Always read state files at session start.** They're plain files — they cannot fail.
|
|
341
|
+
2. **Always update state files at session end.** Edit in place; don't append new sections.
|
|
342
|
+
3. **Keep the global index small** (under 80 lines). Detail goes in `memory/` files.
|
|
343
|
+
4. **Per-repo state stays focused** on that repo. Cross-repo context goes in topic files.
|
|
344
|
+
5. **Don't gitignore your AI tool's config directory as a whole.** Only ignore local-only files (state.md, secrets). Commands, skills, and settings should be tracked.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Skip Tissue — Backup Push Hook
|
|
3
|
+
# Runs at session end. Syncs ~/.claude/ memory files to backup repo and pushes.
|
|
4
|
+
# Silently no-ops if backup isn't configured or nothing changed.
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
MEMORY_DIR="$HOME/.claude"
|
|
9
|
+
BACKUP_DIR_FILE="$MEMORY_DIR/.backup-dir"
|
|
10
|
+
|
|
11
|
+
[ -f "$BACKUP_DIR_FILE" ] || exit 0
|
|
12
|
+
BACKUP_DIR="$(cat "$BACKUP_DIR_FILE")"
|
|
13
|
+
[ -d "$BACKUP_DIR/.git" ] || exit 0
|
|
14
|
+
command -v git &>/dev/null || exit 0
|
|
15
|
+
|
|
16
|
+
# Sync: ~/.claude/ -> backup repo
|
|
17
|
+
rsync -a \
|
|
18
|
+
"$MEMORY_DIR/global-state.md" \
|
|
19
|
+
"$MEMORY_DIR/state.md" \
|
|
20
|
+
"$BACKUP_DIR/" 2>/dev/null || true
|
|
21
|
+
|
|
22
|
+
if [ -d "$MEMORY_DIR/memory" ]; then
|
|
23
|
+
rsync -a "$MEMORY_DIR/memory/" "$BACKUP_DIR/memory/" 2>/dev/null || true
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# Commit and push if anything changed
|
|
27
|
+
cd "$BACKUP_DIR" || { echo "ERROR: cannot cd to backup dir $BACKUP_DIR"; exit 1; }
|
|
28
|
+
git add -A
|
|
29
|
+
if git diff --cached --quiet; then
|
|
30
|
+
exit 0 # Nothing changed — skip silently
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
git commit -m "auto: $(date '+%Y-%m-%d %H:%M')" --quiet
|
|
34
|
+
|
|
35
|
+
# Push
|
|
36
|
+
GIT_ERROR=$(git push origin "${BRANCH:-main}" --quiet 2>&1) && {
|
|
37
|
+
echo "$(date '+%Y-%m-%d %H:%M')" > "$HOME/.claude/.backup-last-push"
|
|
38
|
+
rm -f "$HOME/.claude/.backup-last-error"
|
|
39
|
+
} || {
|
|
40
|
+
ERROR_MSG="$(date '+%Y-%m-%d %H:%M') — git push failed: $GIT_ERROR"
|
|
41
|
+
echo "$ERROR_MSG" > "$HOME/.claude/.backup-last-error"
|
|
42
|
+
echo "Warning: Backup push failed. Details: $HOME/.claude/.backup-last-error"
|
|
43
|
+
exit 1
|
|
44
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Skip Tissue — Backup Restore Hook
|
|
3
|
+
# Runs at session start. Pulls latest from backup repo, then syncs to ~/.claude/
|
|
4
|
+
# Silently no-ops if backup isn't configured or git isn't available.
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
MEMORY_DIR="$HOME/.claude"
|
|
9
|
+
BACKUP_DIR_FILE="$MEMORY_DIR/.backup-dir"
|
|
10
|
+
|
|
11
|
+
[ -f "$BACKUP_DIR_FILE" ] || exit 0
|
|
12
|
+
BACKUP_DIR="$(cat "$BACKUP_DIR_FILE")"
|
|
13
|
+
[ -d "$BACKUP_DIR/.git" ] || exit 0
|
|
14
|
+
command -v git &>/dev/null || exit 0
|
|
15
|
+
|
|
16
|
+
# Warn if last push failed
|
|
17
|
+
LAST_ERROR="$HOME/.claude/.backup-last-error"
|
|
18
|
+
if [ -f "$LAST_ERROR" ]; then
|
|
19
|
+
echo "Warning: Backup: last push FAILED at $(cat "$LAST_ERROR")"
|
|
20
|
+
echo " Fix and re-run: cd ~/.claude-backup && git push"
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
# Pull latest (silently — don't block session start)
|
|
24
|
+
git -C "$BACKUP_DIR" pull --quiet --ff-only 2>/dev/null || true
|
|
25
|
+
|
|
26
|
+
# Restore: sync backup -> ~/.claude/
|
|
27
|
+
rsync -a --update \
|
|
28
|
+
"$BACKUP_DIR/global-state.md" \
|
|
29
|
+
"$MEMORY_DIR/" 2>/dev/null || true
|
|
30
|
+
|
|
31
|
+
rsync -a --update \
|
|
32
|
+
"$BACKUP_DIR/state.md" \
|
|
33
|
+
"$MEMORY_DIR/" 2>/dev/null || true
|
|
34
|
+
|
|
35
|
+
if [ -d "$BACKUP_DIR/memory" ]; then
|
|
36
|
+
rsync -a --update "$BACKUP_DIR/memory/" "$MEMORY_DIR/memory/" 2>/dev/null || true
|
|
37
|
+
fi
|
package/backup/setup.sh
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Skip Tissue — Backup Setup
|
|
3
|
+
# Wires a private GitHub repo as your memory backup.
|
|
4
|
+
#
|
|
5
|
+
# Usage: bash backup/setup.sh <repo-url>
|
|
6
|
+
# Example: bash backup/setup.sh git@github.com:you/claude-memory.git
|
|
7
|
+
# bash backup/setup.sh https://github.com/you/claude-memory.git
|
|
8
|
+
#
|
|
9
|
+
# What this does:
|
|
10
|
+
# 1. Clones your backup repo to ~/.claude-backup/
|
|
11
|
+
# 2. Does an initial sync of your memory files into it
|
|
12
|
+
# 3. Installs session-start (restore) and session-end (push) hooks
|
|
13
|
+
# 4. Registers both hooks in ~/.claude/settings.json
|
|
14
|
+
|
|
15
|
+
set -euo pipefail
|
|
16
|
+
|
|
17
|
+
REPO_URL="${1:-}"
|
|
18
|
+
BACKUP_DIR="$HOME/.claude-backup"
|
|
19
|
+
MEMORY_DIR="$HOME/.claude"
|
|
20
|
+
HOOKS_DIR="$HOME/.claude/hooks"
|
|
21
|
+
SETTINGS="$HOME/.claude/settings.json"
|
|
22
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
23
|
+
|
|
24
|
+
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; RESET='\033[0m'
|
|
25
|
+
log() { echo -e "${GREEN}✓${RESET} $1"; }
|
|
26
|
+
warn() { echo -e "${YELLOW}⚠${RESET} $1"; }
|
|
27
|
+
err() { echo -e "${RED}✗${RESET} $1"; exit 1; }
|
|
28
|
+
|
|
29
|
+
# ── Validate ──────────────────────────────────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
if [ -z "$REPO_URL" ]; then
|
|
32
|
+
err "No repo URL provided.\nUsage: bash backup/setup.sh <repo-url>"
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
if ! command -v git &>/dev/null; then
|
|
36
|
+
err "git is required but not installed."
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
if ! command -v rsync &>/dev/null; then
|
|
40
|
+
err "rsync is required but not installed. On macOS: brew install rsync"
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# ── Clone or init backup repo ─────────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
echo ""
|
|
46
|
+
echo "Skip Tissue — Backup Setup"
|
|
47
|
+
echo ""
|
|
48
|
+
|
|
49
|
+
if [ -d "$BACKUP_DIR/.git" ]; then
|
|
50
|
+
warn "Backup repo already exists at $BACKUP_DIR — pulling latest"
|
|
51
|
+
git -C "$BACKUP_DIR" pull --quiet
|
|
52
|
+
else
|
|
53
|
+
echo "Cloning backup repo..."
|
|
54
|
+
if git clone "$REPO_URL" "$BACKUP_DIR" 2>/dev/null; then
|
|
55
|
+
log "Cloned $REPO_URL → $BACKUP_DIR"
|
|
56
|
+
else
|
|
57
|
+
# Repo exists on GitHub but is empty — clone fails. Init locally instead.
|
|
58
|
+
mkdir -p "$BACKUP_DIR"
|
|
59
|
+
git -C "$BACKUP_DIR" init
|
|
60
|
+
git -C "$BACKUP_DIR" remote add origin "$REPO_URL"
|
|
61
|
+
log "Initialized empty backup repo at $BACKUP_DIR"
|
|
62
|
+
fi
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# ── Initial sync ──────────────────────────────────────────────────────────────
|
|
66
|
+
|
|
67
|
+
echo "Syncing memory files to backup repo..."
|
|
68
|
+
|
|
69
|
+
# Files to back up: global index, admin state, and the entire memory/ directory
|
|
70
|
+
mkdir -p "$BACKUP_DIR"
|
|
71
|
+
rsync -a \
|
|
72
|
+
"$MEMORY_DIR/global-state.md" \
|
|
73
|
+
"$MEMORY_DIR/state.md" \
|
|
74
|
+
"$BACKUP_DIR/" 2>/dev/null || true
|
|
75
|
+
|
|
76
|
+
if [ -d "$MEMORY_DIR/memory" ]; then
|
|
77
|
+
mkdir -p "$BACKUP_DIR/memory"
|
|
78
|
+
rsync -a "$MEMORY_DIR/memory/" "$BACKUP_DIR/memory/" 2>/dev/null || true
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
# Initial commit
|
|
82
|
+
cd "$BACKUP_DIR"
|
|
83
|
+
git add -A
|
|
84
|
+
if ! git diff --cached --quiet; then
|
|
85
|
+
git commit -m "initial backup — $(date '+%Y-%m-%d')"
|
|
86
|
+
git push -u origin main 2>/dev/null || git push -u origin master 2>/dev/null || \
|
|
87
|
+
warn "Push failed — check your repo URL and SSH/token auth, then run: git -C $BACKUP_DIR push"
|
|
88
|
+
log "Initial backup pushed"
|
|
89
|
+
else
|
|
90
|
+
log "Nothing to commit in initial sync"
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# ── Install hook scripts ──────────────────────────────────────────────────────
|
|
94
|
+
|
|
95
|
+
mkdir -p "$HOOKS_DIR"
|
|
96
|
+
|
|
97
|
+
cp "$SCRIPT_DIR/hooks/session-start.sh" "$HOOKS_DIR/backup-restore.sh"
|
|
98
|
+
chmod +x "$HOOKS_DIR/backup-restore.sh"
|
|
99
|
+
log "Installed: $HOOKS_DIR/backup-restore.sh"
|
|
100
|
+
|
|
101
|
+
cp "$SCRIPT_DIR/hooks/session-end.sh" "$HOOKS_DIR/backup-push.sh"
|
|
102
|
+
chmod +x "$HOOKS_DIR/backup-push.sh"
|
|
103
|
+
log "Installed: $HOOKS_DIR/backup-push.sh"
|
|
104
|
+
|
|
105
|
+
# Store the backup dir path so hooks know where to find it
|
|
106
|
+
echo "$BACKUP_DIR" > "$MEMORY_DIR/.backup-dir"
|
|
107
|
+
log "Stored backup dir config: $MEMORY_DIR/.backup-dir"
|
|
108
|
+
|
|
109
|
+
# ── Register hooks in settings.json ──────────────────────────────────────────
|
|
110
|
+
|
|
111
|
+
if [ ! -f "$SETTINGS" ]; then
|
|
112
|
+
cp "$SCRIPT_DIR/../specializations/claude-code/settings.json" "$SETTINGS"
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
python3 - <<PYEOF
|
|
116
|
+
import json, os
|
|
117
|
+
|
|
118
|
+
settings_path = os.path.expanduser("$SETTINGS")
|
|
119
|
+
with open(settings_path) as f:
|
|
120
|
+
s = json.load(f)
|
|
121
|
+
|
|
122
|
+
hooks = s.setdefault("hooks", {})
|
|
123
|
+
|
|
124
|
+
# SessionStart: restore (pull) — prepend so it runs before check-global-state
|
|
125
|
+
start_hooks = hooks.setdefault("SessionStart", [])
|
|
126
|
+
restore_cmd = {"type": "command", "command": "bash ~/.claude/hooks/backup-restore.sh"}
|
|
127
|
+
if not any(h.get("command", "").endswith("backup-restore.sh") for h in start_hooks):
|
|
128
|
+
start_hooks.insert(0, restore_cmd)
|
|
129
|
+
print(" + Registered backup-restore.sh in SessionStart")
|
|
130
|
+
else:
|
|
131
|
+
print(" - backup-restore.sh already in SessionStart")
|
|
132
|
+
|
|
133
|
+
# Stop: push — runs when Claude session ends
|
|
134
|
+
stop_hooks = hooks.setdefault("Stop", [])
|
|
135
|
+
push_cmd = {"type": "command", "command": "bash ~/.claude/hooks/backup-push.sh"}
|
|
136
|
+
if not any(h.get("command", "").endswith("backup-push.sh") for h in stop_hooks):
|
|
137
|
+
stop_hooks.append(push_cmd)
|
|
138
|
+
print(" + Registered backup-push.sh in Stop")
|
|
139
|
+
else:
|
|
140
|
+
print(" - backup-push.sh already in Stop")
|
|
141
|
+
|
|
142
|
+
with open(settings_path, "w") as f:
|
|
143
|
+
json.dump(s, f, indent=2)
|
|
144
|
+
f.write("\n")
|
|
145
|
+
PYEOF
|
|
146
|
+
|
|
147
|
+
log "Updated $SETTINGS"
|
|
148
|
+
|
|
149
|
+
# ── Done ──────────────────────────────────────────────────────────────────────
|
|
150
|
+
|
|
151
|
+
echo ""
|
|
152
|
+
echo "Backup setup complete."
|
|
153
|
+
echo " Backup repo: $BACKUP_DIR → $REPO_URL"
|
|
154
|
+
echo " Restore hook: runs at session start (pulls latest)"
|
|
155
|
+
echo " Push hook: runs at session end (commits + pushes changes)"
|
|
156
|
+
echo ""
|