jasper-recall 0.2.2 → 0.2.3

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.
@@ -15,7 +15,11 @@ const fs = require('fs');
15
15
  const path = require('path');
16
16
  const os = require('os');
17
17
 
18
- const VERSION = '0.2.2';
18
+ const VERSION = '0.2.3';
19
+
20
+ // Check for updates in background (non-blocking)
21
+ const { checkInBackground } = require('./update-check');
22
+ checkInBackground();
19
23
  const VENV_PATH = path.join(os.homedir(), '.openclaw', 'rag-env');
20
24
  const CHROMA_PATH = path.join(os.homedir(), '.openclaw', 'chroma-db');
21
25
  const BIN_PATH = path.join(os.homedir(), '.local', 'bin');
@@ -135,6 +139,7 @@ COMMANDS:
135
139
  index Index memory files (alias for index-digests)
136
140
  digest Process session logs (alias for digest-sessions)
137
141
  serve Start HTTP API server (for sandboxed agents)
142
+ update Check for updates
138
143
  help Show this help message
139
144
 
140
145
  EXAMPLES:
@@ -186,6 +191,18 @@ switch (command) {
186
191
  const { runCLI } = require('./server');
187
192
  runCLI(process.argv.slice(3));
188
193
  break;
194
+ case 'update':
195
+ case 'check-update':
196
+ // Check for updates explicitly
197
+ const { checkForUpdates } = require('./update-check');
198
+ checkForUpdates().then(result => {
199
+ if (result && !result.updateAvailable) {
200
+ console.log(`✓ You're on the latest version (${result.current})`);
201
+ } else if (!result) {
202
+ console.log('Could not check for updates');
203
+ }
204
+ });
205
+ break;
189
206
  case '--version':
190
207
  case '-v':
191
208
  console.log(VERSION);
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Check for updates and notify user
3
+ * Non-blocking, caches check for 24 hours
4
+ */
5
+
6
+ const https = require('https');
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const os = require('os');
10
+
11
+ const PACKAGE_NAME = 'jasper-recall';
12
+ const CACHE_FILE = path.join(os.homedir(), '.openclaw', '.jasper-recall-update-check');
13
+ const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
14
+
15
+ /**
16
+ * Get current package version
17
+ */
18
+ function getCurrentVersion() {
19
+ try {
20
+ const pkg = require('../package.json');
21
+ return pkg.version;
22
+ } catch {
23
+ return null;
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Check if we should run update check
29
+ */
30
+ function shouldCheck() {
31
+ try {
32
+ if (fs.existsSync(CACHE_FILE)) {
33
+ const stat = fs.statSync(CACHE_FILE);
34
+ const age = Date.now() - stat.mtimeMs;
35
+ if (age < CHECK_INTERVAL_MS) {
36
+ return false; // Checked recently
37
+ }
38
+ }
39
+ } catch {
40
+ // Ignore errors, just check
41
+ }
42
+ return true;
43
+ }
44
+
45
+ /**
46
+ * Save check timestamp
47
+ */
48
+ function saveCheckTime(latestVersion) {
49
+ try {
50
+ const dir = path.dirname(CACHE_FILE);
51
+ if (!fs.existsSync(dir)) {
52
+ fs.mkdirSync(dir, { recursive: true });
53
+ }
54
+ fs.writeFileSync(CACHE_FILE, JSON.stringify({
55
+ checked: new Date().toISOString(),
56
+ latest: latestVersion
57
+ }));
58
+ } catch {
59
+ // Ignore errors
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Fetch latest version from npm
65
+ */
66
+ function fetchLatestVersion() {
67
+ return new Promise((resolve, reject) => {
68
+ const req = https.get(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, {
69
+ timeout: 3000,
70
+ headers: { 'Accept': 'application/json' }
71
+ }, (res) => {
72
+ let data = '';
73
+ res.on('data', chunk => data += chunk);
74
+ res.on('end', () => {
75
+ try {
76
+ const pkg = JSON.parse(data);
77
+ resolve(pkg.version);
78
+ } catch (e) {
79
+ reject(e);
80
+ }
81
+ });
82
+ });
83
+
84
+ req.on('error', reject);
85
+ req.on('timeout', () => {
86
+ req.destroy();
87
+ reject(new Error('timeout'));
88
+ });
89
+ });
90
+ }
91
+
92
+ /**
93
+ * Compare semver versions
94
+ */
95
+ function isNewer(latest, current) {
96
+ const l = latest.split('.').map(Number);
97
+ const c = current.split('.').map(Number);
98
+
99
+ for (let i = 0; i < 3; i++) {
100
+ if ((l[i] || 0) > (c[i] || 0)) return true;
101
+ if ((l[i] || 0) < (c[i] || 0)) return false;
102
+ }
103
+ return false;
104
+ }
105
+
106
+ /**
107
+ * Check for updates (non-blocking)
108
+ */
109
+ async function checkForUpdates(silent = false) {
110
+ if (!shouldCheck()) {
111
+ return null;
112
+ }
113
+
114
+ const current = getCurrentVersion();
115
+ if (!current) return null;
116
+
117
+ try {
118
+ const latest = await fetchLatestVersion();
119
+ saveCheckTime(latest);
120
+
121
+ if (isNewer(latest, current)) {
122
+ if (!silent) {
123
+ console.log('');
124
+ console.log(`📦 Update available: ${current} → ${latest}`);
125
+ console.log(` Run: npm update -g jasper-recall`);
126
+ console.log('');
127
+ }
128
+ return { current, latest, updateAvailable: true };
129
+ }
130
+
131
+ return { current, latest, updateAvailable: false };
132
+ } catch {
133
+ // Silent fail - don't block user
134
+ return null;
135
+ }
136
+ }
137
+
138
+ /**
139
+ * Run check in background (fire and forget)
140
+ */
141
+ function checkInBackground() {
142
+ // Don't await - let it run async
143
+ checkForUpdates().catch(() => {});
144
+ }
145
+
146
+ module.exports = { checkForUpdates, checkInBackground, getCurrentVersion };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jasper-recall",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Local RAG system for AI agent memory using ChromaDB and sentence-transformers",
5
5
  "main": "src/index.js",
6
6
  "bin": {