Files
claude-mem/scripts/sync-marketplace.cjs
Alex Newman bfc7de377a revert: roll back v12.3.3 (Issue Blowout 2026)
SessionStart context injection regressed in v12.3.3 — no memory
context is being delivered to new sessions. Rolling back to the
v12.3.2 tree state while the regression is investigated.

Reverts #2080.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 11:59:15 -07:00

136 lines
4.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* Protected sync-marketplace script
*
* Prevents accidental rsync overwrite when installed plugin is on beta branch.
* If on beta, the user should use the UI to update instead.
*/
const { execSync } = require('child_process');
const { existsSync, readFileSync } = require('fs');
const path = require('path');
const os = require('os');
const INSTALLED_PATH = path.join(os.homedir(), '.claude', 'plugins', 'marketplaces', 'thedotmack');
const CACHE_BASE_PATH = path.join(os.homedir(), '.claude', 'plugins', 'cache', 'thedotmack', 'claude-mem');
function getCurrentBranch() {
try {
if (!existsSync(path.join(INSTALLED_PATH, '.git'))) {
return null;
}
return execSync('git rev-parse --abbrev-ref HEAD', {
cwd: INSTALLED_PATH,
encoding: 'utf-8',
stdio: ['pipe', 'pipe', 'pipe']
}).trim();
} catch {
return null;
}
}
function getGitignoreExcludes(basePath) {
const gitignorePath = path.join(basePath, '.gitignore');
if (!existsSync(gitignorePath)) return '';
const lines = readFileSync(gitignorePath, 'utf-8').split('\n');
return lines
.map(line => line.trim())
.filter(line => line && !line.startsWith('#') && !line.startsWith('!'))
.map(pattern => `--exclude=${JSON.stringify(pattern)}`)
.join(' ');
}
const branch = getCurrentBranch();
const isForce = process.argv.includes('--force');
if (branch && branch !== 'main' && !isForce) {
console.log('');
console.log('\x1b[33m%s\x1b[0m', `WARNING: Installed plugin is on beta branch: ${branch}`);
console.log('\x1b[33m%s\x1b[0m', 'Running rsync would overwrite beta code.');
console.log('');
console.log('Options:');
console.log(' 1. Use UI at http://localhost:37777 to update beta');
console.log(' 2. Switch to stable in UI first, then run sync');
console.log(' 3. Force rsync: npm run sync-marketplace:force');
console.log('');
process.exit(1);
}
// Get version from plugin.json
function getPluginVersion() {
try {
const pluginJsonPath = path.join(__dirname, '..', 'plugin', '.claude-plugin', 'plugin.json');
const pluginJson = JSON.parse(readFileSync(pluginJsonPath, 'utf-8'));
return pluginJson.version;
} catch (error) {
console.error('\x1b[31m%s\x1b[0m', 'Failed to read plugin version:', error.message);
process.exit(1);
}
}
// Normal rsync for main branch or fresh install
console.log('Syncing to marketplace...');
try {
const rootDir = path.join(__dirname, '..');
const gitignoreExcludes = getGitignoreExcludes(rootDir);
execSync(
`rsync -av --delete --exclude=.git --exclude=bun.lock --exclude=package-lock.json ${gitignoreExcludes} ./ ~/.claude/plugins/marketplaces/thedotmack/`,
{ stdio: 'inherit' }
);
console.log('Running bun install in marketplace...');
execSync(
'cd ~/.claude/plugins/marketplaces/thedotmack/ && bun install',
{ stdio: 'inherit' }
);
// Sync to cache folder with version
const version = getPluginVersion();
const CACHE_VERSION_PATH = path.join(CACHE_BASE_PATH, version);
const pluginDir = path.join(rootDir, 'plugin');
const pluginGitignoreExcludes = getGitignoreExcludes(pluginDir);
console.log(`Syncing to cache folder (version ${version})...`);
execSync(
`rsync -av --delete --exclude=.git ${pluginGitignoreExcludes} plugin/ "${CACHE_VERSION_PATH}/"`,
{ stdio: 'inherit' }
);
// Install dependencies in cache directory so worker can resolve them
console.log(`Running bun install in cache folder (version ${version})...`);
execSync(`bun install`, { cwd: CACHE_VERSION_PATH, stdio: 'inherit' });
console.log('\x1b[32m%s\x1b[0m', 'Sync complete!');
// Trigger worker restart after file sync
console.log('\n🔄 Triggering worker restart...');
const http = require('http');
const req = http.request({
hostname: '127.0.0.1',
port: 37777,
path: '/api/admin/restart',
method: 'POST',
timeout: 2000
}, (res) => {
if (res.statusCode === 200) {
console.log('\x1b[32m%s\x1b[0m', '✓ Worker restart triggered');
} else {
console.log('\x1b[33m%s\x1b[0m', ` Worker restart returned status ${res.statusCode}`);
}
});
req.on('error', () => {
console.log('\x1b[33m%s\x1b[0m', ' Worker not running, will start on next hook');
});
req.on('timeout', () => {
req.destroy();
console.log('\x1b[33m%s\x1b[0m', ' Worker restart timed out');
});
req.end();
} catch (error) {
console.error('\x1b[31m%s\x1b[0m', 'Sync failed:', error.message);
process.exit(1);
}