mtrx-cli 0.1.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 +32 -0
- package/bin/mtrx.js +111 -0
- package/package.json +34 -0
- package/src/matrx/__init__.py +1 -0
- package/src/matrx/cli/__init__.py +2 -0
- package/src/matrx/cli/launcher.py +796 -0
- package/src/matrx/cli/main.py +510 -0
- package/src/matrx/cli/state.py +291 -0
package/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# `mtrx-cli`
|
|
2
|
+
|
|
3
|
+
`mtrx-cli` installs the `mtrx` command from npm.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
Global install:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g mtrx-cli
|
|
11
|
+
mtrx help
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
One-off execution:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx mtrx-cli help
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Local project install:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install --save-dev mtrx-cli
|
|
24
|
+
npx mtrx help
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Requirements
|
|
28
|
+
|
|
29
|
+
- Node.js 18+
|
|
30
|
+
- Python 3.10+ available as `python3`, `python`, or `py -3`
|
|
31
|
+
|
|
32
|
+
This npm package is a thin wrapper around the Python CLI bundled in this repo.
|
package/bin/mtrx.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { spawnSync } = require('node:child_process');
|
|
5
|
+
const path = require('node:path');
|
|
6
|
+
|
|
7
|
+
const packageRoot = path.resolve(__dirname, '..');
|
|
8
|
+
const pythonPathEntry = path.join(packageRoot, 'src');
|
|
9
|
+
const cliArgs = process.argv.slice(2);
|
|
10
|
+
|
|
11
|
+
function pythonCandidates() {
|
|
12
|
+
if (process.platform === 'win32') {
|
|
13
|
+
return [
|
|
14
|
+
{ command: 'py', prefixArgs: ['-3'] },
|
|
15
|
+
{ command: 'python', prefixArgs: [] },
|
|
16
|
+
{ command: 'python3', prefixArgs: [] },
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
return [
|
|
20
|
+
{ command: 'python3', prefixArgs: [] },
|
|
21
|
+
{ command: 'python', prefixArgs: [] },
|
|
22
|
+
];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function probePython(candidate) {
|
|
26
|
+
const result = spawnSync(
|
|
27
|
+
candidate.command,
|
|
28
|
+
[
|
|
29
|
+
...candidate.prefixArgs,
|
|
30
|
+
'-c',
|
|
31
|
+
'import json,sys; print(json.dumps({"major": sys.version_info[0], "minor": sys.version_info[1]}))',
|
|
32
|
+
],
|
|
33
|
+
{
|
|
34
|
+
encoding: 'utf8',
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
if (result.error || result.status !== 0) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
const version = JSON.parse((result.stdout || '').trim());
|
|
44
|
+
return { ...candidate, version };
|
|
45
|
+
} catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function findPython() {
|
|
51
|
+
let bestUnsupported = null;
|
|
52
|
+
|
|
53
|
+
for (const candidate of pythonCandidates()) {
|
|
54
|
+
const probed = probePython(candidate);
|
|
55
|
+
if (!probed) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const { major, minor } = probed.version;
|
|
59
|
+
if (major > 3 || (major === 3 && minor >= 10)) {
|
|
60
|
+
return probed;
|
|
61
|
+
}
|
|
62
|
+
if (!bestUnsupported) {
|
|
63
|
+
bestUnsupported = probed;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return bestUnsupported;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function buildEnv() {
|
|
71
|
+
const env = { ...process.env };
|
|
72
|
+
const existingPythonPath = env.PYTHONPATH;
|
|
73
|
+
env.PYTHONPATH = existingPythonPath
|
|
74
|
+
? `${pythonPathEntry}${path.delimiter}${existingPythonPath}`
|
|
75
|
+
: pythonPathEntry;
|
|
76
|
+
return env;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function fail(message) {
|
|
80
|
+
console.error(message);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const python = findPython();
|
|
85
|
+
|
|
86
|
+
if (!python) {
|
|
87
|
+
fail(
|
|
88
|
+
'mtrx-cli requires Python 3.10+ in PATH. Install Python 3.10+ and retry.',
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (python.version.major < 3 || (python.version.major === 3 && python.version.minor < 10)) {
|
|
93
|
+
fail(
|
|
94
|
+
`mtrx-cli requires Python 3.10+. Found ${python.command} ${python.version.major}.${python.version.minor}.`,
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const result = spawnSync(
|
|
99
|
+
python.command,
|
|
100
|
+
[...python.prefixArgs, '-m', 'matrx.cli.main', ...cliArgs],
|
|
101
|
+
{
|
|
102
|
+
stdio: 'inherit',
|
|
103
|
+
env: buildEnv(),
|
|
104
|
+
},
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
if (result.error) {
|
|
108
|
+
fail(`Failed to launch the Python MATRX CLI: ${result.error.message}`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
process.exit(result.status === null ? 1 : result.status);
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mtrx-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MATRX CLI for routing Codex and Claude through Matrx",
|
|
5
|
+
"homepage": "https://mtrx.so",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/vinaynarahari/matrx.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/vinaynarahari/matrx/issues"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"matrx",
|
|
15
|
+
"cli",
|
|
16
|
+
"codex",
|
|
17
|
+
"claude",
|
|
18
|
+
"ai"
|
|
19
|
+
],
|
|
20
|
+
"bin": {
|
|
21
|
+
"mtrx": "bin/mtrx.js"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"bin/mtrx.js",
|
|
25
|
+
"src/matrx/__init__.py",
|
|
26
|
+
"src/matrx/cli/__init__.py",
|
|
27
|
+
"src/matrx/cli/launcher.py",
|
|
28
|
+
"src/matrx/cli/main.py",
|
|
29
|
+
"src/matrx/cli/state.py"
|
|
30
|
+
],
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=18"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|