@mandors/cli 0.0.19 → 0.0.20

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 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
- * Main entry point for the Mandor CLI wrapper
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
- main().catch(console.error);
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 programmatic usage and CLI access
4
- * @version 0.0.1
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
- // CLI entry point when bin/mandor is executed
123
- if (require.main === module) {
124
- resolve()
125
- .then(binaryPath => {
126
- const { spawn } = require('child_process');
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
  }
@@ -36,8 +36,17 @@ async function getLatestVersion(prerelease = false) {
36
36
  res.on('end', () => {
37
37
  try {
38
38
  const parsed = JSON.parse(data);
39
- const tagName = Array.isArray(parsed) ? parsed[0].tag_name : parsed.tag_name;
40
- resolve(tagName.replace(/^v/, ''));
39
+ let tagName = null;
40
+ if (parsed && parsed.tag_name) {
41
+ tagName = parsed.tag_name;
42
+ } else if (Array.isArray(parsed) && parsed.length > 0 && parsed[0].tag_name) {
43
+ tagName = parsed[0].tag_name;
44
+ }
45
+ if (tagName) {
46
+ resolve(tagName.replace(/^v/, ''));
47
+ } else {
48
+ reject(new Error('No release found'));
49
+ }
41
50
  } catch (e) {
42
51
  reject(e);
43
52
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mandors/cli",
3
- "version": "0.0.19",
3
+ "version": "0.0.20",
4
4
  "description": "Event-based task manager CLI for AI agent workflows",
5
5
  "main": "npm/lib/index.js",
6
6
  "bin": {
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;
@@ -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
- };
@@ -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
- };