@contextmirror/claude-memory 0.3.1 → 0.4.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.
@@ -16,8 +16,9 @@ import { homedir } from 'os';
16
16
  import { DEFAULT_MEMORY_CONFIG } from '../types/index.js';
17
17
  import { isPro, getProFeatureMessage } from '../license/index.js';
18
18
  import { detectStaleProjects, checkCurrentProjectStaleness, formatStalenessForMcp } from '../scanner/stalenessDetector.js';
19
+ import { checkForUpdate, formatUpdateMessage } from '../utils/updateChecker.js';
19
20
  const MEMORY_DIR = join(homedir(), '.claude-memory');
20
- const CURRENT_VERSION = '0.3.0'; // Update this with each release
21
+ const CURRENT_VERSION = '0.4.0'; // Update this with each release
21
22
  // Tool definitions
22
23
  const tools = [
23
24
  {
@@ -227,10 +228,16 @@ function detectCurrentDirectoryStatus(cwd, context, config) {
227
228
  suggestedAction: 'none',
228
229
  };
229
230
  }
230
- function handleGetGlobalContext(cwd) {
231
+ async function handleGetGlobalContext(cwd) {
231
232
  const context = loadContext();
232
233
  const config = loadConfig();
233
234
  const lines = [];
235
+ // Check for updates (cached, won't block)
236
+ const updateResult = await checkForUpdate(CURRENT_VERSION);
237
+ if (updateResult.updateAvailable) {
238
+ lines.push(formatUpdateMessage(updateResult));
239
+ lines.push('');
240
+ }
234
241
  // If cwd is provided, check the current directory status first
235
242
  if (cwd) {
236
243
  const cwdStatus = detectCurrentDirectoryStatus(cwd, context, config);
@@ -569,7 +576,7 @@ async function main() {
569
576
  let result;
570
577
  switch (name) {
571
578
  case 'get_global_context':
572
- result = handleGetGlobalContext(args.cwd);
579
+ result = await handleGetGlobalContext(args.cwd);
573
580
  break;
574
581
  case 'get_project_summary':
575
582
  result = handleGetProjectSummary(args.project);
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Update checker for claude-memory
3
+ * Checks npm registry for newer versions and caches result
4
+ */
5
+ interface UpdateCheckResult {
6
+ updateAvailable: boolean;
7
+ currentVersion: string;
8
+ latestVersion: string | null;
9
+ message?: string;
10
+ }
11
+ /**
12
+ * Check if an update is available
13
+ * Uses cache to avoid checking too frequently
14
+ */
15
+ export declare function checkForUpdate(currentVersion: string): Promise<UpdateCheckResult>;
16
+ /**
17
+ * Format update message for MCP output
18
+ */
19
+ export declare function formatUpdateMessage(result: UpdateCheckResult): string;
20
+ export {};
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Update checker for claude-memory
3
+ * Checks npm registry for newer versions and caches result
4
+ */
5
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
6
+ import { join } from 'path';
7
+ import { homedir } from 'os';
8
+ import https from 'https';
9
+ const MEMORY_DIR = join(homedir(), '.claude-memory');
10
+ const UPDATE_CACHE_FILE = join(MEMORY_DIR, 'update-check.json');
11
+ const PACKAGE_NAME = '@contextmirror/claude-memory';
12
+ const CHECK_INTERVAL_HOURS = 24; // Check once per day
13
+ /**
14
+ * Fetch the latest version from npm registry
15
+ */
16
+ function fetchLatestVersion() {
17
+ return new Promise((resolve) => {
18
+ const url = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
19
+ const req = https.get(url, { timeout: 5000 }, (res) => {
20
+ let data = '';
21
+ res.on('data', (chunk) => {
22
+ data += chunk;
23
+ });
24
+ res.on('end', () => {
25
+ try {
26
+ const json = JSON.parse(data);
27
+ resolve(json.version || null);
28
+ }
29
+ catch {
30
+ resolve(null);
31
+ }
32
+ });
33
+ });
34
+ req.on('error', () => {
35
+ resolve(null);
36
+ });
37
+ req.on('timeout', () => {
38
+ req.destroy();
39
+ resolve(null);
40
+ });
41
+ });
42
+ }
43
+ /**
44
+ * Load cached update check result
45
+ */
46
+ function loadCache() {
47
+ try {
48
+ if (existsSync(UPDATE_CACHE_FILE)) {
49
+ return JSON.parse(readFileSync(UPDATE_CACHE_FILE, 'utf-8'));
50
+ }
51
+ }
52
+ catch {
53
+ // Ignore errors
54
+ }
55
+ return null;
56
+ }
57
+ /**
58
+ * Save update check result to cache
59
+ */
60
+ function saveCache(cache) {
61
+ try {
62
+ if (!existsSync(MEMORY_DIR)) {
63
+ mkdirSync(MEMORY_DIR, { recursive: true });
64
+ }
65
+ writeFileSync(UPDATE_CACHE_FILE, JSON.stringify(cache, null, 2), 'utf-8');
66
+ }
67
+ catch {
68
+ // Ignore errors
69
+ }
70
+ }
71
+ /**
72
+ * Compare semantic versions
73
+ * Returns true if latestVersion is newer than currentVersion
74
+ */
75
+ function isNewer(currentVersion, latestVersion) {
76
+ const current = currentVersion.split('.').map(Number);
77
+ const latest = latestVersion.split('.').map(Number);
78
+ for (let i = 0; i < 3; i++) {
79
+ if ((latest[i] || 0) > (current[i] || 0))
80
+ return true;
81
+ if ((latest[i] || 0) < (current[i] || 0))
82
+ return false;
83
+ }
84
+ return false;
85
+ }
86
+ /**
87
+ * Check if an update is available
88
+ * Uses cache to avoid checking too frequently
89
+ */
90
+ export async function checkForUpdate(currentVersion) {
91
+ const cache = loadCache();
92
+ const now = new Date();
93
+ // Check if we have a recent cache
94
+ if (cache) {
95
+ const lastChecked = new Date(cache.lastChecked);
96
+ const hoursSinceCheck = (now.getTime() - lastChecked.getTime()) / (1000 * 60 * 60);
97
+ if (hoursSinceCheck < CHECK_INTERVAL_HOURS && cache.latestVersion) {
98
+ // Use cached result
99
+ const updateAvailable = isNewer(currentVersion, cache.latestVersion);
100
+ return {
101
+ updateAvailable,
102
+ currentVersion,
103
+ latestVersion: cache.latestVersion,
104
+ message: updateAvailable
105
+ ? `⬆️ Update available: v${currentVersion} → v${cache.latestVersion}`
106
+ : undefined,
107
+ };
108
+ }
109
+ }
110
+ // Fetch fresh version info
111
+ const latestVersion = await fetchLatestVersion();
112
+ // Save to cache
113
+ saveCache({
114
+ lastChecked: now.toISOString(),
115
+ latestVersion,
116
+ currentVersion,
117
+ });
118
+ if (!latestVersion) {
119
+ return {
120
+ updateAvailable: false,
121
+ currentVersion,
122
+ latestVersion: null,
123
+ };
124
+ }
125
+ const updateAvailable = isNewer(currentVersion, latestVersion);
126
+ return {
127
+ updateAvailable,
128
+ currentVersion,
129
+ latestVersion,
130
+ message: updateAvailable
131
+ ? `⬆️ Update available: v${currentVersion} → v${latestVersion}`
132
+ : undefined,
133
+ };
134
+ }
135
+ /**
136
+ * Format update message for MCP output
137
+ */
138
+ export function formatUpdateMessage(result) {
139
+ if (!result.updateAvailable || !result.latestVersion) {
140
+ return '';
141
+ }
142
+ return [
143
+ '',
144
+ '---',
145
+ '',
146
+ `### ${result.message}`,
147
+ '',
148
+ 'Run to update:',
149
+ '```bash',
150
+ 'npm update -g @contextmirror/claude-memory',
151
+ '```',
152
+ '',
153
+ '> After updating, restart Claude Code to use the new version.',
154
+ ].join('\n');
155
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contextmirror/claude-memory",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Cross-project memory for Claude Code - know about all your projects",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",