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 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
+ }