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.
Files changed (33) hide show
  1. package/BOOTSTRAP_PROMPT.md +110 -0
  2. package/README.md +344 -0
  3. package/backup/hooks/session-end.sh +44 -0
  4. package/backup/hooks/session-start.sh +37 -0
  5. package/backup/setup.sh +156 -0
  6. package/bin/meridian.js +100 -0
  7. package/doctor.sh +173 -0
  8. package/install.sh +62 -0
  9. package/journal-summary.sh +577 -0
  10. package/package.json +42 -0
  11. package/setup.sh +407 -0
  12. package/specializations/claude-code/CLAUDE.md-global-fragment.md +52 -0
  13. package/specializations/claude-code/CLAUDE.md-repo-fragment.md +16 -0
  14. package/specializations/claude-code/README.md +96 -0
  15. package/specializations/claude-code/commands/doctor.md +31 -0
  16. package/specializations/claude-code/commands/init-memory.md +127 -0
  17. package/specializations/claude-code/commands/init-team.md +335 -0
  18. package/specializations/claude-code/commands/journal.md +66 -0
  19. package/specializations/claude-code/hooks/check-global-state.sh +68 -0
  20. package/specializations/claude-code/settings.json +10 -0
  21. package/specializations/cursor/README.md +112 -0
  22. package/specializations/cursor/global-rule.mdc +53 -0
  23. package/specializations/cursor/repo-rule.mdc +25 -0
  24. package/specializations/generic/README.md +47 -0
  25. package/templates/global.md +73 -0
  26. package/templates/memory-file.md +18 -0
  27. package/templates/personal-state.md +14 -0
  28. package/templates/product-state.md +39 -0
  29. package/templates/repo-state.md +18 -0
  30. package/templates/session-protocol-fragment.md +46 -0
  31. package/templates/strategy-state.md +37 -0
  32. package/templates/team-state.md +29 -0
  33. 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
@@ -0,0 +1,10 @@
1
+ {
2
+ "hooks": {
3
+ "SessionStart": [
4
+ {
5
+ "type": "command",
6
+ "command": "bash ~/.claude/hooks/check-global-state.sh"
7
+ }
8
+ ]
9
+ }
10
+ }