@mandors/cli 0.0.18 → 0.0.19

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.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Post-install hook for Mandor CLI
3
- * @description Downloads binary from GitHub releases during npm install
4
- * @version 0.0.4
3
+ * @description Downloads and extracts binary from GitHub releases
4
+ * @version 0.0.5
5
5
  */
6
6
 
7
7
  const fs = require('fs');
@@ -11,8 +11,7 @@ const { execSync } = require('child_process');
11
11
  const https = require('https');
12
12
 
13
13
  const REPO = 'sanxzy/mandor';
14
- const GITHUB_API = 'https://api.github.com';
15
- const CACHE_DIR = path.join(os.homedir(), '.mandor', 'bin');
14
+ const INSTALL_DIR = path.join(os.homedir(), '.local', 'bin');
16
15
 
17
16
  function getPlatform() {
18
17
  const platform = os.platform();
@@ -27,8 +26,8 @@ function getPlatform() {
27
26
 
28
27
  async function getLatestVersion(prerelease = false) {
29
28
  const url = prerelease
30
- ? `${GITHUB_API}/repos/${REPO}/releases`
31
- : `${GITHUB_API}/repos/${REPO}/releases/latest`;
29
+ ? `https://api.github.com/repos/${REPO}/releases`
30
+ : `https://api.github.com/repos/${REPO}/releases/latest`;
32
31
 
33
32
  return new Promise((resolve, reject) => {
34
33
  https.get(url, { headers: { 'User-Agent': 'Mandor-CLI' } }, (res) => {
@@ -70,7 +69,7 @@ async function install(options = {}) {
70
69
  const version = options.version || 'latest';
71
70
  const prerelease = options.prerelease || false;
72
71
  const osArch = `${platform}-${arch}`;
73
- const assetName = `${osArch}.tar.gz`;
72
+ const binaryName = platform === 'win32' ? 'mandor.exe' : 'mandor';
74
73
 
75
74
  console.log('Mandor Installer');
76
75
  console.log('================');
@@ -85,37 +84,38 @@ async function install(options = {}) {
85
84
  console.log(`Version: ${installVersion}`);
86
85
  console.log('');
87
86
 
88
- const cachePath = path.join(CACHE_DIR, installVersion, osArch);
89
- const binaryPath = path.join(cachePath, platform === 'win32' ? 'mandor.exe' : 'mandor');
87
+ const binaryPath = path.join(INSTALL_DIR, binaryName);
90
88
 
91
89
  if (fs.existsSync(binaryPath)) {
92
- console.log(`Using cached binary: ${binaryPath}`);
90
+ console.log(`Already installed: ${binaryPath}`);
93
91
  return binaryPath;
94
92
  }
95
93
 
96
94
  console.log('Downloading from GitHub releases...');
97
- const downloadUrl = `https://github.com/${REPO}/releases/download/v${installVersion}/${assetName}`;
98
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mandor-install-'));
99
- const tarball = path.join(tempDir, assetName);
95
+ const downloadUrl = `https://github.com/${REPO}/releases/download/v${installVersion}/${osArch}.tar.gz`;
96
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mandor-'));
97
+ const tarball = path.join(tempDir, `${osArch}.tar.gz`);
100
98
 
101
99
  await downloadFile(downloadUrl, tarball);
102
100
 
103
- if (!fs.existsSync(cachePath)) {
104
- fs.mkdirSync(cachePath, { recursive: true });
105
- }
101
+ fs.mkdirSync(INSTALL_DIR, { recursive: true });
102
+ execSync(`tar -xzf "${tarball}" -C "${tempDir}"`, { stdio: 'inherit' });
106
103
 
107
- execSync(`tar -xzf "${tarball}" -C "${cachePath}"`, { stdio: 'inherit' });
104
+ const extractedBinary = path.join(tempDir, binaryName);
105
+ fs.copyFileSync(extractedBinary, binaryPath);
108
106
  fs.chmodSync(binaryPath, '755');
109
107
 
110
108
  fs.rmSync(tempDir, { recursive: true });
111
109
 
112
110
  console.log(`Installed: ${binaryPath}`);
111
+ console.log('');
112
+ console.log('Add to PATH:');
113
+ console.log(` export PATH="${INSTALL_DIR}:$PATH"`);
113
114
  return binaryPath;
114
115
  }
115
116
 
116
117
  if (require.main === module || process.env.npm_lifecycle_event === 'postinstall') {
117
- const prerelease = process.argv.includes('--prerelease') || process.argv.includes('-p');
118
- install({ prerelease }).catch(error => {
118
+ install().catch(error => {
119
119
  console.error('Failed to install Mandor:', error.message);
120
120
  process.exit(1);
121
121
  });
@@ -1,159 +1,60 @@
1
1
  /**
2
2
  * @fileoverview Version resolution module for Mandor CLI
3
- * @description Resolves the correct binary path based on version and platform
4
- * @version 0.0.2
3
+ * @description Resolves the binary path for the CLI
4
+ * @version 0.0.3
5
5
  */
6
6
 
7
7
  const path = require('path');
8
- const fs = require('fs');
9
8
  const os = require('os');
10
- const { downloadBinary, getCurrentPlatform } = require('./download');
9
+ const https = require('https');
11
10
 
12
11
  const REPO = 'sanxzy/mandor';
13
- const GITHUB_API = 'https://api.github.com';
14
12
  const DEFAULT_VERSION = 'latest';
15
-
16
- function getCachedBinary(version, platform, arch) {
17
- const osArch = `${platform}-${arch}`;
18
- const binaryName = platform === 'win32' ? 'mandor.exe' : 'mandor';
19
- const binaryPath = path.join(os.homedir(), '.mandor', 'bin', version, osArch, binaryName);
20
-
21
- if (fs.existsSync(binaryPath)) {
22
- return binaryPath;
23
- }
24
- return null;
13
+ const INSTALL_DIR = path.join(os.homedir(), '.local', 'bin');
14
+
15
+ function getPlatform() {
16
+ const platform = os.platform();
17
+ const arch = os.arch();
18
+ const platformMap = { darwin: 'darwin', linux: 'linux', win32: 'win32' };
19
+ const archMap = { x64: 'x64', arm64: 'arm64', amd64: 'x64', aarch64: 'arm64' };
20
+ return {
21
+ platform: platformMap[platform] || platform,
22
+ arch: archMap[arch] || arch
23
+ };
25
24
  }
26
25
 
27
26
  async function getLatestVersion(prerelease = false) {
28
27
  const url = prerelease
29
- ? `${GITHUB_API}/repos/${REPO}/releases`
30
- : `${GITHUB_API}/repos/${REPO}/releases/latest`;
31
-
32
- const response = await fetch(url);
33
- if (!response.ok) {
34
- throw new Error(`Failed to fetch releases: ${response.statusText}`);
35
- }
36
- const data = await response.json();
37
- const tagName = Array.isArray(data) ? data[0].tag_name : data.tag_name;
38
- return tagName.replace(/^v/, '');
39
- }
40
-
41
- function cacheBinary(binaryPath, version, platform, arch) {
42
- const osArch = `${platform}-${arch}`;
43
- const cacheDir = path.join(os.homedir(), '.mandor', 'bin', version, osArch);
44
- fs.mkdirSync(cacheDir, { recursive: true });
45
-
46
- const binaryName = platform === 'win32' ? 'mandor.exe' : 'mandor';
47
- const destPath = path.join(cacheDir, binaryName);
48
-
49
- fs.copyFileSync(binaryPath, destPath);
50
- fs.chmodSync(destPath, '755');
51
- }
52
-
53
- async function resolve(options = {}) {
54
- const version = options.version || DEFAULT_VERSION;
55
- const { platform, arch } = getCurrentPlatform();
56
- const prerelease = options.prerelease || false;
57
-
58
- let resolveVersion = version;
59
- if (version === 'latest') {
60
- resolveVersion = await getLatestVersion(prerelease);
61
- }
62
-
63
- const cachedPath = getCachedBinary(resolveVersion, platform, arch);
64
- if (cachedPath && !options.forceDownload) {
65
- return cachedPath;
66
- }
67
-
68
- const osArch = `${platform}-${arch}`;
69
- const downloadUrl = `https://github.com/${REPO}/releases/download/v${resolveVersion}/${osArch}.tar.gz`;
70
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mandor-download-'));
71
- const tarball = path.join(tempDir, `${osArch}.tar.gz`);
72
-
73
- console.log(`Downloading Mandor ${resolveVersion}...`);
74
-
75
- const response = await fetch(downloadUrl);
76
- if (!response.ok) {
77
- fs.rmSync(tempDir, { recursive: true });
78
- throw new Error(`Download failed: ${response.statusText}`);
79
- }
80
-
81
- const file = fs.createWriteStream(tarball);
82
- await new Promise((resolve, reject) => {
83
- response.body.pipe(file);
84
- file.on('finish', resolve);
85
- file.on('error', reject);
86
- });
87
-
88
- const binaryName = platform === 'win32' ? 'mandor.exe' : 'mandor';
89
- const cacheDir = path.join(os.homedir(), '.mandor', 'bin', resolveVersion, osArch);
90
- fs.mkdirSync(cacheDir, { recursive: true });
91
-
92
- const { execSync } = require('child_process');
93
- execSync(`tar -xzf "${tarball}" -C "${cacheDir}"`, { stdio: 'pipe' });
94
- fs.chmodSync(path.join(cacheDir, binaryName), '755');
95
-
96
- fs.rmSync(tempDir, { recursive: true });
97
-
98
- return path.join(cacheDir, binaryName);
99
- }
100
-
101
- function listCachedBinaries() {
102
- const cacheDir = path.join(os.homedir(), '.mandor', 'bin');
103
-
104
- if (!fs.existsSync(cacheDir)) {
105
- return [];
106
- }
107
-
108
- const versions = [];
109
- const entries = fs.readdirSync(cacheDir);
110
-
111
- for (const entry of entries) {
112
- const versionPath = path.join(cacheDir, entry);
113
- if (fs.statSync(versionPath).isDirectory()) {
114
- const subEntries = fs.readdirSync(versionPath);
115
- for (const subEntry of subEntries) {
116
- const subPath = path.join(versionPath, subEntry);
117
- if (fs.statSync(subPath).isDirectory()) {
118
- const parts = subEntry.split('-');
119
- const arch = parts.pop();
120
- const platform = parts.join('-');
121
- versions.push({ version: entry, platform, arch, path: subPath });
28
+ ? `https://api.github.com/repos/${REPO}/releases`
29
+ : `https://api.github.com/repos/${REPO}/releases/latest`;
30
+
31
+ return new Promise((resolve, reject) => {
32
+ https.get(url, { headers: { 'User-Agent': 'Mandor-CLI' } }, (res) => {
33
+ let data = '';
34
+ res.on('data', chunk => data += chunk);
35
+ res.on('end', () => {
36
+ try {
37
+ const parsed = JSON.parse(data);
38
+ const tagName = Array.isArray(parsed) ? parsed[0].tag_name : parsed.tag_name;
39
+ resolve(tagName.replace(/^v/, ''));
40
+ } catch (e) {
41
+ reject(e);
122
42
  }
123
- }
124
- }
125
- }
126
-
127
- return versions;
43
+ });
44
+ }).on('error', reject);
45
+ });
128
46
  }
129
47
 
130
- function clearCache() {
131
- const cacheDir = path.join(os.homedir(), '.mandor', 'bin');
132
-
133
- if (!fs.existsSync(cacheDir)) {
134
- return 0;
135
- }
136
-
137
- const entries = fs.readdirSync(cacheDir);
138
- let removed = 0;
139
-
140
- for (const entry of entries) {
141
- const entryPath = path.join(cacheDir, entry);
142
- if (fs.statSync(entryPath).isDirectory()) {
143
- fs.rmSync(entryPath, { recursive: true, force: true });
144
- removed++;
145
- }
146
- }
147
-
148
- return removed;
48
+ function getBinaryPath(version = DEFAULT_VERSION) {
49
+ const { platform, arch } = getPlatform();
50
+ const binaryName = platform === 'win32' ? 'mandor.exe' : 'mandor';
51
+ return path.join(INSTALL_DIR, binaryName);
149
52
  }
150
53
 
151
54
  module.exports = {
152
- resolve,
153
- getCachedBinary,
154
- cacheBinary,
155
- listCachedBinaries,
156
- clearCache,
55
+ getPlatform,
56
+ getLatestVersion,
57
+ getBinaryPath,
157
58
  DEFAULT_VERSION,
158
- getLatestVersion
59
+ INSTALL_DIR
159
60
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mandors/cli",
3
- "version": "0.0.18",
3
+ "version": "0.0.19",
4
4
  "description": "Event-based task manager CLI for AI agent workflows",
5
5
  "main": "npm/lib/index.js",
6
6
  "bin": {