@the-17/agentsecrets 1.1.4 → 3.0.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.
package/README.md CHANGED
@@ -58,7 +58,7 @@ pip install agentsecrets-cli
58
58
 
59
59
  **Go:**
60
60
  ```bash
61
- go install github.com/The-17/agentsecrets/cmd/agentsecrets@latest
61
+ go install github.com/The-17/agentsecrets/cmd/agentsecrets@v3.0.0
62
62
  ```
63
63
 
64
64
  ---
@@ -1,166 +1,185 @@
1
- #!/usr/bin/env node
2
-
3
- const os = require('os');
4
- const fs = require('fs');
5
- const path = require('path');
6
- const { spawn } = require('child_process');
7
- const https = require('https');
8
- const tar = require('tar');
9
-
10
- const GITHUB_REPO = "The-17/agentsecrets";
11
-
12
- function getPlatformInfo() {
13
- const platform = os.platform();
14
- const arch = os.arch();
15
-
16
- let osName = platform;
17
- if (platform === 'win32') osName = 'windows';
18
- if (platform === 'darwin') osName = 'darwin';
19
- if (platform === 'linux') osName = 'linux';
20
-
21
- let archName = 'amd64';
22
- if (arch === 'x64') archName = 'amd64';
23
- if (arch === 'arm64') archName = 'arm64';
24
- if (arch === 'ia32') archName = '386';
25
-
26
- return { osName, archName };
27
- }
28
-
29
- function httpsGet(url) {
30
- return new Promise((resolve, reject) => {
31
- https.get(url, { headers: { 'User-Agent': 'agentsecrets-npm' } }, (res) => {
32
- if (res.statusCode === 301 || res.statusCode === 302) {
33
- return httpsGet(res.headers.location).then(resolve).catch(reject);
34
- }
35
- let data = '';
36
- res.on('data', chunk => data += chunk);
37
- res.on('end', () => resolve({ statusCode: res.statusCode, body: data }));
38
- }).on('error', reject);
39
- });
40
- }
41
-
42
- const CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
43
-
44
- async function getLatestVersion(baseDir) {
45
- const cacheFile = path.join(baseDir, 'version.cache');
46
-
47
- // Check cache first
48
- if (fs.existsSync(cacheFile)) {
49
- const cache = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
50
- if (Date.now() - cache.timestamp < CACHE_TTL_MS) {
51
- return cache.version;
52
- }
53
- }
54
-
55
- try {
56
- const { body } = await httpsGet(`https://api.github.com/repos/${GITHUB_REPO}/releases/latest`);
57
- const release = JSON.parse(body);
58
- const version = release.tag_name.replace(/^v/, '');
59
-
60
- // Save to cache
61
- fs.writeFileSync(cacheFile, JSON.stringify({ version, timestamp: Date.now() }));
62
- return version;
63
- } catch {
64
- return null;
65
- }
66
- }
67
-
68
- async function downloadFile(url, dest) {
69
- return new Promise((resolve, reject) => {
70
- const file = fs.createWriteStream(dest);
71
- https.get(url, { headers: { 'User-Agent': 'agentsecrets-npm' } }, (response) => {
72
- if (response.statusCode === 302 || response.statusCode === 301) {
73
- downloadFile(response.headers.location, dest).then(resolve).catch(reject);
74
- return;
75
- }
76
- if (response.statusCode !== 200) {
77
- reject(new Error(`Failed to download: ${response.statusCode}`));
78
- return;
79
- }
80
- response.pipe(file);
81
- file.on('finish', () => file.close(resolve));
82
- }).on('error', (err) => {
83
- fs.unlink(dest, () => reject(err));
84
- });
85
- });
86
- }
87
-
88
- async function ensureBinary() {
89
- const { osName, archName } = getPlatformInfo();
90
- const baseDir = path.join(os.homedir(), '.agentsecrets', 'bin');
91
- if (!fs.existsSync(baseDir)) {
92
- fs.mkdirSync(baseDir, { recursive: true });
93
- }
94
-
95
- let binaryName = 'agentsecrets';
96
- if (osName === 'windows') binaryName += '.exe';
97
-
98
- // Check GitHub for the latest version
99
- const latestVersion = await getLatestVersion(baseDir);
100
-
101
- if (!latestVersion) {
102
- // Offline or GitHub unreachable — fall back to any existing binary
103
- const existing = fs.readdirSync(baseDir).find(f => f.startsWith(binaryName));
104
- if (existing) {
105
- process.stderr.write('Could not reach GitHub. Using cached binary.\n');
106
- return path.join(baseDir, existing);
107
- }
108
- throw new Error('No cached binary and could not reach GitHub to download one.');
109
- }
110
-
111
- const binaryPath = path.join(baseDir, `${binaryName}_${latestVersion}`);
112
-
113
- if (fs.existsSync(binaryPath)) {
114
- return binaryPath; // Already on latest
115
- }
116
-
117
- // Delete old binaries
118
- const oldBinaries = fs.readdirSync(baseDir).filter(f => f.startsWith(binaryName));
119
- for (const old of oldBinaries) {
120
- fs.unlinkSync(path.join(baseDir, old));
121
- }
122
-
123
- process.stderr.write(`Downloading AgentSecrets v${latestVersion} for ${osName}/${archName}...\n`);
124
-
125
- const ext = osName === 'windows' ? 'zip' : 'tar.gz';
126
- const assetName = `agentsecrets_${latestVersion}_${osName}_${archName}.${ext}`;
127
- const url = `https://github.com/${GITHUB_REPO}/releases/download/v${latestVersion}/${assetName}`;
128
-
129
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsecrets-'));
130
- const archivePath = path.join(tmpDir, assetName);
131
-
132
- try {
133
- await downloadFile(url, archivePath);
134
-
135
- if (ext === 'tar.gz') {
136
- await tar.x({ file: archivePath, cwd: tmpDir });
137
- } else {
138
- if (osName === 'windows') {
139
- throw new Error('Automatic zip extraction for Windows not yet implemented.');
140
- }
141
- }
142
-
143
- const extractedBinary = path.join(tmpDir, binaryName);
144
- fs.copyFileSync(extractedBinary, binaryPath);
145
- fs.chmodSync(binaryPath, 0o755);
146
- fs.rmSync(tmpDir, { recursive: true, force: true });
147
-
148
- return binaryPath;
149
- } catch (err) {
150
- throw new Error(`Failed to download AgentSecrets binary: ${err.message}`);
151
- }
152
- }
153
-
154
- async function main() {
155
- try {
156
- const binaryPath = await ensureBinary();
157
- const args = process.argv.slice(2);
158
- const child = spawn(binaryPath, args, { stdio: 'inherit' });
159
- child.on('exit', (code) => process.exit(code));
160
- } catch (err) {
161
- process.stderr.write(`Error: ${err.message}\n`);
162
- process.exit(1);
163
- }
164
- }
165
-
166
- main();
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const os = require('os');
6
+ const { spawn } = require('child_process');
7
+ const https = require('https');
8
+ const tar = require('tar');
9
+
10
+ const PACKAGE_JSON = require('../package.json');
11
+ const VERSION = PACKAGE_JSON.version;
12
+ const GITHUB_REPO = "The-17/agentsecrets";
13
+
14
+ function getPlatformInfo() {
15
+ const type = os.type();
16
+ const arch = os.arch();
17
+
18
+ let os_name = '';
19
+ if (type === 'Darwin') os_name = 'darwin';
20
+ else if (type === 'Linux') os_name = 'linux';
21
+ else if (type === 'Windows_NT') os_name = 'windows';
22
+
23
+ let arch_name = '';
24
+ if (arch === 'x64') arch_name = 'amd64';
25
+ else if (arch === 'arm64') arch_name = 'arm64';
26
+ else if (arch === 'ia32') arch_name = '386';
27
+
28
+ return { os_name, arch_name };
29
+ }
30
+
31
+ async function downloadBinary(url, dest, isZip = false) {
32
+ return new Promise((resolve, reject) => {
33
+ https.get(url, (res) => {
34
+ if (res.statusCode === 302 || res.statusCode === 301) {
35
+ const nextIsZip = isZip || url.split('?')[0].endsWith('.zip');
36
+ return downloadBinary(res.headers.location, dest, nextIsZip).then(resolve).catch(reject);
37
+ }
38
+ if (res.statusCode !== 200) {
39
+ return reject(new Error(`Failed to download: ${res.statusCode}`));
40
+ }
41
+
42
+ const tempDir = path.join(os.tmpdir(), `agentsecrets-${Date.now()}`);
43
+ fs.mkdirSync(tempDir, { recursive: true });
44
+
45
+ const isWin = isZip || url.split('?')[0].endsWith('.zip');
46
+ if (isWin) {
47
+ const zipPath = path.join(tempDir, 'archive.zip');
48
+ const fileStream = fs.createWriteStream(zipPath);
49
+ res.pipe(fileStream);
50
+ fileStream.on('finish', () => {
51
+ fileStream.close(() => {
52
+ const { execSync } = require('child_process');
53
+ try {
54
+ // Use ErrorActionPreference = Stop so PowerShell errors trigger execSync failure
55
+ execSync('powershell.exe -NoProfile -Command "$ErrorActionPreference = \'Stop\'; Expand-Archive -Path \'' + zipPath + '\' -DestinationPath \'' + tempDir + '\' -Force"', { stdio: 'pipe' });
56
+ const binaryName = 'agentsecrets.exe';
57
+ const src = path.join(tempDir, binaryName);
58
+ if (fs.existsSync(src)) {
59
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
60
+ fs.renameSync(src, dest);
61
+ resolve();
62
+ } else {
63
+ reject(new Error('Binary ' + binaryName + ' not found in zip archive'));
64
+ }
65
+ } catch (err) {
66
+ const stderr = err.stderr ? err.stderr.toString() : '';
67
+ reject(new Error('Failed to extract ZIP archive on Windows: ' + err.message + '\nPowerShell Error: ' + stderr));
68
+ }
69
+ });
70
+ });
71
+ fileStream.on('error', reject);
72
+ return;
73
+ }
74
+
75
+ res.pipe(tar.x({ C: tempDir }))
76
+ .on('finish', () => {
77
+ const binaryName = os.platform() === 'win32' ? 'agentsecrets.exe' : 'agentsecrets';
78
+ const src = path.join(tempDir, binaryName);
79
+ if (fs.existsSync(src)) {
80
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
81
+ fs.renameSync(src, dest);
82
+ fs.chmodSync(dest, 0o755);
83
+
84
+ // Pre-register with keychain-auth if available. This eliminates
85
+ // the one-time setup spinner on the user's first command.
86
+ try {
87
+ const { execFileSync } = require('child_process');
88
+ execFileSync('keychain-auth', ['register', dest], {
89
+ timeout: 5000,
90
+ stdio: 'ignore',
91
+ });
92
+ } catch (_) {
93
+ // Silent — AutoSetup handles registration at runtime if needed
94
+ }
95
+
96
+ resolve();
97
+ } else {
98
+ reject(new Error(`Binary ${binaryName} not found in archive`));
99
+ }
100
+ })
101
+ .on('error', reject);
102
+ }).on('error', reject);
103
+ });
104
+ }
105
+
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
+ async function getBinaryPath() {
132
+ const { os_name, arch_name } = getPlatformInfo();
133
+ const binDir = path.join(os.homedir(), '.agentsecrets', 'bin');
134
+ const binaryName = os_name === 'windows' ? 'agentsecrets.exe' : 'agentsecrets';
135
+
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
+
145
+ const binaryPath = path.join(binDir, `${binaryName}_${version}`);
146
+
147
+ if (fs.existsSync(binaryPath)) {
148
+ return binaryPath;
149
+ }
150
+
151
+ console.error(`AgentSecrets binary not found. Downloading v${version} for ${os_name}/${arch_name}...`);
152
+
153
+ const ext = os_name === 'windows' ? 'zip' : 'tar.gz';
154
+ const assetName = `agentsecrets_${version}_${os_name}_${arch_name}.${ext}`;
155
+ const url = `https://github.com/${GITHUB_REPO}/releases/download/v${version}/${assetName}`;
156
+
157
+ try {
158
+ await downloadBinary(url, binaryPath);
159
+ return binaryPath;
160
+ } catch (err) {
161
+ throw new Error(`Failed to download AgentSecrets binary: ${err.message}\nURL: ${url}`);
162
+ }
163
+ }
164
+
165
+ async function main() {
166
+ try {
167
+ const binaryPath = await getBinaryPath();
168
+ const args = process.argv.slice(2);
169
+ const proc = spawn(binaryPath, args, { stdio: 'inherit' });
170
+ proc.on('close', (code) => process.exit(code || 0));
171
+ proc.on('error', (err) => {
172
+ console.error(`Failed to execute AgentSecrets: ${err.message}`);
173
+ process.exit(1);
174
+ });
175
+ } catch (err) {
176
+ console.error(err.message);
177
+ process.exit(1);
178
+ }
179
+ }
180
+
181
+ if (require.main === module) {
182
+ main();
183
+ }
184
+
185
+ module.exports = { getBinaryPath };
package/index.js ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @the-17/agentsecrets
3
+ * Zero-knowledge secrets infrastructure built for AI agents.
4
+ */
5
+
6
+ const { spawn } = require('child_process');
7
+ const path = require('path');
8
+ const { getBinaryPath } = require('./bin/agentsecrets');
9
+
10
+ /**
11
+ * Executes the agentsecrets CLI binary with the given arguments.
12
+ * @param {string[]} args
13
+ * @returns {Promise<number>}
14
+ */
15
+ async function run(args = []) {
16
+ const binaryPath = await getBinaryPath();
17
+ return new Promise((resolve, reject) => {
18
+ const proc = spawn(binaryPath, args, { stdio: 'inherit' });
19
+ proc.on('close', (code) => resolve(code));
20
+ proc.on('error', (err) => reject(err));
21
+ });
22
+ }
23
+
24
+ module.exports = {
25
+ run,
26
+ getBinaryPath
27
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@the-17/agentsecrets",
3
- "version": "1.1.4",
3
+ "version": "3.0.0",
4
4
  "description": "AI-native zero-knowledge secrets manager (CLI wrapper)",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -18,7 +18,7 @@
18
18
  "cli",
19
19
  "ai-secrets-management"
20
20
  ],
21
- "author": "The Seventeen <hello@theseventeen.co>",
21
+ "author": "The Seventeen <engineering@theseventeen.co>",
22
22
  "license": "MIT",
23
23
  "repository": {
24
24
  "type": "git",