@mandors/cli 0.0.19 → 0.0.21
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/npm/bin/mandor +9 -26
- package/npm/lib/index.js +9 -126
- package/npm/lib/install.js +12 -16
- package/package.json +1 -1
- package/npm/lib/api.js +0 -216
- package/npm/lib/download.js +0 -83
- package/npm/lib/resolve.js +0 -60
package/npm/bin/mandor
CHANGED
|
@@ -1,32 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* @fileoverview Mandor CLI Node.js wrapper script
|
|
5
|
-
* @description Resolves the Mandor binary path and spawns the CLI with provided arguments
|
|
6
|
-
* @version 0.0.1
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const { resolve } = require('../lib/resolve');
|
|
10
3
|
const { spawn } = require('child_process');
|
|
11
4
|
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
12
6
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* @async
|
|
16
|
-
* @returns {Promise<void>} Resolves when the CLI process exits
|
|
17
|
-
* @throws {Error} If binary resolution fails
|
|
18
|
-
* @example
|
|
19
|
-
* // Run: mandor task list --project api
|
|
20
|
-
* await main();
|
|
21
|
-
*/
|
|
22
|
-
async function main() {
|
|
23
|
-
const binaryPath = await resolve();
|
|
24
|
-
const args = process.argv.slice(2);
|
|
25
|
-
const proc = spawn(binaryPath, args, {
|
|
26
|
-
stdio: 'inherit',
|
|
27
|
-
cwd: process.cwd()
|
|
28
|
-
});
|
|
29
|
-
proc.on('exit', process.exit);
|
|
30
|
-
}
|
|
7
|
+
const INSTALL_DIR = path.join(os.homedir(), '.local', 'bin');
|
|
8
|
+
const binaryPath = path.join(INSTALL_DIR, process.platform === 'win32' ? 'mandor.exe' : 'mandor');
|
|
31
9
|
|
|
32
|
-
|
|
10
|
+
const args = process.argv.slice(2);
|
|
11
|
+
const proc = spawn(binaryPath, args, {
|
|
12
|
+
stdio: 'inherit',
|
|
13
|
+
cwd: process.cwd()
|
|
14
|
+
});
|
|
15
|
+
proc.on('exit', process.exit);
|
package/npm/lib/index.js
CHANGED
|
@@ -1,138 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Mandor CLI npm package entry point
|
|
3
|
-
* @description Main export for
|
|
4
|
-
* @version 0.0.
|
|
3
|
+
* @description Main export for CLI access
|
|
4
|
+
* @version 0.0.2
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
const Mandor = require('./api');
|
|
8
|
-
const MandorConfig = require('./config');
|
|
9
|
-
const { resolve, listCachedBinaries, clearCache } = require('./resolve');
|
|
10
|
-
const { downloadBinary, getCurrentPlatform } = require('./download');
|
|
11
7
|
const { install } = require('./install');
|
|
8
|
+
const MandorConfig = require('./config');
|
|
12
9
|
|
|
13
|
-
/**
|
|
14
|
-
* Main export object containing all public APIs
|
|
15
|
-
* @namespace mandor
|
|
16
|
-
* @version 0.0.1
|
|
17
|
-
* @example
|
|
18
|
-
* const mandor = require('@mandor/cli');
|
|
19
|
-
*
|
|
20
|
-
* // CLI access via npx or npm script
|
|
21
|
-
* // $ npx mandor init "My Project"
|
|
22
|
-
*
|
|
23
|
-
* // Programmatic usage
|
|
24
|
-
* const cli = new mandor.Mandor({ json: true });
|
|
25
|
-
* await cli.init('My Project');
|
|
26
|
-
*/
|
|
27
10
|
module.exports = {
|
|
28
|
-
/**
|
|
29
|
-
* Mandor CLI wrapper class for programmatic access
|
|
30
|
-
* @type {typeof Mandor}
|
|
31
|
-
* @memberof mandor
|
|
32
|
-
* @example
|
|
33
|
-
* const mandor = require('@mandor/cli');
|
|
34
|
-
* const cli = new mandor.Mandor({ json: true });
|
|
35
|
-
*/
|
|
36
|
-
Mandor,
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Configuration management class
|
|
40
|
-
* @type {typeof MandorConfig}
|
|
41
|
-
* @memberof mandor
|
|
42
|
-
* @example
|
|
43
|
-
* const config = new mandor.MandorConfig('/path/to/project');
|
|
44
|
-
* const priority = config.get('priority.default', 'P3');
|
|
45
|
-
*/
|
|
46
11
|
MandorConfig,
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Resolves the Mandor binary path
|
|
50
|
-
* @function
|
|
51
|
-
* @param {Object} [options] - Resolution options
|
|
52
|
-
* @param {string} [options.version] - Version to use
|
|
53
|
-
* @returns {Promise<string>} Path to binary
|
|
54
|
-
* @memberof mandor
|
|
55
|
-
* @example
|
|
56
|
-
* const binaryPath = await mandor.resolve({ version: 'latest' });
|
|
57
|
-
*/
|
|
58
|
-
resolve,
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Lists all cached binary versions
|
|
62
|
-
* @function
|
|
63
|
-
* @returns {Object[]} Cached binary info
|
|
64
|
-
* @memberof mandor
|
|
65
|
-
* @example
|
|
66
|
-
* const cached = mandor.listCachedBinaries();
|
|
67
|
-
*/
|
|
68
|
-
listCachedBinaries,
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Clears all cached binaries
|
|
72
|
-
* @function
|
|
73
|
-
* @returns {number} Number of binaries removed
|
|
74
|
-
* @memberof mandor
|
|
75
|
-
* @example
|
|
76
|
-
* const removed = mandor.clearCache();
|
|
77
|
-
*/
|
|
78
|
-
clearCache,
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Downloads a Mandor binary
|
|
82
|
-
* @function
|
|
83
|
-
* @param {string} version - Version to download
|
|
84
|
-
* @param {string} [platform] - Target platform
|
|
85
|
-
* @param {string} [arch] - Target architecture
|
|
86
|
-
* @returns {Promise<string>} Path to downloaded binary
|
|
87
|
-
* @memberof mandor
|
|
88
|
-
* @example
|
|
89
|
-
* const binary = await mandor.downloadBinary('1.0.0', 'darwin', 'x64');
|
|
90
|
-
*/
|
|
91
|
-
downloadBinary,
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Gets current platform information
|
|
95
|
-
* @function
|
|
96
|
-
* @returns {{platform: string, arch: string}} Platform info
|
|
97
|
-
* @memberof mandor
|
|
98
|
-
* @example
|
|
99
|
-
* const { platform, arch } = mandor.getCurrentPlatform();
|
|
100
|
-
*/
|
|
101
|
-
getCurrentPlatform,
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Runs post-install setup
|
|
105
|
-
* @function
|
|
106
|
-
* @param {Object} [options] - Install options
|
|
107
|
-
* @returns {Promise<string>} Path to installed binary
|
|
108
|
-
* @memberof mandor
|
|
109
|
-
* @example
|
|
110
|
-
* await mandor.install({ version: 'latest' });
|
|
111
|
-
*/
|
|
112
12
|
install,
|
|
113
|
-
|
|
114
|
-
// Version info
|
|
115
|
-
/** @type {string} Package version */
|
|
116
|
-
version: '0.0.1',
|
|
117
|
-
|
|
118
|
-
/** @type {string} Supported Mandor version range */
|
|
119
|
-
mandorVersionRange: '>=0.0.1'
|
|
13
|
+
version: '0.0.2'
|
|
120
14
|
};
|
|
121
15
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
.
|
|
126
|
-
|
|
127
|
-
const args = process.argv.slice(2);
|
|
128
|
-
const proc = spawn(binaryPath, args, {
|
|
129
|
-
stdio: 'inherit',
|
|
130
|
-
cwd: process.cwd()
|
|
131
|
-
});
|
|
132
|
-
proc.on('exit', process.exit);
|
|
133
|
-
})
|
|
134
|
-
.catch(error => {
|
|
135
|
-
console.error('Failed to start Mandor:', error.message);
|
|
136
|
-
process.exit(1);
|
|
137
|
-
});
|
|
16
|
+
if (require.main === module || process.env.npm_lifecycle_event === 'postinstall') {
|
|
17
|
+
install().catch(error => {
|
|
18
|
+
console.error('Failed to install Mandor:', error.message);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
});
|
|
138
21
|
}
|
package/npm/lib/install.js
CHANGED
|
@@ -25,9 +25,7 @@ function getPlatform() {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
async function getLatestVersion(prerelease = false) {
|
|
28
|
-
const url =
|
|
29
|
-
? `https://api.github.com/repos/${REPO}/releases`
|
|
30
|
-
: `https://api.github.com/repos/${REPO}/releases/latest`;
|
|
28
|
+
const url = `https://api.github.com/repos/${REPO}/releases`;
|
|
31
29
|
|
|
32
30
|
return new Promise((resolve, reject) => {
|
|
33
31
|
https.get(url, { headers: { 'User-Agent': 'Mandor-CLI' } }, (res) => {
|
|
@@ -36,8 +34,12 @@ async function getLatestVersion(prerelease = false) {
|
|
|
36
34
|
res.on('end', () => {
|
|
37
35
|
try {
|
|
38
36
|
const parsed = JSON.parse(data);
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
if (Array.isArray(parsed) && parsed.length > 0) {
|
|
38
|
+
const release = parsed[0];
|
|
39
|
+
resolve(release.tag_name.replace(/^v/, ''));
|
|
40
|
+
} else {
|
|
41
|
+
reject(new Error('No release found'));
|
|
42
|
+
}
|
|
41
43
|
} catch (e) {
|
|
42
44
|
reject(e);
|
|
43
45
|
}
|
|
@@ -64,10 +66,8 @@ function downloadFile(url, dest) {
|
|
|
64
66
|
});
|
|
65
67
|
}
|
|
66
68
|
|
|
67
|
-
async function install(
|
|
69
|
+
async function install() {
|
|
68
70
|
const { platform, arch } = getPlatform();
|
|
69
|
-
const version = options.version || 'latest';
|
|
70
|
-
const prerelease = options.prerelease || false;
|
|
71
71
|
const osArch = `${platform}-${arch}`;
|
|
72
72
|
const binaryName = platform === 'win32' ? 'mandor.exe' : 'mandor';
|
|
73
73
|
|
|
@@ -75,13 +75,9 @@ async function install(options = {}) {
|
|
|
75
75
|
console.log('================');
|
|
76
76
|
console.log(`OS: ${osArch}`);
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
installVersion = await getLatestVersion(prerelease);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
console.log(`Version: ${installVersion}`);
|
|
78
|
+
console.log('Fetching latest release...');
|
|
79
|
+
const version = await getLatestVersion();
|
|
80
|
+
console.log(`Version: ${version}`);
|
|
85
81
|
console.log('');
|
|
86
82
|
|
|
87
83
|
const binaryPath = path.join(INSTALL_DIR, binaryName);
|
|
@@ -92,7 +88,7 @@ async function install(options = {}) {
|
|
|
92
88
|
}
|
|
93
89
|
|
|
94
90
|
console.log('Downloading from GitHub releases...');
|
|
95
|
-
const downloadUrl = `https://github.com/${REPO}/releases/download/v${
|
|
91
|
+
const downloadUrl = `https://github.com/${REPO}/releases/download/v${version}/${osArch}.tar.gz`;
|
|
96
92
|
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mandor-'));
|
|
97
93
|
const tarball = path.join(tempDir, `${osArch}.tar.gz`);
|
|
98
94
|
|
package/package.json
CHANGED
package/npm/lib/api.js
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Mandor CLI programmatic API
|
|
3
|
-
* @description Node.js API for interacting with Mandor from JavaScript/TypeScript code
|
|
4
|
-
* @version 0.0.1
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const { spawn } = require('child_process');
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @typedef {Object} MandorOptions
|
|
11
|
-
* @property {string} [cwd] - Working directory (default: process.cwd())
|
|
12
|
-
* @property {boolean} [json] - Use JSON output format (default: false)
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @typedef {Object} ProjectCreateOptions
|
|
17
|
-
* @property {string} [name] - Project display name
|
|
18
|
-
* @property {string} [goal] - Project goal description
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @typedef {Object} TaskListOptions
|
|
23
|
-
* @property {string} [project] - Filter by project ID
|
|
24
|
-
* @property {string} [feature] - Filter by feature ID
|
|
25
|
-
* @property {string} [status] - Filter by status (pending, ready, in_progress, done, blocked, cancelled)
|
|
26
|
-
* @property {string} [priority] - Filter by priority (P0-P5)
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Mandor CLI wrapper class for programmatic access
|
|
31
|
-
* @class
|
|
32
|
-
* @version 0.0.1
|
|
33
|
-
* @example
|
|
34
|
-
* const mandor = new Mandor({ cwd: '/path/to/project', json: true });
|
|
35
|
-
* const tasks = await mandor.taskList({ project: 'api', status: 'pending' });
|
|
36
|
-
*/
|
|
37
|
-
class Mandor {
|
|
38
|
-
/**
|
|
39
|
-
* Creates a new Mandor instance
|
|
40
|
-
* @constructor
|
|
41
|
-
* @param {MandorOptions} [options] - Configuration options
|
|
42
|
-
* @example
|
|
43
|
-
* const mandor = new Mandor({ cwd: '/my/project', json: true });
|
|
44
|
-
*/
|
|
45
|
-
constructor(options = {}) {
|
|
46
|
-
/** @type {string} Working directory */
|
|
47
|
-
this.cwd = options.cwd || process.cwd();
|
|
48
|
-
/** @type {boolean} Use JSON output */
|
|
49
|
-
this.json = options.json || false;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Initializes a new Mandor workspace
|
|
54
|
-
* @async
|
|
55
|
-
* @param {string} name - Workspace name
|
|
56
|
-
* @returns {Promise<number>} Exit code from the CLI
|
|
57
|
-
* @throws {Error} If initialization fails
|
|
58
|
-
* @example
|
|
59
|
-
* await mandor.init('My AI Project');
|
|
60
|
-
*/
|
|
61
|
-
async init(name) {
|
|
62
|
-
return this._run('init', [name]);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Creates a new project
|
|
67
|
-
* @async
|
|
68
|
-
* @param {string} id - Project identifier (lowercase, hyphens only)
|
|
69
|
-
* @param {ProjectCreateOptions} [options] - Project options
|
|
70
|
-
* @returns {Promise<number>} Exit code from the CLI
|
|
71
|
-
* @example
|
|
72
|
-
* await mandor.projectCreate('api', {
|
|
73
|
-
* name: 'API Service',
|
|
74
|
-
* goal: 'Implement REST API with user management'
|
|
75
|
-
* });
|
|
76
|
-
*/
|
|
77
|
-
async projectCreate(id, options = {}) {
|
|
78
|
-
const args = ['project', 'create', id];
|
|
79
|
-
if (options.name) args.push('--name', options.name);
|
|
80
|
-
if (options.goal) args.push('--goal', options.goal);
|
|
81
|
-
return this._run(...args);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Lists tasks with optional filters
|
|
86
|
-
* @async
|
|
87
|
-
* @param {TaskListOptions} [options] - Filter options
|
|
88
|
-
* @returns {Promise<Object[]|number>} Task list (JSON) or exit code
|
|
89
|
-
* @example
|
|
90
|
-
* const tasks = await mandor.taskList({
|
|
91
|
-
* project: 'api',
|
|
92
|
-
* status: 'pending',
|
|
93
|
-
* json: true
|
|
94
|
-
* });
|
|
95
|
-
*/
|
|
96
|
-
async taskList(options = {}) {
|
|
97
|
-
const args = ['task', 'list'];
|
|
98
|
-
if (options.project) args.push('--project', options.project);
|
|
99
|
-
if (options.feature) args.push('--feature', options.feature);
|
|
100
|
-
if (options.status) args.push('--status', options.status);
|
|
101
|
-
if (options.priority) args.push('--priority', options.priority);
|
|
102
|
-
if (options.json) args.push('--json');
|
|
103
|
-
return this._run(...args);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Gets detailed information about a task
|
|
108
|
-
* @async
|
|
109
|
-
* @param {string} taskId - Task identifier
|
|
110
|
-
* @returns {Promise<Object|number>} Task details (JSON) or exit code
|
|
111
|
-
* @example
|
|
112
|
-
* const task = await mandor.taskDetail('api-feature-abc-task-xyz789', { json: true });
|
|
113
|
-
*/
|
|
114
|
-
async taskDetail(taskId) {
|
|
115
|
-
return this._run('task', 'detail', taskId);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Updates a task's status or metadata
|
|
120
|
-
* @async
|
|
121
|
-
* @param {string} taskId - Task identifier
|
|
122
|
-
* @param {Object} updates - Fields to update
|
|
123
|
-
* @returns {Promise<number>} Exit code from the CLI
|
|
124
|
-
* @example
|
|
125
|
-
* await mandor.taskUpdate('api-feature-abc-task-xyz789', {
|
|
126
|
-
* status: 'in_progress'
|
|
127
|
-
* });
|
|
128
|
-
*/
|
|
129
|
-
async taskUpdate(taskId, updates = {}) {
|
|
130
|
-
const args = ['task', 'update', taskId];
|
|
131
|
-
if (updates.status) args.push('--status', updates.status);
|
|
132
|
-
if (updates.name) args.push('--name', updates.name);
|
|
133
|
-
if (updates.priority) args.push('--priority', updates.priority);
|
|
134
|
-
return this._run(...args);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Lists features with optional filters
|
|
139
|
-
* @async
|
|
140
|
-
* @param {Object} [options] - Filter options
|
|
141
|
-
* @returns {Promise<Object[]|number>} Feature list (JSON) or exit code
|
|
142
|
-
* @example
|
|
143
|
-
* const features = await mandor.featureList({ project: 'api', json: true });
|
|
144
|
-
*/
|
|
145
|
-
async featureList(options = {}) {
|
|
146
|
-
const args = ['feature', 'list'];
|
|
147
|
-
if (options.project) args.push('--project', options.project);
|
|
148
|
-
if (options.status) args.push('--status', options.status);
|
|
149
|
-
if (options.json) args.push('--json');
|
|
150
|
-
return this._run(...args);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Lists issues with optional filters
|
|
155
|
-
* @async
|
|
156
|
-
* @param {Object} [options] - Filter options
|
|
157
|
-
* @returns {Promise<Object[]|number>} Issue list (JSON) or exit code
|
|
158
|
-
* @example
|
|
159
|
-
* const issues = await mandor.issueList({ project: 'api', type: 'bug', json: true });
|
|
160
|
-
*/
|
|
161
|
-
async issueList(options = {}) {
|
|
162
|
-
const args = ['issue', 'list'];
|
|
163
|
-
if (options.project) args.push('--project', options.project);
|
|
164
|
-
if (options.type) args.push('--type', options.type);
|
|
165
|
-
if (options.status) args.push('--status', options.status);
|
|
166
|
-
if (options.json) args.push('--json');
|
|
167
|
-
return this._run(...args);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Gets workspace status and statistics
|
|
172
|
-
* @async
|
|
173
|
-
* @param {Object} [options] - Options
|
|
174
|
-
* @returns {Promise<Object|number>} Status (JSON) or exit code
|
|
175
|
-
* @example
|
|
176
|
-
* const status = await mandor.status({ json: true });
|
|
177
|
-
*/
|
|
178
|
-
async status(options = {}) {
|
|
179
|
-
const args = ['status'];
|
|
180
|
-
if (options.json) args.push('--json');
|
|
181
|
-
return this._run(...args);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Internal method to run mandor CLI commands
|
|
186
|
-
* @private
|
|
187
|
-
* @async
|
|
188
|
-
* @param {...string} args - Command arguments
|
|
189
|
-
* @returns {Promise<Object|number>} Result based on json option
|
|
190
|
-
* @throws {Error} If process fails
|
|
191
|
-
*/
|
|
192
|
-
_run(...args) {
|
|
193
|
-
return new Promise((resolve, reject) => {
|
|
194
|
-
const proc = spawn('mandor', args, {
|
|
195
|
-
cwd: this.cwd,
|
|
196
|
-
stdio: this.json ? 'pipe' : 'inherit'
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
if (this.json) {
|
|
200
|
-
let data = '';
|
|
201
|
-
proc.stdout.on('data', chunk => data += chunk);
|
|
202
|
-
proc.on('close', (code) => {
|
|
203
|
-
try {
|
|
204
|
-
resolve(JSON.parse(data));
|
|
205
|
-
} catch {
|
|
206
|
-
resolve(data);
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
|
-
} else {
|
|
210
|
-
proc.on('close', resolve);
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
module.exports = Mandor;
|
package/npm/lib/download.js
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Binary download module for Mandor CLI
|
|
3
|
-
* @description Handles downloading and caching Mandor binaries for the current platform
|
|
4
|
-
* @version 0.0.1
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const https = require('https');
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const path = require('path');
|
|
10
|
-
const os = require('os');
|
|
11
|
-
|
|
12
|
-
/** @type {string} GitHub releases API URL */
|
|
13
|
-
const RELEASES_URL = 'https://api.github.com/repos/sanxzy/mandor/releases';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Downloads the Mandor binary for the specified platform and architecture
|
|
17
|
-
* @async
|
|
18
|
-
* @param {string} version - The Mandor version to download (e.g., '1.0.0', 'latest')
|
|
19
|
-
* @param {string} platform - Target platform (e.g., 'darwin', 'linux', 'win32')
|
|
20
|
-
* @param {string} arch - Target architecture (e.g., 'x64', 'arm64')
|
|
21
|
-
* @returns {Promise<string>} Path to the downloaded and executable binary
|
|
22
|
-
* @throws {Error} If download fails or platform is unsupported
|
|
23
|
-
* @example
|
|
24
|
-
* // Download Mandor v1.0.0 for macOS x64
|
|
25
|
-
* const binaryPath = await downloadBinary('1.0.0', 'darwin', 'x64');
|
|
26
|
-
* console.log(`Binary downloaded to: ${binaryPath}`);
|
|
27
|
-
*/
|
|
28
|
-
async function downloadBinary(version, platform, arch) {
|
|
29
|
-
const filename = `mandor-${platform}-${arch}`;
|
|
30
|
-
const url = `${RELEASES_URL}/download/${version}/${filename}`;
|
|
31
|
-
const dest = path.join(os.homedir(), '.mandor', 'bin', filename);
|
|
32
|
-
|
|
33
|
-
// Download and make executable
|
|
34
|
-
return new Promise((resolve, reject) => {
|
|
35
|
-
https.get(url, (response) => {
|
|
36
|
-
if (response.statusCode === 302) {
|
|
37
|
-
return downloadBinary(response.headers.location, platform, arch);
|
|
38
|
-
}
|
|
39
|
-
const file = fs.createWriteStream(dest);
|
|
40
|
-
response.pipe(file);
|
|
41
|
-
file.on('finish', () => {
|
|
42
|
-
fs.chmodSync(dest, '755');
|
|
43
|
-
resolve(dest);
|
|
44
|
-
});
|
|
45
|
-
}).on('error', reject);
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Gets the platform identifier for the current system
|
|
51
|
-
* @returns {{platform: string, arch: string}} Platform and architecture info
|
|
52
|
-
* @example
|
|
53
|
-
* const { platform, arch } = getCurrentPlatform();
|
|
54
|
-
* console.log(`Running on ${platform}-${arch}`);
|
|
55
|
-
*/
|
|
56
|
-
function getCurrentPlatform() {
|
|
57
|
-
const platform = os.platform(); // 'darwin', 'linux', 'win32'
|
|
58
|
-
const arch = os.arch(); // 'x64', 'arm64'
|
|
59
|
-
return { platform, arch };
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Checks if a binary already exists and is up-to-date
|
|
64
|
-
* @param {string} version - Expected version
|
|
65
|
-
* @param {string} platform - Target platform
|
|
66
|
-
* @param {string} arch - Target architecture
|
|
67
|
-
* @returns {Promise<boolean>} True if binary exists and is valid
|
|
68
|
-
* @example
|
|
69
|
-
* const exists = await binaryExists('1.0.0', 'darwin', 'x64');
|
|
70
|
-
* if (exists) { console.log('Binary cached'); }
|
|
71
|
-
*/
|
|
72
|
-
async function binaryExists(version, platform, arch) {
|
|
73
|
-
const filename = `mandor-${platform}-${arch}`;
|
|
74
|
-
const dest = path.join(os.homedir(), '.mandor', 'bin', filename);
|
|
75
|
-
return fs.existsSync(dest);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
module.exports = {
|
|
79
|
-
downloadBinary,
|
|
80
|
-
getCurrentPlatform,
|
|
81
|
-
binaryExists,
|
|
82
|
-
RELEASES_URL
|
|
83
|
-
};
|
package/npm/lib/resolve.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Version resolution module for Mandor CLI
|
|
3
|
-
* @description Resolves the binary path for the CLI
|
|
4
|
-
* @version 0.0.3
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const path = require('path');
|
|
8
|
-
const os = require('os');
|
|
9
|
-
const https = require('https');
|
|
10
|
-
|
|
11
|
-
const REPO = 'sanxzy/mandor';
|
|
12
|
-
const DEFAULT_VERSION = 'latest';
|
|
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
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async function getLatestVersion(prerelease = false) {
|
|
27
|
-
const url = prerelease
|
|
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);
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
}).on('error', reject);
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
|
|
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);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
module.exports = {
|
|
55
|
-
getPlatform,
|
|
56
|
-
getLatestVersion,
|
|
57
|
-
getBinaryPath,
|
|
58
|
-
DEFAULT_VERSION,
|
|
59
|
-
INSTALL_DIR
|
|
60
|
-
};
|