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,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Initialize the Skip Tissue for the current repo. Creates .claude/team-state.md (tracked in git) and .claude/personal-state.md (gitignored), ensures correct .gitignore entries, appends session protocol to CLAUDE.md, and registers the repo in the global index. Safe to run multiple times (idempotent).
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Initialize Memory System for Current Repo
|
|
6
|
+
|
|
7
|
+
Run these steps in order. Skip any step that's already done (this command is idempotent).
|
|
8
|
+
|
|
9
|
+
## Step 1: Detect Context
|
|
10
|
+
|
|
11
|
+
- Determine the current working directory
|
|
12
|
+
- Check if it's a git repo (`ls .git` or `git rev-parse --show-toplevel`)
|
|
13
|
+
- Read `~/.claude/global-state.md` to check if this repo is already registered
|
|
14
|
+
|
|
15
|
+
## Step 2: Create state files (if missing)
|
|
16
|
+
|
|
17
|
+
This repo uses TWO state files with different visibility:
|
|
18
|
+
|
|
19
|
+
**`.claude/team-state.md`** — committed to git (shared team context)
|
|
20
|
+
|
|
21
|
+
If `.claude/team-state.md` does not exist, create it:
|
|
22
|
+
|
|
23
|
+
```markdown
|
|
24
|
+
# [Repo Name] — Team State
|
|
25
|
+
|
|
26
|
+
Last updated: [today's date]
|
|
27
|
+
|
|
28
|
+
## Architecture & Key Decisions
|
|
29
|
+
<!-- Decisions the whole team should know. Include the "why" not just the "what". -->
|
|
30
|
+
|
|
31
|
+
## Conventions
|
|
32
|
+
<!-- Patterns, naming, tooling choices that apply across the team. -->
|
|
33
|
+
|
|
34
|
+
## Current Sprint Focus
|
|
35
|
+
<!-- Team-level "what are we working on right now" -->
|
|
36
|
+
|
|
37
|
+
## Shared Gotchas
|
|
38
|
+
<!-- Hard-won lessons. What surprised us. What NOT to do. -->
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**`.claude/personal-state.md`** — gitignored (your personal context)
|
|
42
|
+
|
|
43
|
+
If `.claude/personal-state.md` does not exist, create it:
|
|
44
|
+
|
|
45
|
+
```markdown
|
|
46
|
+
# [Repo Name] — Personal State
|
|
47
|
+
|
|
48
|
+
Last updated: [today's date]
|
|
49
|
+
|
|
50
|
+
(This file is gitignored. It's yours — context you wouldn't want teammates reading as objective fact.)
|
|
51
|
+
|
|
52
|
+
## My Current Focus
|
|
53
|
+
<!-- Your personal next steps -->
|
|
54
|
+
|
|
55
|
+
## Personal Context
|
|
56
|
+
<!-- Working notes, opinions, relationship dynamics for this repo -->
|
|
57
|
+
|
|
58
|
+
## What I'm Watching
|
|
59
|
+
<!-- Open questions, things to follow up on -->
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Step 3: Fix `.gitignore`
|
|
63
|
+
|
|
64
|
+
Check `.gitignore`. Ensure these lines are present:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
.claude/personal-state.md
|
|
68
|
+
.claude/settings.local.json
|
|
69
|
+
.claude/memory.db
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Do NOT add `.claude/` as a whole directory.** That breaks skills and commands. Only add the specific files above. Note that `team-state.md` is intentionally NOT gitignored — it is meant to be committed and shared with your team.
|
|
73
|
+
|
|
74
|
+
If any of those lines are missing, append them. If `.claude/` (as a directory) is already in `.gitignore`, remove it and replace with the three file-level entries above.
|
|
75
|
+
|
|
76
|
+
## Step 4: Append Session Protocol to CLAUDE.md
|
|
77
|
+
|
|
78
|
+
Read the repo's `CLAUDE.md`. If it does NOT already contain "Session State Protocol", append this:
|
|
79
|
+
|
|
80
|
+
```markdown
|
|
81
|
+
|
|
82
|
+
## Session State Protocol
|
|
83
|
+
|
|
84
|
+
**At session start (REQUIRED):**
|
|
85
|
+
1. Read `~/.claude/global-state.md` — preferences, active projects, memory file manifest
|
|
86
|
+
2. Read `.claude/team-state.md` in this repo — shared team context: architecture decisions, conventions, sprint focus, gotchas
|
|
87
|
+
3. Read `.claude/personal-state.md` in this repo — your personal context: current focus, working notes, opinions
|
|
88
|
+
4. Check the Memory Files table in global-state.md — load any `~/.claude/memory/` files relevant to this session's topic
|
|
89
|
+
|
|
90
|
+
**At session end (when user says stop/done/pause/tomorrow):**
|
|
91
|
+
1. Update `.claude/team-state.md` with shared context: architecture decisions, conventions, gotchas the team should know
|
|
92
|
+
2. Update `.claude/personal-state.md` with personal context: your next steps, working notes, opinions
|
|
93
|
+
3. Update the project's row in `~/.claude/global-state.md` Active Projects table
|
|
94
|
+
4. If significant new cross-repo context was created (patterns, strategies, decisions), create or update a file in `~/.claude/memory/` and add it to the Memory Files manifest in global-state.md
|
|
95
|
+
|
|
96
|
+
**Do NOT use ruvector/claude-flow memory CLI for state storage.** Use plain markdown files only.
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
If `CLAUDE.md` doesn't exist, create a minimal one with the repo name as a heading and the block above.
|
|
100
|
+
|
|
101
|
+
## Step 5: Register in Global Index
|
|
102
|
+
|
|
103
|
+
Read `~/.claude/global-state.md`. If the current repo is NOT in the Active Projects table, add a row:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
| [Project Name] | [full repo path] | New — just initialized | TBD |
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Add the repo's state files to the State Files table if missing:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
| `[full path]/.claude/team-state.md` | Shared team context for this repo |
|
|
113
|
+
| `[full path]/.claude/personal-state.md` | Personal context for this repo (gitignored) |
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Step 6: Report
|
|
117
|
+
|
|
118
|
+
Tell the user:
|
|
119
|
+
- `.claude/team-state.md` — created or already existed (committed to git, shared with team)
|
|
120
|
+
- `.claude/personal-state.md` — created or already existed (gitignored, personal only)
|
|
121
|
+
- `.gitignore` — updated or already correct
|
|
122
|
+
- `CLAUDE.md` — protocol appended or already present
|
|
123
|
+
- `global-state.md` — repo registered or already listed
|
|
124
|
+
|
|
125
|
+
**If they haven't set up team context yet**, mention:
|
|
126
|
+
"Run `/init-team` to set up team-level context sharing — shared journals, weekly digests
|
|
127
|
+
(Slack + Notion), and product state for your PM."
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Set up Meridian team context for your organization. Interactive walkthrough that creates a team context repo, configures Slack digests, sets up Notion integration, and initializes product-state.md for a pilot repo. Run once per team.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Initialize Team Context (Meridian)
|
|
6
|
+
|
|
7
|
+
Interactive setup for team-level context sharing. Walk the user through each step,
|
|
8
|
+
asking questions as needed. Skip steps that are already done (idempotent).
|
|
9
|
+
|
|
10
|
+
## Prerequisites Check
|
|
11
|
+
|
|
12
|
+
Before starting, verify:
|
|
13
|
+
1. Skip Tissue is installed (`~/.claude/skip-tissue/` exists)
|
|
14
|
+
2. User has `gh` CLI authenticated (`gh auth status`)
|
|
15
|
+
3. User is in a git repo within an organization (or can specify one)
|
|
16
|
+
4. Ask: **"Which GitHub org will host the team context repo?"** (e.g., `HopSkipInc`)
|
|
17
|
+
|
|
18
|
+
If any prerequisite fails, tell the user what's needed and stop.
|
|
19
|
+
|
|
20
|
+
## Step 1: Team Context Repo
|
|
21
|
+
|
|
22
|
+
This repo holds shared journals, strategy state, digest archives, and the GitHub
|
|
23
|
+
Action that generates digests.
|
|
24
|
+
|
|
25
|
+
Ask: **"Do you already have a team context repo for shared journals and digests? If so, what's the repo name? If not, I'll help you create one."**
|
|
26
|
+
|
|
27
|
+
### If creating new:
|
|
28
|
+
|
|
29
|
+
Ask: **"What should the repo be called?"** Suggest: `<org>/engineering-context`
|
|
30
|
+
|
|
31
|
+
Guide the user:
|
|
32
|
+
```
|
|
33
|
+
gh repo create <org>/<repo-name> --private --description "Team decision trail — journals, digests, strategy (powered by Meridian)"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Then clone it and create the initial structure:
|
|
37
|
+
```
|
|
38
|
+
<repo>/
|
|
39
|
+
README.md # Brief explanation of what this repo is
|
|
40
|
+
strategy-state.md # CTO strategy (from templates/strategy-state.md)
|
|
41
|
+
journals/ # One subdirectory per team member
|
|
42
|
+
<username>/ # Journal files sync here from each person's local
|
|
43
|
+
digests/ # Archive of generated digests
|
|
44
|
+
.github/workflows/ # Digest generation (added in Step 2)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Create `README.md` with:
|
|
48
|
+
```markdown
|
|
49
|
+
# Team Context
|
|
50
|
+
|
|
51
|
+
Shared decision trail for [team name]. Powered by [Meridian](https://github.com/leizerowicz/skip-tissue).
|
|
52
|
+
|
|
53
|
+
## What's here
|
|
54
|
+
|
|
55
|
+
- `strategy-state.md` — Strategic direction, research, prototypes, technology bets
|
|
56
|
+
- `journals/` — AI session journals from each team member (auto-synced)
|
|
57
|
+
- `digests/` — Weekly digest archives
|
|
58
|
+
- `.github/workflows/` — Automated digest generation
|
|
59
|
+
|
|
60
|
+
## How it works
|
|
61
|
+
|
|
62
|
+
Team members use Skip Tissue in their daily AI-assisted development sessions.
|
|
63
|
+
Journals capture what was done, what was decided, what was discovered, and what drifted.
|
|
64
|
+
Weekly digests aggregate this into views for engineering, product, and strategy.
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Create `strategy-state.md` from the strategy-state template in this repo's
|
|
68
|
+
`templates/strategy-state.md`. Fill in today's date. Ask the user to provide
|
|
69
|
+
a brief summary of current strategic direction (or leave placeholder comments).
|
|
70
|
+
|
|
71
|
+
Create the `journals/` directory with a `.gitkeep` file.
|
|
72
|
+
Create the `digests/` directory with a `.gitkeep` file.
|
|
73
|
+
|
|
74
|
+
Commit and push the initial structure.
|
|
75
|
+
|
|
76
|
+
### If existing:
|
|
77
|
+
|
|
78
|
+
Clone or pull the repo. Verify it has `journals/` and `digests/` directories.
|
|
79
|
+
Create them if missing.
|
|
80
|
+
|
|
81
|
+
Store the team context repo path for later steps. Record it in `~/.claude/global-state.md`
|
|
82
|
+
in the Memory Files table:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
| `meridian-team-context.md` | team context, journals, digests, meridian | Team context repo location and configuration |
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Create `~/.claude/memory/meridian-team-context.md` with:
|
|
89
|
+
```markdown
|
|
90
|
+
# Meridian Team Context
|
|
91
|
+
|
|
92
|
+
> Load this file when: team context, journals, digests, meridian, init-team
|
|
93
|
+
|
|
94
|
+
## Team Context Repo
|
|
95
|
+
- Org: <org>
|
|
96
|
+
- Repo: <org>/<repo-name>
|
|
97
|
+
- Local path: <path>
|
|
98
|
+
|
|
99
|
+
## Integrations Configured
|
|
100
|
+
- Slack webhook: [yes/no — URL stored in repo secret]
|
|
101
|
+
- Notion: [yes/no — page ID]
|
|
102
|
+
|
|
103
|
+
## Team Members
|
|
104
|
+
- <list of usernames with journal directories>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Step 2: Slack Integration
|
|
108
|
+
|
|
109
|
+
Ask: **"Do you want weekly digests posted to Slack? You'll need a Slack Incoming Webhook URL. If you have one, paste it. If not, I can walk you through creating one."**
|
|
110
|
+
|
|
111
|
+
### If they need help creating a webhook:
|
|
112
|
+
1. Go to https://api.slack.com/apps → Create New App → From Scratch
|
|
113
|
+
2. Name it "Meridian Digests" (or team preference), select workspace
|
|
114
|
+
3. Features → Incoming Webhooks → Activate
|
|
115
|
+
4. Add New Webhook to Workspace → Select channel (suggest `#engineering`)
|
|
116
|
+
5. Copy the webhook URL
|
|
117
|
+
|
|
118
|
+
### Once they have the URL:
|
|
119
|
+
|
|
120
|
+
Store it as a GitHub repo secret (NOT in plain text):
|
|
121
|
+
```
|
|
122
|
+
gh secret set SLACK_WEBHOOK_URL --repo <org>/<team-context-repo> --body "<webhook-url>"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Ask: **"Which Slack channel(s) should receive digests?"**
|
|
126
|
+
Suggest defaults:
|
|
127
|
+
- Engineering digest → `#engineering`
|
|
128
|
+
- PM digest → `#product` (or the same channel if team is small)
|
|
129
|
+
- Strategy digest → `#leadership` (or skip if CTO just reads the Notion page)
|
|
130
|
+
|
|
131
|
+
Record the channel configuration in `meridian-team-context.md`.
|
|
132
|
+
|
|
133
|
+
### Create the GitHub Action:
|
|
134
|
+
|
|
135
|
+
Create `.github/workflows/weekly-digest.yml` in the team context repo:
|
|
136
|
+
|
|
137
|
+
```yaml
|
|
138
|
+
name: Weekly Digest
|
|
139
|
+
|
|
140
|
+
on:
|
|
141
|
+
schedule:
|
|
142
|
+
- cron: '0 10 * * 1' # Monday 10:00 UTC (adjust for timezone)
|
|
143
|
+
workflow_dispatch: # Manual trigger for testing
|
|
144
|
+
|
|
145
|
+
jobs:
|
|
146
|
+
digest:
|
|
147
|
+
runs-on: ubuntu-latest
|
|
148
|
+
steps:
|
|
149
|
+
- uses: actions/checkout@v4
|
|
150
|
+
|
|
151
|
+
- name: Install Skip Tissue
|
|
152
|
+
run: |
|
|
153
|
+
curl -fsSL https://raw.githubusercontent.com/leizerowicz/skip-tissue/main/install.sh | bash
|
|
154
|
+
|
|
155
|
+
- name: Generate engineering digest
|
|
156
|
+
run: |
|
|
157
|
+
~/.claude/skip-tissue/journal-summary.sh \
|
|
158
|
+
--team journals \
|
|
159
|
+
--last-week \
|
|
160
|
+
--format markdown \
|
|
161
|
+
> digests/engineering-$(date +%Y-%m-%d).md
|
|
162
|
+
|
|
163
|
+
- name: Post to Slack
|
|
164
|
+
if: env.SLACK_WEBHOOK_URL != ''
|
|
165
|
+
env:
|
|
166
|
+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
|
167
|
+
run: |
|
|
168
|
+
DIGEST=$(cat digests/engineering-$(date +%Y-%m-%d).md | head -c 3000)
|
|
169
|
+
curl -X POST "$SLACK_WEBHOOK_URL" \
|
|
170
|
+
-H 'Content-type: application/json' \
|
|
171
|
+
-d "$(jq -n --arg text "$DIGEST" '{text: $text}')"
|
|
172
|
+
|
|
173
|
+
- name: Archive digest
|
|
174
|
+
run: |
|
|
175
|
+
git config user.name "Meridian Bot"
|
|
176
|
+
git config user.email "meridian-bot@users.noreply.github.com"
|
|
177
|
+
git add digests/
|
|
178
|
+
git diff --cached --quiet || git commit -m "Weekly digest $(date +%Y-%m-%d)"
|
|
179
|
+
git push
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Tell the user: **"You can test the digest manually: go to the Actions tab in the team context repo and run the 'Weekly Digest' workflow."**
|
|
183
|
+
|
|
184
|
+
## Step 3: Notion Integration
|
|
185
|
+
|
|
186
|
+
Ask: **"Do you want digests and product context visible in Notion? This creates a shared Notion page your PM and team can browse."**
|
|
187
|
+
|
|
188
|
+
### If yes:
|
|
189
|
+
|
|
190
|
+
Ask: **"What Notion workspace should I create the Meridian pages in? I can search for existing pages or create a new top-level page."**
|
|
191
|
+
|
|
192
|
+
Use the Notion MCP tools to:
|
|
193
|
+
|
|
194
|
+
1. **Create a top-level page**: "Meridian — [Team Name]"
|
|
195
|
+
- Use `mcp__notion__notion-create-pages` or the Claude.ai Notion tools
|
|
196
|
+
|
|
197
|
+
2. **Create child pages**:
|
|
198
|
+
- "Weekly Digests" — will hold one child page per week
|
|
199
|
+
- "Product State" — browseable product intent (mirrors product-state.md files)
|
|
200
|
+
- "Decisions Log" — searchable history of product decisions
|
|
201
|
+
- "Strategy" — mirrors strategy-state.md
|
|
202
|
+
|
|
203
|
+
3. For now, note the page IDs. Full Notion sync (automated posting of digests to
|
|
204
|
+
Notion pages) will be added as a GitHub Action step later. For the dogfood phase,
|
|
205
|
+
digests can be manually pasted or the CTO can update Notion from their session.
|
|
206
|
+
|
|
207
|
+
Record the Notion page IDs in `meridian-team-context.md`.
|
|
208
|
+
|
|
209
|
+
Tell the user: **"Notion pages created. For now, digests will post to Slack automatically. Notion gets updated when you or a team member copies the digest over, or we can automate that next."**
|
|
210
|
+
|
|
211
|
+
## Step 4: Product State for Pilot Repo
|
|
212
|
+
|
|
213
|
+
Ask: **"Which repo should we set up product-state.md for first? I'll create the PM intent layer so engineering sessions have product context."**
|
|
214
|
+
|
|
215
|
+
Navigate to that repo (or confirm we're already in it).
|
|
216
|
+
|
|
217
|
+
Create `.claude/product-state.md` using the template from `templates/product-state.md`.
|
|
218
|
+
|
|
219
|
+
Walk through filling it in interactively:
|
|
220
|
+
|
|
221
|
+
1. Ask: **"Who's the PM for this repo?"** → record in team-state.md Signal Routing
|
|
222
|
+
2. Ask: **"In one or two sentences, what is this repo building and for whom?"** → fill "What We're Building"
|
|
223
|
+
3. Ask: **"Why is this the priority right now?"** → fill "Why This, Why Now"
|
|
224
|
+
4. Ask: **"How will you know it's working? What does success look like in user terms?"** → fill "Success Criteria"
|
|
225
|
+
5. Ask: **"Any scope constraints or product decisions that engineering should know?"** → fill "Scope & Constraints"
|
|
226
|
+
6. Ask: **"Any open questions that haven't been decided yet?"** → fill "Open Questions"
|
|
227
|
+
|
|
228
|
+
If the user doesn't know answers to some questions, leave the placeholder comments.
|
|
229
|
+
Those fields will get filled by the PM in a future session.
|
|
230
|
+
|
|
231
|
+
## Step 5: Update Team State
|
|
232
|
+
|
|
233
|
+
If `.claude/team-state.md` exists in the pilot repo, update the Signal Routing section:
|
|
234
|
+
|
|
235
|
+
```markdown
|
|
236
|
+
## Signal Routing
|
|
237
|
+
Bugs & feedback: [answer from user or "TBD"]
|
|
238
|
+
PM contact: [PM name from Step 4]
|
|
239
|
+
CTO/Strategy contact: [user's name or "TBD"]
|
|
240
|
+
QA process: [answer from user or "TBD"]
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
If it doesn't exist, create it from `templates/team-state.md` and fill in what we know.
|
|
244
|
+
|
|
245
|
+
## Step 6: Journal Sync Configuration
|
|
246
|
+
|
|
247
|
+
Each team member's journals need to flow to the team context repo. Set up the sync
|
|
248
|
+
for the current user.
|
|
249
|
+
|
|
250
|
+
Create a journal sync script at `~/.claude/hooks/sync-team-journal.sh`:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
#!/usr/bin/env bash
|
|
254
|
+
# Meridian — Sync journals to team context repo
|
|
255
|
+
# Called by session-end hook after local journal is updated
|
|
256
|
+
|
|
257
|
+
set -euo pipefail
|
|
258
|
+
|
|
259
|
+
TEAM_REPO="<path-to-team-context-repo>"
|
|
260
|
+
USER_DIR="$TEAM_REPO/journals/$(whoami)"
|
|
261
|
+
|
|
262
|
+
# Only sync if team repo exists and has journals dir
|
|
263
|
+
[ -d "$TEAM_REPO/journals" ] || exit 0
|
|
264
|
+
|
|
265
|
+
mkdir -p "$USER_DIR"
|
|
266
|
+
|
|
267
|
+
# Copy journal files (not personal state)
|
|
268
|
+
JOURNAL_DIR=""
|
|
269
|
+
if [ -d "$HOME/.claude/memory/journal" ]; then
|
|
270
|
+
JOURNAL_DIR="$HOME/.claude/memory/journal"
|
|
271
|
+
elif [ -d "$HOME/.ai-memory/memory/journal" ]; then
|
|
272
|
+
JOURNAL_DIR="$HOME/.ai-memory/memory/journal"
|
|
273
|
+
fi
|
|
274
|
+
|
|
275
|
+
[ -z "$JOURNAL_DIR" ] && exit 0
|
|
276
|
+
|
|
277
|
+
# Sync only .md files from journal dir
|
|
278
|
+
rsync -a --include='*.md' --exclude='*' "$JOURNAL_DIR/" "$USER_DIR/"
|
|
279
|
+
|
|
280
|
+
# Commit and push if there are changes
|
|
281
|
+
cd "$TEAM_REPO"
|
|
282
|
+
git add "journals/$(whoami)/" 2>/dev/null || true
|
|
283
|
+
if ! git diff --cached --quiet 2>/dev/null; then
|
|
284
|
+
git commit -m "Journal sync: $(whoami) $(date +%Y-%m-%d)" --quiet
|
|
285
|
+
git push --quiet 2>/dev/null || true
|
|
286
|
+
fi
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Make it executable. Tell the user to add this to their session-end hook in
|
|
290
|
+
`~/.claude/settings.json` (or integrate with their existing backup hook).
|
|
291
|
+
|
|
292
|
+
Provide the exact settings.json snippet to add.
|
|
293
|
+
|
|
294
|
+
## Step 7: Onboarding Instructions
|
|
295
|
+
|
|
296
|
+
Generate a message the user can send to their team. Ask: **"What's the best way to share setup instructions with your team? Slack message? Notion page?"**
|
|
297
|
+
|
|
298
|
+
Draft the onboarding message:
|
|
299
|
+
|
|
300
|
+
```
|
|
301
|
+
Hey team — I've set up Meridian for our engineering context.
|
|
302
|
+
|
|
303
|
+
**What it does**: Captures the decisions, discoveries, and context from your AI-assisted
|
|
304
|
+
sessions and generates weekly digests so everyone stays oriented.
|
|
305
|
+
|
|
306
|
+
**What you need to do**:
|
|
307
|
+
1. Install Skip Tissue (30 seconds):
|
|
308
|
+
Open Claude Code and paste:
|
|
309
|
+
```
|
|
310
|
+
curl -fsSL https://raw.githubusercontent.com/leizerowicz/skip-tissue/main/install.sh | bash
|
|
311
|
+
```
|
|
312
|
+
2. In any repo you work in, run `/init-memory` to set up context tracking
|
|
313
|
+
3. That's it. Work normally. Claude will capture context at the end of each session.
|
|
314
|
+
|
|
315
|
+
**What you'll see**:
|
|
316
|
+
- Monday digest in #[channel] showing what shipped, what drifted, and what was discovered
|
|
317
|
+
- Product context in your sessions (so your AI knows *why* you're building what you're building)
|
|
318
|
+
|
|
319
|
+
Questions? Ask [user's name].
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Step 8: Report
|
|
323
|
+
|
|
324
|
+
Summarize everything that was set up:
|
|
325
|
+
|
|
326
|
+
- Team context repo: `<org>/<repo>` — created/configured
|
|
327
|
+
- Slack: webhook configured, posting to `#<channel>` on Mondays
|
|
328
|
+
- Notion: pages created at [page link] (or skipped)
|
|
329
|
+
- Product state: initialized in `<pilot-repo>` with PM = `<name>`
|
|
330
|
+
- Journal sync: configured for current user
|
|
331
|
+
- Onboarding: message drafted for team
|
|
332
|
+
|
|
333
|
+
Tell the user: **"Team context is set up. Send the onboarding message to your team,
|
|
334
|
+
then run the GitHub Action manually to test the first digest. Once journals start
|
|
335
|
+
flowing, you'll see the first real digest next Monday."**
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Generate a journal summary — weekly digest, drift detection, and recurring lessons from AI session journals.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Skip Tissue — Journal Summary
|
|
6
|
+
|
|
7
|
+
Aggregate AI session journal entries into a weekly digest with drift detection and recurring lesson extraction.
|
|
8
|
+
|
|
9
|
+
## Step 1: Run journal-summary.sh
|
|
10
|
+
|
|
11
|
+
Look for `~/.claude/skip-tissue/journal-summary.sh`. If found, run it based on what the user asked:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# This week (default)
|
|
15
|
+
bash ~/.claude/skip-tissue/journal-summary.sh
|
|
16
|
+
|
|
17
|
+
# Last week
|
|
18
|
+
bash ~/.claude/skip-tissue/journal-summary.sh --last-week
|
|
19
|
+
|
|
20
|
+
# Specific date range
|
|
21
|
+
bash ~/.claude/skip-tissue/journal-summary.sh --from 2026-02-01 --to 2026-02-28
|
|
22
|
+
|
|
23
|
+
# All history as Markdown (good for Notion/GitHub)
|
|
24
|
+
bash ~/.claude/skip-tissue/journal-summary.sh --all --format markdown
|
|
25
|
+
|
|
26
|
+
# Team aggregate (each subdir is a contributor's journal dir)
|
|
27
|
+
bash ~/.claude/skip-tissue/journal-summary.sh --team ~/team-journals
|
|
28
|
+
|
|
29
|
+
# Custom journal directory
|
|
30
|
+
bash ~/.claude/skip-tissue/journal-summary.sh --dir ~/.ai-memory/memory/journal
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Step 2: If journal-summary.sh is not installed
|
|
34
|
+
|
|
35
|
+
Run setup.sh with `--update` to install it:
|
|
36
|
+
```bash
|
|
37
|
+
bash ~/repos/greg/skip-tissue/setup.sh --tool claude-code --update
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Or install manually:
|
|
41
|
+
```bash
|
|
42
|
+
cp ~/repos/greg/skip-tissue/journal-summary.sh ~/.claude/skip-tissue/journal-summary.sh
|
|
43
|
+
chmod +x ~/.claude/skip-tissue/journal-summary.sh
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Step 3: Interpret results
|
|
47
|
+
|
|
48
|
+
The summary surfaces four key sections:
|
|
49
|
+
|
|
50
|
+
- **Sessions by Repo** — Every session in the period, grouped by repo. ⚠ marks drifted sessions.
|
|
51
|
+
- **Drift Log** — Sessions where "On track?" indicated scope creep or goal drift. Review these to identify recurring blockers.
|
|
52
|
+
- **Recurring Lessons** — Lessons that appeared in 2+ sessions. These are strong candidates to add to `CLAUDE.md` or `global-state.md` so the AI learns from them.
|
|
53
|
+
- **All Lessons** — Full lesson archive for the period, with ♻ markers on recurring ones.
|
|
54
|
+
|
|
55
|
+
## Options quick reference
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
--dir <path> Journal directory (auto-detects ~/.claude or ~/.ai-memory)
|
|
59
|
+
--team <path> Team mode: each subdirectory is a contributor's journal dir
|
|
60
|
+
--week This week Mon–Sun (default)
|
|
61
|
+
--last-week Last week Mon–Sun
|
|
62
|
+
--from <YYYY-MM-DD> Start date
|
|
63
|
+
--to <YYYY-MM-DD> End date (default: today)
|
|
64
|
+
--all All available journal files
|
|
65
|
+
--format markdown Output as Markdown instead of plain text
|
|
66
|
+
```
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Skip Tissue — Anti-Drift Hook for Claude Code
|
|
3
|
+
# Runs on SessionStart. Warns when a repo's .claude/state.md is newer than
|
|
4
|
+
# ~/.claude/global-state.md, indicating the global Active Projects table
|
|
5
|
+
# may be stale for this repo.
|
|
6
|
+
#
|
|
7
|
+
# Install: copy to ~/.claude/hooks/check-global-state.sh
|
|
8
|
+
# Register: add to ~/.claude/settings.json (see settings.json in this directory)
|
|
9
|
+
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
GLOBAL_STATE="$HOME/.claude/global-state.md"
|
|
13
|
+
# Try team-state.md first (new split convention), fall back to state.md
|
|
14
|
+
REPO_STATE=".claude/team-state.md"
|
|
15
|
+
[ -f "$REPO_STATE" ] || REPO_STATE=".claude/state.md"
|
|
16
|
+
|
|
17
|
+
# Extract "Last updated: YYYY-MM-DD" from a file
|
|
18
|
+
get_date() {
|
|
19
|
+
grep -m1 '^Last updated:' "$1" 2>/dev/null | sed 's/^Last updated: *//; s/\r//' || echo ""
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
# --- Check current repo ---
|
|
23
|
+
if [ -f "$REPO_STATE" ]; then
|
|
24
|
+
REPO_DATE=$(get_date "$REPO_STATE")
|
|
25
|
+
GLOBAL_DATE=$(get_date "$GLOBAL_STATE")
|
|
26
|
+
|
|
27
|
+
if [ -n "$REPO_DATE" ] && [ -n "$GLOBAL_DATE" ]; then
|
|
28
|
+
if [[ "$REPO_DATE" > "$GLOBAL_DATE" ]]; then
|
|
29
|
+
REPO_NAME=$(basename "$(git -C . rev-parse --show-toplevel 2>/dev/null || pwd)")
|
|
30
|
+
STATE_FILE=$(basename "$REPO_STATE")
|
|
31
|
+
echo "⚠️ STALE GLOBAL STATE: ${REPO_NAME}/.claude/${STATE_FILE} was updated ${REPO_DATE} but ~/.claude/global-state.md was last updated ${GLOBAL_DATE}."
|
|
32
|
+
echo "ACTION REQUIRED: Update the Active Projects row for '${REPO_NAME}' in ~/.claude/global-state.md before proceeding."
|
|
33
|
+
fi
|
|
34
|
+
fi
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# --- Scan all repos for broader staleness ---
|
|
38
|
+
# Scan roots: colon-separated list of directories to search for repo state files.
|
|
39
|
+
# Override by setting AI_MEMORY_SCAN_ROOTS in your environment (colon-separated).
|
|
40
|
+
# Default: $HOME/repos:$HOME/code:$HOME/dev:$HOME/projects
|
|
41
|
+
IFS=: read -ra SCAN_ROOT_ARRAY <<< "${AI_MEMORY_SCAN_ROOTS:-$HOME/repos:$HOME/code:$HOME/dev:$HOME/projects}"
|
|
42
|
+
|
|
43
|
+
STALE_REPOS=()
|
|
44
|
+
GLOBAL_DATE=$(get_date "$GLOBAL_STATE")
|
|
45
|
+
|
|
46
|
+
if [ -n "$GLOBAL_DATE" ]; then
|
|
47
|
+
for root in "${SCAN_ROOT_ARRAY[@]}"; do
|
|
48
|
+
[ -d "$root" ] || continue
|
|
49
|
+
while IFS= read -r state_file; do
|
|
50
|
+
FILE_DATE=$(get_date "$state_file")
|
|
51
|
+
if [ -n "$FILE_DATE" ] && [[ "$FILE_DATE" > "$GLOBAL_DATE" ]]; then
|
|
52
|
+
rel="${state_file#$HOME/}"
|
|
53
|
+
repo_name="${rel%/.claude/team-state.md}"
|
|
54
|
+
repo_name="${repo_name%/.claude/state.md}"
|
|
55
|
+
STALE_REPOS+=("$repo_name ($FILE_DATE)")
|
|
56
|
+
fi
|
|
57
|
+
done < <(find "$root" \( -path '*/.claude/state.md' -o -path '*/.claude/team-state.md' \) -not -path '*/node_modules/*' 2>/dev/null)
|
|
58
|
+
done
|
|
59
|
+
|
|
60
|
+
if [ ${#STALE_REPOS[@]} -gt 0 ]; then
|
|
61
|
+
echo ""
|
|
62
|
+
echo "📋 Other repos with state newer than global-state.md (${GLOBAL_DATE}):"
|
|
63
|
+
for r in "${STALE_REPOS[@]}"; do
|
|
64
|
+
echo " - $r"
|
|
65
|
+
done
|
|
66
|
+
echo "Consider updating their Active Projects rows when convenient."
|
|
67
|
+
fi
|
|
68
|
+
fi
|