Skip to content

Commit 1267843

Browse files
committed
feat: v1.2.0 — auto-install skills on npm install, version-safe tests
- postinstall script copies slash commands to ~/.claude/commands/ - Skills + integrations + scripts shipped in npm package - Tests no longer hardcode version numbers (won't break on bumps) - VERSION constant synced to 1.2.0
1 parent 43087ec commit 1267843

7 files changed

Lines changed: 72 additions & 8 deletions

File tree

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "slm-mesh",
3-
"version": "1.1.0",
3+
"version": "1.2.0",
44
"description": "Peer-to-peer communication for AI coding agents — by Qualixar, powered by SuperLocalMemory",
55
"author": "Varun Pratap Bhardwaj",
66
"license": "MIT",
@@ -12,6 +12,9 @@
1212
},
1313
"files": [
1414
"dist",
15+
"skills",
16+
"scripts",
17+
"integrations",
1518
"README.md",
1619
"LICENSE"
1720
],
@@ -23,6 +26,7 @@
2326
"test:coverage": "vitest run --coverage",
2427
"typecheck": "tsc --noEmit",
2528
"lint": "tsc --noEmit",
29+
"postinstall": "node scripts/postinstall.mjs 2>/dev/null || true",
2630
"prepublishOnly": "npm run build"
2731
},
2832
"dependencies": {

python/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "slm-mesh"
3-
version = "1.1.0"
3+
version = "1.2.0"
44
description = "Python client for SLM Mesh — peer-to-peer communication for AI coding agents."
55
readme = "README.md"
66
license = "MIT"

scripts/postinstall.mjs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/usr/bin/env node
2+
/**
3+
* SLM Mesh — Post-install: auto-setup skills for supported platforms.
4+
* Runs after `npm install -g slm-mesh`.
5+
*
6+
* SAFETY RULES:
7+
* - NEVER overwrite existing files (skip if file exists)
8+
* - NEVER modify existing config files
9+
* - NEVER break if a platform isn't installed
10+
* - Only CREATE new files in expected directories
11+
* - Every operation wrapped in try/catch
12+
* - Silent exit on any error (don't break npm install)
13+
*
14+
* Copyright 2026 Varun Pratap Bhardwaj. MIT License.
15+
*/
16+
17+
import { mkdirSync, copyFileSync, readdirSync, existsSync } from 'node:fs';
18+
import { join, dirname } from 'node:path';
19+
import { homedir } from 'node:os';
20+
import { fileURLToPath } from 'node:url';
21+
22+
const __dirname = dirname(fileURLToPath(import.meta.url));
23+
const skillsDir = join(__dirname, '..', 'skills');
24+
const home = homedir();
25+
26+
// Silent exit if skills folder missing (CI, partial install)
27+
if (!existsSync(skillsDir)) process.exit(0);
28+
29+
const skills = readdirSync(skillsDir).filter(f => f.endsWith('.md'));
30+
if (skills.length === 0) process.exit(0);
31+
32+
// ─── Claude Code: ~/.claude/commands/ ───
33+
// These are slash commands. Only copies files that don't already exist.
34+
try {
35+
const claudeDir = join(home, '.claude', 'commands');
36+
mkdirSync(claudeDir, { recursive: true });
37+
let count = 0;
38+
for (const skill of skills) {
39+
const target = join(claudeDir, skill);
40+
if (!existsSync(target)) {
41+
copyFileSync(join(skillsDir, skill), target);
42+
count++;
43+
}
44+
}
45+
if (count > 0) {
46+
console.log(` slm-mesh: ${count} slash commands installed to ~/.claude/commands/`);
47+
console.log(' Type /mesh-peers, /mesh-send, /mesh-lock in any Claude Code session.');
48+
}
49+
} catch {
50+
// Skip silently — don't break npm install
51+
}
52+
53+
// ─── Summary ───
54+
console.log('');
55+
console.log(' slm-mesh: Setup complete.');
56+
console.log(' Add to Claude Code: claude mcp add --scope user slm-mesh -- npx slm-mesh');
57+
console.log(' Add to Cursor/Windsurf/VS Code:');
58+
console.log(' { "mcpServers": { "slm-mesh": { "command": "npx", "args": ["slm-mesh"] } } }');
59+
console.log(' Docs: https://github.com/qualixar/slm-mesh');

src/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export interface MeshConfig {
2626
readonly walCheckpointIntervalMs: number;
2727
}
2828

29-
export const VERSION = '1.0.0';
29+
export const VERSION = '1.2.0';
3030
export const PRODUCT_NAME = 'SLM Mesh';
3131
export const BRANDING = `${PRODUCT_NAME} v${VERSION} | Part of the Qualixar research initiative`;
3232

tests/unit/cli/cli-coverage.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ describe('runCli', () => {
288288
console.log = (...args: unknown[]) => logOutput.push(args.map(String).join(' '));
289289
try {
290290
await runCli(['node', 'slm-mesh', 'version']);
291-
expect(logOutput.some(l => l.includes('1.0.0'))).toBe(true);
291+
expect(logOutput.some(l => /\d+\.\d+\.\d+/.test(l))).toBe(true);
292292
} finally {
293293
console.log = origLog;
294294
}

tests/unit/cli/cli.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import { describe, it, expect } from 'vitest';
88
import { createServer } from 'node:http';
99
import { createProgram, buildAuthHeaders, brokerGet, brokerPost } from '../../../src/cli/cli.js';
10+
import { VERSION } from '../../../src/config.js';
1011

1112
describe('createProgram', () => {
1213
it('creates a program with all expected commands', () => {
@@ -34,7 +35,7 @@ describe('createProgram', () => {
3435
it('has correct version set', () => {
3536
const program = createProgram();
3637
expect(program.version()).toBeDefined();
37-
expect(program.version()).toContain('1.0.0');
38+
expect(program.version()).toContain(VERSION);
3839
});
3940

4041
it('has correct program name', () => {

tests/unit/mcp/server.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,16 @@ import { VERSION, PRODUCT_NAME, BRANDING, createConfig } from '../../../src/conf
3030
// via manual testing and the broker integration tests.
3131

3232
describe('MCP Server configuration', () => {
33-
it('config has correct version', () => {
34-
expect(VERSION).toBe('1.0.0');
33+
it('config has correct version format', () => {
34+
expect(VERSION).toMatch(/^\d+\.\d+\.\d+$/);
3535
});
3636

3737
it('config has correct product name', () => {
3838
expect(PRODUCT_NAME).toBe('SLM Mesh');
3939
});
4040

4141
it('branding includes version and Qualixar', () => {
42-
expect(BRANDING).toContain('1.0.0');
42+
expect(BRANDING).toContain(VERSION);
4343
expect(BRANDING).toContain('Qualixar');
4444
});
4545

0 commit comments

Comments
 (0)