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,100 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { execSync, spawnSync } = require('child_process');
4
+ const path = require('path');
5
+ const fs = require('fs');
6
+
7
+ const ROOT = path.join(__dirname, '..');
8
+ const COMMANDS = {
9
+ init: {
10
+ desc: 'Install Meridian for your AI tool (Claude Code, Cursor, or generic)',
11
+ run: (args) => {
12
+ const hasToolFlag = args.some((a) => a === '--tool' || a.startsWith('--tool='));
13
+ const toolArgs = hasToolFlag ? args : ['--tool', 'claude-code', ...args];
14
+ spawn('bash', [path.join(ROOT, 'setup.sh'), ...toolArgs]);
15
+ },
16
+ },
17
+ 'init-cursor': {
18
+ desc: 'Install Meridian for Cursor',
19
+ run: (args) => {
20
+ spawn('bash', [path.join(ROOT, 'setup.sh'), '--tool', 'cursor', ...args]);
21
+ },
22
+ },
23
+ update: {
24
+ desc: 'Update Meridian to latest version (re-runs setup in update mode)',
25
+ run: (args) => {
26
+ const tool = args.includes('--tool') ? args : ['--tool', 'claude-code', ...args];
27
+ spawn('bash', [path.join(ROOT, 'setup.sh'), '--update', ...tool]);
28
+ },
29
+ },
30
+ digest: {
31
+ desc: 'Generate a journal digest (weekly summary of AI sessions)',
32
+ run: (args) => {
33
+ spawn('bash', [path.join(ROOT, 'journal-summary.sh'), ...args]);
34
+ },
35
+ },
36
+ doctor: {
37
+ desc: 'Check your Meridian installation for issues',
38
+ run: (args) => {
39
+ spawn('bash', [path.join(ROOT, 'doctor.sh'), ...args]);
40
+ },
41
+ },
42
+ help: {
43
+ desc: 'Show this help message',
44
+ run: () => showHelp(),
45
+ },
46
+ };
47
+
48
+ function showHelp() {
49
+ console.log('');
50
+ console.log('Meridian — Team decision trail for AI-assisted development');
51
+ console.log('');
52
+ console.log('Usage: meridian <command> [options]');
53
+ console.log('');
54
+ console.log('Commands:');
55
+ for (const [name, cmd] of Object.entries(COMMANDS)) {
56
+ console.log(` ${name.padEnd(16)} ${cmd.desc}`);
57
+ }
58
+ console.log('');
59
+ console.log('Getting started:');
60
+ console.log(' npx meridian-dev init Install for Claude Code');
61
+ console.log(' npx meridian-dev init-cursor Install for Cursor');
62
+ console.log('');
63
+ console.log('In a Claude Code session:');
64
+ console.log(' /init-memory Set up memory for current repo');
65
+ console.log(' /init-team Set up team context (journals, digests, Notion)');
66
+ console.log(' /journal View your session journal digest');
67
+ console.log(' /doctor Check installation health');
68
+ console.log('');
69
+ console.log('Ongoing:');
70
+ console.log(' npx meridian-dev digest This week\'s digest');
71
+ console.log(' npx meridian-dev digest --last-week Last week\'s digest');
72
+ console.log(' npx meridian-dev digest --team <path> Team digest from shared journals');
73
+ console.log('');
74
+ }
75
+
76
+ function spawn(cmd, args) {
77
+ const result = spawnSync(cmd, args, {
78
+ stdio: 'inherit',
79
+ env: { ...process.env },
80
+ });
81
+ if (result.error) {
82
+ console.error(`Error: ${result.error.message}`);
83
+ process.exit(1);
84
+ }
85
+ process.exit(result.status || 0);
86
+ }
87
+
88
+ // --- Main ---
89
+
90
+ const args = process.argv.slice(2);
91
+ const command = args[0] || 'help';
92
+ const commandArgs = args.slice(1);
93
+
94
+ if (COMMANDS[command]) {
95
+ COMMANDS[command].run(commandArgs);
96
+ } else {
97
+ console.error(`Unknown command: ${command}`);
98
+ console.error('Run "meridian help" for available commands.');
99
+ process.exit(1);
100
+ }
package/doctor.sh ADDED
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env bash
2
+ # Skip Tissue — Doctor
3
+ # Validates that the memory system is correctly installed and functioning.
4
+ # Usage: bash doctor.sh [--verbose]
5
+
6
+ set -euo pipefail
7
+
8
+ VERBOSE=false
9
+ [[ "${1:-}" == "--verbose" ]] && VERBOSE=true
10
+
11
+ GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; RESET='\033[0m'
12
+
13
+ ok() { echo -e "${GREEN}✓${RESET} $1"; }
14
+ warn() { echo -e "${YELLOW}⚠${RESET} $1"; }
15
+ err() { echo -e "${RED}✗${RESET} $1"; }
16
+ info() { echo " $1"; }
17
+
18
+ ISSUES=0
19
+
20
+ check_hook_registered() {
21
+ echo ""
22
+ echo "Hook registration"
23
+ local SETTINGS="$HOME/.claude/settings.json"
24
+ if [ ! -f "$SETTINGS" ]; then
25
+ err "settings.json not found — hook is not registered"
26
+ info "Run: bash setup.sh --tool claude-code"
27
+ ISSUES=$((ISSUES + 1))
28
+ return
29
+ fi
30
+ if grep -q "check-global-state" "$SETTINGS" 2>/dev/null; then
31
+ ok "SessionStart hook registered in settings.json"
32
+ else
33
+ err "Hook not registered in settings.json"
34
+ info "Re-run setup.sh to merge the hook"
35
+ ISSUES=$((ISSUES + 1))
36
+ fi
37
+
38
+ if [ -f "$HOME/.claude/hooks/check-global-state.sh" ]; then
39
+ ok "check-global-state.sh exists"
40
+ else
41
+ err "check-global-state.sh not found at ~/.claude/hooks/"
42
+ ISSUES=$((ISSUES + 1))
43
+ fi
44
+ }
45
+
46
+ check_global_state() {
47
+ echo ""
48
+ echo "Global state file"
49
+ local GLOBAL="$HOME/.claude/global-state.md"
50
+ if [ ! -f "$GLOBAL" ]; then
51
+ err "global-state.md not found at $GLOBAL"
52
+ info "Run: bash setup.sh --tool claude-code"
53
+ ISSUES=$((ISSUES + 1))
54
+ return
55
+ fi
56
+ ok "global-state.md exists"
57
+
58
+ # Check if it was updated recently
59
+ local LAST_UPDATED
60
+ LAST_UPDATED=$(grep -m1 '^Last updated:' "$GLOBAL" 2>/dev/null | sed 's/^Last updated: *//' || echo "")
61
+ if [ -n "$LAST_UPDATED" ]; then
62
+ if [[ "$LAST_UPDATED" < "$(date -d '7 days ago' +%Y-%m-%d 2>/dev/null || date -v-7d +%Y-%m-%d 2>/dev/null || echo '0000-00-00')" ]]; then
63
+ warn "global-state.md last updated $LAST_UPDATED (>7 days ago)"
64
+ else
65
+ ok "global-state.md updated $LAST_UPDATED"
66
+ fi
67
+ else
68
+ warn "global-state.md has no 'Last updated:' line"
69
+ fi
70
+ }
71
+
72
+ check_backup() {
73
+ echo ""
74
+ echo "Backup status"
75
+ local LAST_PUSH="$HOME/.claude/.backup-last-push"
76
+ local LAST_ERROR="$HOME/.claude/.backup-last-error"
77
+
78
+ if [ ! -f "$HOME/.claude-backup/.git/config" ] 2>/dev/null && [ ! -f "$LAST_PUSH" ]; then
79
+ info "Backup not configured (optional — run backup/setup.sh <repo-url> to enable)"
80
+ return
81
+ fi
82
+
83
+ if [ -f "$LAST_ERROR" ]; then
84
+ warn "Backup: last push FAILED"
85
+ info "$(cat "$LAST_ERROR")"
86
+ ISSUES=$((ISSUES + 1))
87
+ elif [ -f "$LAST_PUSH" ]; then
88
+ local PUSH_TIME
89
+ PUSH_TIME=$(cat "$LAST_PUSH")
90
+ ok "Backup: last push $PUSH_TIME"
91
+ else
92
+ warn "Backup configured but no push record found"
93
+ fi
94
+ }
95
+
96
+ scan_repos() {
97
+ echo ""
98
+ echo "Repo state files"
99
+ local SCAN_ROOTS="${AI_MEMORY_SCAN_ROOTS:-$HOME/repos $HOME/code $HOME/dev $HOME/projects}"
100
+ local FOUND=0
101
+
102
+ for root in $SCAN_ROOTS; do
103
+ [ -d "$root" ] || continue
104
+ while IFS= read -r state_file; do
105
+ FOUND=$((FOUND + 1))
106
+ local rel="${state_file#$HOME/}"
107
+ local repo_name="${rel%/.claude/team-state.md}"
108
+ repo_name="${repo_name%/.claude/state.md}"
109
+ local LAST_UPDATED
110
+ LAST_UPDATED=$(grep -m1 '^Last updated:' "$state_file" 2>/dev/null | sed 's/^Last updated: *//' || echo "unknown")
111
+ ok "$repo_name (updated $LAST_UPDATED)"
112
+ done < <(find "$root" \( -path '*/.claude/state.md' -o -path '*/.claude/team-state.md' \) 2>/dev/null | sort)
113
+ done
114
+
115
+ if [ "$FOUND" -eq 0 ]; then
116
+ info "No repos with state.md found in: $SCAN_ROOTS"
117
+ info "Run /init-memory in a repo to initialize it"
118
+ fi
119
+ }
120
+
121
+ check_memory_files() {
122
+ echo ""
123
+ echo "Memory files"
124
+ local MEMORY_DIR="$HOME/.claude/memory"
125
+ if [ ! -d "$MEMORY_DIR" ]; then
126
+ warn "Memory directory not found: $MEMORY_DIR"
127
+ return
128
+ fi
129
+
130
+ local COUNT=0
131
+ while IFS= read -r f; do
132
+ COUNT=$((COUNT + 1))
133
+ local SIZE
134
+ SIZE=$(wc -c < "$f" 2>/dev/null || echo 0)
135
+ local SIZE_KB=$((SIZE / 1024))
136
+ local FNAME
137
+ FNAME=$(basename "$f")
138
+ if [ "$SIZE" -gt 8192 ]; then
139
+ warn "$FNAME (${SIZE_KB}KB) — exceeds recommended 8KB; consider summarizing"
140
+ else
141
+ [ "$VERBOSE" = true ] && ok "$FNAME (${SIZE_KB}KB)"
142
+ fi
143
+ done < <(find "$MEMORY_DIR" -name '*.md' -not -path '*/journal/*' 2>/dev/null | sort)
144
+
145
+ local JOURNAL_DIR="$MEMORY_DIR/journal"
146
+ if [ -d "$JOURNAL_DIR" ]; then
147
+ local JOURNAL_COUNT
148
+ JOURNAL_COUNT=$(find "$JOURNAL_DIR" -name '*.md' 2>/dev/null | wc -l)
149
+ ok "Journal: $JOURNAL_COUNT entries"
150
+ fi
151
+
152
+ [ "$COUNT" -gt 0 ] && ok "$COUNT memory file(s) found" || info "No memory files yet"
153
+ }
154
+
155
+ # Run checks
156
+ echo ""
157
+ echo "Skip Tissue — Doctor"
158
+ echo "══════════════════════"
159
+
160
+ check_hook_registered
161
+ check_global_state
162
+ check_backup
163
+ check_memory_files
164
+ scan_repos
165
+
166
+ echo ""
167
+ echo "══════════════════════"
168
+ if [ "$ISSUES" -eq 0 ]; then
169
+ echo -e "${GREEN}All checks passed${RESET}"
170
+ else
171
+ echo -e "${YELLOW}$ISSUES issue(s) found${RESET}"
172
+ exit 1
173
+ fi
package/install.sh ADDED
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env bash
2
+ # Skip Tissue — Installer
3
+ # Usage:
4
+ # curl -fsSL https://raw.githubusercontent.com/leizerowicz/skip-tissue/main/install.sh | bash
5
+ # ST_VERSION=v1.0.0 bash install.sh # Install specific version
6
+
7
+ set -euo pipefail
8
+
9
+ REPO="leizerowicz/skip-tissue"
10
+ VERSION="${ST_VERSION:-main}"
11
+ TMP_DIR="$(mktemp -d)"
12
+
13
+ cleanup() { rm -rf "$TMP_DIR"; }
14
+ trap cleanup EXIT
15
+
16
+ echo ""
17
+ echo "Skip Tissue — Installing${VERSION:+ (${VERSION})}..."
18
+ echo ""
19
+
20
+ # Download
21
+ if [ "$VERSION" = "main" ]; then
22
+ DOWNLOAD_URL="https://github.com/$REPO/archive/refs/heads/main.tar.gz"
23
+ ARCHIVE_NAME="skip-tissue-main"
24
+ else
25
+ DOWNLOAD_URL="https://github.com/$REPO/archive/refs/tags/${VERSION}.tar.gz"
26
+ ARCHIVE_NAME="skip-tissue-${VERSION#v}"
27
+ fi
28
+
29
+ ARCHIVE="$TMP_DIR/kit.tar.gz"
30
+ if ! curl -fsSL "$DOWNLOAD_URL" -o "$ARCHIVE"; then
31
+ echo ""
32
+ echo "Error: download failed."
33
+ if [ "$VERSION" != "main" ]; then
34
+ echo "Check that version '$VERSION' exists: https://github.com/$REPO/releases"
35
+ fi
36
+ exit 1
37
+ fi
38
+ tar -xz -C "$TMP_DIR" -f "$ARCHIVE"
39
+ KIT_DIR="$TMP_DIR/$ARCHIVE_NAME"
40
+
41
+ # Verify the kit downloaded correctly
42
+ if [ ! -f "$KIT_DIR/setup.sh" ]; then
43
+ echo "Error: download failed or unexpected archive structure"
44
+ exit 1
45
+ fi
46
+
47
+ # Run setup
48
+ bash "$KIT_DIR/setup.sh" --tool claude-code
49
+
50
+ # Keep the kit locally so doctor.sh and future updates are available
51
+ KIT_DEST="$HOME/.claude/skip-tissue"
52
+ rm -rf "$KIT_DEST"
53
+ cp -r "$KIT_DIR" "$KIT_DEST"
54
+
55
+ echo ""
56
+ echo "Installation complete."
57
+ [ "$VERSION" != "main" ] && echo "Version: $VERSION"
58
+ echo "Kit installed to: $KIT_DEST"
59
+ echo ""
60
+ echo "Next: run /init-memory in any Claude Code session to initialize a repo."
61
+ echo "To set up backup: tell Claude 'Set up backup using <your-private-repo-url>'"
62
+ echo ""