@the-17/agentsecrets 3.2.2 → 3.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.
Files changed (2) hide show
  1. package/bin/agentsecrets.js +78 -41
  2. package/package.json +1 -1
@@ -28,6 +28,78 @@ function getPlatformInfo() {
28
28
  return { os_name, arch_name };
29
29
  }
30
30
 
31
+ function compareVersions(v1, v2) {
32
+ const p1 = (v1 || '').replace(/^v/, '').split('.').map(Number);
33
+ const p2 = (v2 || '').replace(/^v/, '').split('.').map(Number);
34
+ for (let i = 0; i < 3; i++) {
35
+ const n1 = p1[i] || 0;
36
+ const n2 = p2[i] || 0;
37
+ if (n1 < n2) return -1;
38
+ if (n1 > n2) return 1;
39
+ }
40
+ return 0;
41
+ }
42
+
43
+ function checkUpdateNotice() {
44
+ try {
45
+ const cacheFile = path.join(os.homedir(), '.agentsecrets', 'npm_update_cache.json');
46
+ let cache = null;
47
+ if (fs.existsSync(cacheFile)) {
48
+ try {
49
+ cache = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
50
+ } catch (_) {}
51
+ }
52
+
53
+ const now = Date.now();
54
+ // Notify on stderr if a newer version is detected
55
+ if (cache && cache.latest_version && compareVersions(cache.latest_version, VERSION) > 0) {
56
+ process.stderr.write(`\n\x1b[33mUpdate available:\x1b[0m ${VERSION} -> \x1b[32m${cache.latest_version}\x1b[0m\nRun: \x1b[36mnpm install -g @the-17/agentsecrets@latest\x1b[0m to update\n\n`);
57
+ }
58
+
59
+ // Refresh cache once per 24 hours in the background (non-blocking)
60
+ if (!cache || !cache.last_checked || now - cache.last_checked > 24 * 60 * 60 * 1000) {
61
+ const req = https.get({
62
+ hostname: 'api.github.com',
63
+ path: `/repos/${GITHUB_REPO}/releases/latest`,
64
+ headers: { 'User-Agent': 'agentsecrets-npm' },
65
+ timeout: 3000
66
+ }, (res) => {
67
+ let data = '';
68
+ res.on('data', (chunk) => data += chunk);
69
+ res.on('end', () => {
70
+ try {
71
+ const json = JSON.parse(data);
72
+ if (json.tag_name) {
73
+ const latest = json.tag_name.replace(/^v/, '');
74
+ fs.mkdirSync(path.dirname(cacheFile), { recursive: true });
75
+ fs.writeFileSync(cacheFile, JSON.stringify({
76
+ last_checked: now,
77
+ latest_version: latest
78
+ }));
79
+ }
80
+ } catch (_) {}
81
+ });
82
+ });
83
+ req.on('error', () => {});
84
+ req.on('timeout', () => req.destroy());
85
+ }
86
+ } catch (_) {}
87
+ }
88
+
89
+ function cleanupOldBinaries(binDir, currentBinaryPath) {
90
+ try {
91
+ if (!fs.existsSync(binDir)) return;
92
+ const files = fs.readdirSync(binDir);
93
+ const prefix = os.platform() === 'win32' ? 'agentsecrets.exe_' : 'agentsecrets_';
94
+ for (const f of files) {
95
+ const fullPath = path.join(binDir, f);
96
+ if (f.startsWith(prefix) && fullPath !== currentBinaryPath) {
97
+ try { fs.unlinkSync(fullPath); } catch (_) {}
98
+ }
99
+ }
100
+ } catch (_) {}
101
+ }
102
+
31
103
  async function downloadBinary(url, dest, isZip = false) {
32
104
  return new Promise((resolve, reject) => {
33
105
  https.get(url, (res) => {
@@ -51,7 +123,6 @@ async function downloadBinary(url, dest, isZip = false) {
51
123
  fileStream.close(() => {
52
124
  const { execSync } = require('child_process');
53
125
  try {
54
- // Use ErrorActionPreference = Stop so PowerShell errors trigger execSync failure
55
126
  execSync('powershell.exe -NoProfile -Command "$ErrorActionPreference = \'Stop\'; Expand-Archive -Path \'' + zipPath + '\' -DestinationPath \'' + tempDir + '\' -Force"', { stdio: 'pipe' });
56
127
  const binaryName = 'agentsecrets.exe';
57
128
  const src = path.join(tempDir, binaryName);
@@ -81,17 +152,14 @@ async function downloadBinary(url, dest, isZip = false) {
81
152
  fs.renameSync(src, dest);
82
153
  fs.chmodSync(dest, 0o755);
83
154
 
84
- // Pre-register with keychain-auth if available. This eliminates
85
- // the one-time setup spinner on the user's first command.
155
+ // Pre-register with keychain-auth if available
86
156
  try {
87
157
  const { execFileSync } = require('child_process');
88
158
  execFileSync('keychain-auth', ['register', dest], {
89
159
  timeout: 5000,
90
160
  stdio: 'ignore',
91
161
  });
92
- } catch (_) {
93
- // Silent — AutoSetup handles registration at runtime if needed
94
- }
162
+ } catch (_) {}
95
163
 
96
164
  resolve();
97
165
  } else {
@@ -103,52 +171,19 @@ async function downloadBinary(url, dest, isZip = false) {
103
171
  });
104
172
  }
105
173
 
106
- async function getLatestVersion() {
107
- return new Promise((resolve, reject) => {
108
- https.get({
109
- hostname: 'api.github.com',
110
- path: `/repos/${GITHUB_REPO}/releases/latest`,
111
- headers: { 'User-Agent': 'agentsecrets-npm' }
112
- }, (res) => {
113
- let data = '';
114
- res.on('data', (chunk) => data += chunk);
115
- res.on('end', () => {
116
- try {
117
- const json = JSON.parse(data);
118
- if (json.tag_name) {
119
- resolve(json.tag_name.replace(/^v/, ''));
120
- } else {
121
- reject(new Error('No tag_name in latest release'));
122
- }
123
- } catch (e) {
124
- reject(e);
125
- }
126
- });
127
- }).on('error', reject);
128
- });
129
- }
130
-
131
174
  async function getBinaryPath() {
132
175
  const { os_name, arch_name } = getPlatformInfo();
133
176
  const binDir = path.join(os.homedir(), '.agentsecrets', 'bin');
134
177
  const binaryName = os_name === 'windows' ? 'agentsecrets.exe' : 'agentsecrets';
135
178
 
136
- // Try to get the latest version from GitHub
137
- let version = VERSION;
138
- try {
139
- version = await getLatestVersion();
140
- console.log(`Latest AgentSecrets version: ${version}`);
141
- } catch (err) {
142
- console.error(`Failed to fetch latest version from GitHub: ${err.message}. Falling back to package version ${VERSION}.`);
143
- }
144
-
179
+ const version = VERSION;
145
180
  const binaryPath = path.join(binDir, `${binaryName}_${version}`);
146
181
 
147
182
  if (fs.existsSync(binaryPath)) {
148
183
  return binaryPath;
149
184
  }
150
185
 
151
- console.error(`AgentSecrets binary not found. Downloading v${version} for ${os_name}/${arch_name}...`);
186
+ process.stderr.write(`AgentSecrets binary not found. Downloading v${version} for ${os_name}/${arch_name}...\n`);
152
187
 
153
188
  const ext = os_name === 'windows' ? 'zip' : 'tar.gz';
154
189
  const assetName = `agentsecrets_${version}_${os_name}_${arch_name}.${ext}`;
@@ -156,6 +191,7 @@ async function getBinaryPath() {
156
191
 
157
192
  try {
158
193
  await downloadBinary(url, binaryPath);
194
+ cleanupOldBinaries(binDir, binaryPath);
159
195
  return binaryPath;
160
196
  } catch (err) {
161
197
  throw new Error(`Failed to download AgentSecrets binary: ${err.message}\nURL: ${url}`);
@@ -164,6 +200,7 @@ async function getBinaryPath() {
164
200
 
165
201
  async function main() {
166
202
  try {
203
+ checkUpdateNotice();
167
204
  const binaryPath = await getBinaryPath();
168
205
  const args = process.argv.slice(2);
169
206
  const proc = spawn(binaryPath, args, { stdio: 'inherit' });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@the-17/agentsecrets",
3
- "version": "3.2.2",
3
+ "version": "3.2.3",
4
4
  "description": "AI-native zero-knowledge secrets manager (CLI wrapper)",
5
5
  "main": "index.js",
6
6
  "bin": {