codexctl 0.1.1
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 +58 -0
- package/bin/poly +13 -0
- package/bin/polycli +13 -0
- package/install.js +123 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# PolyCLI
|
|
2
|
+
|
|
3
|
+
Universal AI CLI Profile Manager - Manage multiple AI CLI accounts (Codex, Claude, Gemini, OpenAI)
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g polycli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or use npx (no install):
|
|
12
|
+
```bash
|
|
13
|
+
npx polycli --help
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Save your current AI CLI profile
|
|
20
|
+
poly codex save work
|
|
21
|
+
poly claude save personal
|
|
22
|
+
|
|
23
|
+
# Switch between profiles
|
|
24
|
+
poly codex load work
|
|
25
|
+
poly claude load personal
|
|
26
|
+
|
|
27
|
+
# List all profiles
|
|
28
|
+
poly list
|
|
29
|
+
|
|
30
|
+
# Quick-switch to previous profile
|
|
31
|
+
poly load -
|
|
32
|
+
|
|
33
|
+
# Auto-switch to best profile based on quota
|
|
34
|
+
poly load auto
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Supported AI CLIs
|
|
38
|
+
|
|
39
|
+
- **Codex CLI** (`poly codex`)
|
|
40
|
+
- **Claude Code** (`poly claude`)
|
|
41
|
+
- **Gemini CLI** (`poly gemini`)
|
|
42
|
+
- **OpenAI CLI** (`poly openai`)
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- 🔐 **Optional Encryption** - age-based encryption for sensitive auth data
|
|
47
|
+
- 🚀 **Fast Switching** - Switch accounts in < 1 second
|
|
48
|
+
- 🤖 **Auto-Switcher** - Automatically pick the best profile based on quota
|
|
49
|
+
- 📊 **Real-Time Quota** - Live usage data from AI provider APIs
|
|
50
|
+
- 🌳 **Concurrent Usage** - Use multiple profiles simultaneously
|
|
51
|
+
|
|
52
|
+
## Documentation
|
|
53
|
+
|
|
54
|
+
Full documentation: https://polycli.repohelper.com
|
|
55
|
+
|
|
56
|
+
## License
|
|
57
|
+
|
|
58
|
+
MIT
|
package/bin/poly
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { spawn } = require('child_process');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const binaryPath = path.join(__dirname, '..', 'bin', 'poly');
|
|
6
|
+
const child = spawn(binaryPath, process.argv.slice(2), {
|
|
7
|
+
stdio: 'inherit',
|
|
8
|
+
windowsHide: true
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
child.on('exit', (code) => {
|
|
12
|
+
process.exit(code);
|
|
13
|
+
});
|
package/bin/polycli
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { spawn } = require('child_process');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const binaryPath = path.join(__dirname, '..', 'bin', 'polycli');
|
|
6
|
+
const child = spawn(binaryPath, process.argv.slice(2), {
|
|
7
|
+
stdio: 'inherit',
|
|
8
|
+
windowsHide: true
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
child.on('exit', (code) => {
|
|
12
|
+
process.exit(code);
|
|
13
|
+
});
|
package/install.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* PolyCLI Installation Script
|
|
4
|
+
* Downloads the appropriate binary for the current platform
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const https = require('https');
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const os = require('os');
|
|
11
|
+
const { execSync } = require('child_process');
|
|
12
|
+
|
|
13
|
+
const VERSION = require('./package.json').version;
|
|
14
|
+
const BINARY_NAME = 'polycli';
|
|
15
|
+
|
|
16
|
+
// Platform mappings
|
|
17
|
+
const platforms = {
|
|
18
|
+
'darwin-x64': 'x86_64-apple-darwin',
|
|
19
|
+
'darwin-arm64': 'aarch64-apple-darwin',
|
|
20
|
+
'linux-x64': 'x86_64-unknown-linux-gnu',
|
|
21
|
+
'linux-arm64': 'aarch64-unknown-linux-gnu',
|
|
22
|
+
'win32-x64': 'x86_64-pc-windows-msvc'
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function getPlatform() {
|
|
26
|
+
const platform = os.platform();
|
|
27
|
+
const arch = os.arch();
|
|
28
|
+
const key = `${platform}-${arch}`;
|
|
29
|
+
|
|
30
|
+
if (!platforms[key]) {
|
|
31
|
+
console.error(`Unsupported platform: ${platform} ${arch}`);
|
|
32
|
+
console.error('Supported platforms:', Object.keys(platforms).join(', '));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return platforms[key];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getDownloadUrl(target) {
|
|
40
|
+
const ext = target.includes('windows') ? 'zip' : 'tar.gz';
|
|
41
|
+
return `https://github.com/repohelper/polycli/releases/download/v${VERSION}/polycli-${target}.${ext}`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function downloadFile(url, dest) {
|
|
45
|
+
return new Promise((resolve, reject) => {
|
|
46
|
+
const file = fs.createWriteStream(dest);
|
|
47
|
+
https.get(url, { followRedirects: true }, (response) => {
|
|
48
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
49
|
+
// Follow redirect
|
|
50
|
+
downloadFile(response.headers.location, dest).then(resolve).catch(reject);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (response.statusCode !== 200) {
|
|
55
|
+
reject(new Error(`Download failed with status ${response.statusCode}`));
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
response.pipe(file);
|
|
60
|
+
file.on('finish', () => {
|
|
61
|
+
file.close();
|
|
62
|
+
resolve();
|
|
63
|
+
});
|
|
64
|
+
}).on('error', reject);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function extractArchive(archivePath, destDir) {
|
|
69
|
+
if (archivePath.endsWith('.zip')) {
|
|
70
|
+
execSync(`unzip -o "${archivePath}" -d "${destDir}"`, { stdio: 'inherit' });
|
|
71
|
+
} else {
|
|
72
|
+
execSync(`tar -xzf "${archivePath}" -C "${destDir}"`, { stdio: 'inherit' });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function install() {
|
|
77
|
+
const binDir = path.join(__dirname, 'bin');
|
|
78
|
+
|
|
79
|
+
// Skip if binaries already exist (development or manual install)
|
|
80
|
+
if (fs.existsSync(path.join(binDir, BINARY_NAME))) {
|
|
81
|
+
console.log('PolyCLI binaries already exist, skipping download');
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Ensure bin directory exists
|
|
86
|
+
if (!fs.existsSync(binDir)) {
|
|
87
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const target = getPlatform();
|
|
91
|
+
const url = getDownloadUrl(target);
|
|
92
|
+
const ext = target.includes('windows') ? 'zip' : 'tar.gz';
|
|
93
|
+
const archivePath = path.join(binDir, `polycli-${target}.${ext}`);
|
|
94
|
+
|
|
95
|
+
console.log(`Downloading PolyCLI v${VERSION} for ${target}...`);
|
|
96
|
+
console.log(`URL: ${url}`);
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
await downloadFile(url, archivePath);
|
|
100
|
+
console.log('Download complete, extracting...');
|
|
101
|
+
|
|
102
|
+
extractArchive(archivePath, binDir);
|
|
103
|
+
fs.unlinkSync(archivePath);
|
|
104
|
+
|
|
105
|
+
// Make binaries executable on Unix
|
|
106
|
+
if (os.platform() !== 'win32') {
|
|
107
|
+
execSync(`chmod +x "${path.join(binDir, BINARY_NAME)}"`);
|
|
108
|
+
execSync(`chmod +x "${path.join(binDir, 'poly')}"`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
console.log('PolyCLI installed successfully!');
|
|
112
|
+
console.log('Run: poly --help');
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.error('Installation failed:', error.message);
|
|
115
|
+
console.error('You can manually download from: https://github.com/repohelper/polycli/releases');
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
install().catch(err => {
|
|
121
|
+
console.error('Unexpected error:', err);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "codexctl",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Universal AI CLI Profile Manager - Manage multiple AI CLI accounts (Codex, Claude, Gemini)",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"codexctl": "./bin/codexctl",
|
|
8
|
+
"cdx": "./bin/cdx"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"postinstall": "node install.js",
|
|
12
|
+
"test": "echo 'Binary package - no tests'"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/repohelper/aix.git"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"ai",
|
|
20
|
+
"cli",
|
|
21
|
+
"profile",
|
|
22
|
+
"manager",
|
|
23
|
+
"codex",
|
|
24
|
+
"claude",
|
|
25
|
+
"gemini",
|
|
26
|
+
"openai",
|
|
27
|
+
"multi-account"
|
|
28
|
+
],
|
|
29
|
+
"author": "Bhanu Korthiwada",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/repohelper/polycli/issues"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://polycli.repohelper.com",
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=16"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"bin/",
|
|
40
|
+
"install.js",
|
|
41
|
+
"README.md",
|
|
42
|
+
"LICENSE"
|
|
43
|
+
],
|
|
44
|
+
"trusted-publishers": [
|
|
45
|
+
{
|
|
46
|
+
"type": "GitHub Actions",
|
|
47
|
+
"workflow": "release.yml"
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|