@pcircle/memesh 4.2.4 → 4.2.5

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.
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env bash
2
+ # upgrade-plugin.sh — one-liner upgrade for the Claude Code plugin install.
3
+ #
4
+ # Use:
5
+ # bash scripts/upgrade-plugin.sh
6
+ #
7
+ # What it does:
8
+ # 1. Fast-forwards the marketplace cache (~/.claude/plugins/marketplaces/pcircle-memesh)
9
+ # against origin.
10
+ # 2. Reads the new version from .claude-plugin/marketplace.json.
11
+ # 3. Stages a new install cache at ~/.claude/plugins/cache/pcircle-memesh/memesh/<new-version>/.
12
+ # 4. Installs runtime deps inside that cache (npm install --omit=dev).
13
+ # 5. Patches ~/.claude/plugins/installed_plugins.json to point at the
14
+ # new version + path.
15
+ # 6. Leaves the previous version on disk (you can delete it manually if you want).
16
+ #
17
+ # Why this exists:
18
+ # Claude Code's plugin marketplace pins versions at install time and
19
+ # does not auto-update. Without this script, every user on an old
20
+ # version has to uninstall + reinstall from the /plugin UI to pick
21
+ # up a new release — even for security advisories.
22
+
23
+ set -uo pipefail
24
+
25
+ MARKETPLACE_DIR="$HOME/.claude/plugins/marketplaces/pcircle-memesh"
26
+ INSTALL_REGISTRY="$HOME/.claude/plugins/installed_plugins.json"
27
+ CACHE_ROOT="$HOME/.claude/plugins/cache/pcircle-memesh/memesh"
28
+
29
+ # ─── Pre-flight ────────────────────────────────────────────────────────────
30
+ if [ ! -d "$MARKETPLACE_DIR" ]; then
31
+ echo "ERROR: marketplace cache not found at $MARKETPLACE_DIR" >&2
32
+ echo " Install the plugin from the Claude Code /plugin UI first." >&2
33
+ exit 1
34
+ fi
35
+ if [ ! -f "$INSTALL_REGISTRY" ]; then
36
+ echo "ERROR: installed_plugins.json not found at $INSTALL_REGISTRY" >&2
37
+ echo " Install the plugin from the Claude Code /plugin UI first." >&2
38
+ exit 1
39
+ fi
40
+ if ! command -v node >/dev/null 2>&1; then
41
+ echo "ERROR: node is not on PATH (needed to read/write JSON safely)." >&2
42
+ exit 1
43
+ fi
44
+ if ! command -v npm >/dev/null 2>&1; then
45
+ echo "ERROR: npm is not on PATH (needed to install runtime deps)." >&2
46
+ exit 1
47
+ fi
48
+ if ! command -v rsync >/dev/null 2>&1; then
49
+ echo "ERROR: rsync is not on PATH." >&2
50
+ exit 1
51
+ fi
52
+
53
+ # ─── 1. Refresh marketplace cache ─────────────────────────────────────────
54
+ echo "==> Fetching latest from marketplace origin..."
55
+ (
56
+ cd "$MARKETPLACE_DIR" || exit 1
57
+ CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo main)"
58
+ git fetch origin "$CURRENT_BRANCH" --quiet || {
59
+ echo "ERROR: git fetch failed in $MARKETPLACE_DIR" >&2
60
+ exit 1
61
+ }
62
+ git merge --ff-only "origin/$CURRENT_BRANCH" --quiet || {
63
+ echo "ERROR: marketplace cache has local commits — refusing fast-forward." >&2
64
+ echo " Reset it: cd $MARKETPLACE_DIR && git reset --hard origin/$CURRENT_BRANCH" >&2
65
+ exit 1
66
+ }
67
+ ) || exit 1
68
+
69
+ # ─── 2. Read new version ──────────────────────────────────────────────────
70
+ # Pass paths via env vars so bash variables never become JS string literals
71
+ # — quote-safety + injection-safety in one move. Same pattern as section 5.
72
+ NEW_VERSION="$(MARKETPLACE_DIR="$MARKETPLACE_DIR" node -e "
73
+ const fs = require('fs');
74
+ const p = process.env.MARKETPLACE_DIR + '/.claude-plugin/marketplace.json';
75
+ const j = JSON.parse(fs.readFileSync(p, 'utf8'));
76
+ const e = (j.plugins || []).find(x => x && x.name === 'memesh');
77
+ if (!e || typeof e.version !== 'string') { process.exit(2); }
78
+ process.stdout.write(e.version);
79
+ ")" || {
80
+ echo "ERROR: could not read memesh version from marketplace.json" >&2
81
+ exit 1
82
+ }
83
+
84
+ if ! [[ "$NEW_VERSION" =~ ^[0-9A-Za-z.+-]+$ ]]; then
85
+ echo "ERROR: marketplace.json reported an unsafe version string: $NEW_VERSION" >&2
86
+ exit 1
87
+ fi
88
+
89
+ echo "==> Target version: $NEW_VERSION"
90
+
91
+ CURRENT_VERSION="$(INSTALL_REGISTRY="$INSTALL_REGISTRY" node -e "
92
+ const fs = require('fs');
93
+ const j = JSON.parse(fs.readFileSync(process.env.INSTALL_REGISTRY, 'utf8'));
94
+ const entries = (j.plugins && j.plugins['memesh@pcircle-memesh']) || [];
95
+ if (entries.length === 0) { process.stdout.write('none'); process.exit(0); }
96
+ process.stdout.write(entries[0].version || 'unknown');
97
+ ")"
98
+
99
+ echo "==> Currently installed: $CURRENT_VERSION"
100
+
101
+ if [ "$CURRENT_VERSION" = "$NEW_VERSION" ]; then
102
+ echo "==> Already at $NEW_VERSION — nothing to do."
103
+ exit 0
104
+ fi
105
+
106
+ # ─── 3. Stage new install cache ───────────────────────────────────────────
107
+ NEW_INSTALL_PATH="$CACHE_ROOT/$NEW_VERSION"
108
+ echo "==> Staging $NEW_INSTALL_PATH..."
109
+ mkdir -p "$NEW_INSTALL_PATH"
110
+ rsync -a --delete \
111
+ --exclude 'node_modules' \
112
+ --exclude '.git' \
113
+ --exclude 'tests' \
114
+ --exclude 'benchmarks' \
115
+ --exclude 'docs/plans' \
116
+ "$MARKETPLACE_DIR/" "$NEW_INSTALL_PATH/" || {
117
+ echo "ERROR: rsync failed" >&2
118
+ exit 1
119
+ }
120
+
121
+ # ─── 4. Install runtime deps ──────────────────────────────────────────────
122
+ echo "==> Installing runtime deps (this may take a minute)..."
123
+ (
124
+ cd "$NEW_INSTALL_PATH" || exit 1
125
+ npm install --omit=dev --no-audit --no-fund --silent
126
+ ) || {
127
+ echo "ERROR: npm install failed in $NEW_INSTALL_PATH" >&2
128
+ exit 1
129
+ }
130
+
131
+ # ─── 5. Patch installed_plugins.json ─────────────────────────────────────
132
+ echo "==> Updating installed_plugins.json..."
133
+ NEW_INSTALL_PATH="$NEW_INSTALL_PATH" \
134
+ NEW_VERSION="$NEW_VERSION" \
135
+ INSTALL_REGISTRY="$INSTALL_REGISTRY" \
136
+ MARKETPLACE_DIR="$MARKETPLACE_DIR" \
137
+ node -e "
138
+ const fs = require('fs');
139
+ const path = process.env.INSTALL_REGISTRY;
140
+ const j = JSON.parse(fs.readFileSync(path, 'utf8'));
141
+ if (!j.plugins || !Array.isArray(j.plugins['memesh@pcircle-memesh'])) {
142
+ console.error('installed_plugins.json missing memesh@pcircle-memesh entry');
143
+ process.exit(2);
144
+ }
145
+ // Read the actual commit sha so future doctor calls match the install.
146
+ let sha = 'unknown';
147
+ try {
148
+ sha = require('child_process')
149
+ .execFileSync('git', ['-C', process.env.MARKETPLACE_DIR, 'rev-parse', 'HEAD'], { encoding: 'utf8' })
150
+ .trim();
151
+ } catch {}
152
+ const entry = j.plugins['memesh@pcircle-memesh'][0] || {};
153
+ entry.installPath = process.env.NEW_INSTALL_PATH;
154
+ entry.version = process.env.NEW_VERSION;
155
+ entry.lastUpdated = new Date().toISOString();
156
+ entry.gitCommitSha = sha;
157
+ j.plugins['memesh@pcircle-memesh'][0] = entry;
158
+ fs.writeFileSync(path, JSON.stringify(j, null, 4) + '\n');
159
+ " || {
160
+ echo "ERROR: failed to patch installed_plugins.json" >&2
161
+ exit 1
162
+ }
163
+
164
+ # ─── 6. Done ─────────────────────────────────────────────────────────────
165
+ echo ""
166
+ echo "✓ MeMesh upgraded: $CURRENT_VERSION -> $NEW_VERSION"
167
+ echo " Install path: $NEW_INSTALL_PATH"
168
+ echo ""
169
+ echo "Next step: restart Claude Code so the new MCP server picks up."
170
+ echo "Old version still on disk at $CACHE_ROOT/$CURRENT_VERSION (safe to delete once verified)."