@kesarcloud/omega-plus-cli 2.0.5 → 2.0.6
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 +2 -2
- package/package.json +4 -2
- package/src/cli.mjs +21 -8
- package/src/constants.mjs +5 -1
- package/src/wizard.mjs +178 -11
package/README.md
CHANGED
|
@@ -30,8 +30,8 @@ Defaults:
|
|
|
30
30
|
- OpenAI-compatible URL: `https://omega.kesarcloud.in/api/v1`
|
|
31
31
|
- Anthropic-compatible URL: `https://omega.kesarcloud.in/v1`
|
|
32
32
|
- API key validation URL: `https://omega.kesarcloud.in/api/omega/validate-key`
|
|
33
|
-
- Model: `omega-
|
|
34
|
-
-
|
|
33
|
+
- Model: `omega-plus` (default)
|
|
34
|
+
- Additional models: `KesarCloud/anthropic/claude-opus-4-6`, `KesarCloud/anthropic/claude-opus-4.7`, `KesarCloud/openai/gpt-5.5`
|
|
35
35
|
|
|
36
36
|
Use `--base-url`, `--openai-base-url`, `--anthropic-base-url`, `--model`, or `--fast-model` to override them.
|
|
37
37
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kesarcloud/omega-plus-cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
4
4
|
"description": "Interactive Omega Plus setup wizard for coding CLI tools.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
},
|
|
19
19
|
"keywords": [
|
|
20
20
|
"omega-plus",
|
|
21
|
-
"
|
|
21
|
+
"claude-opus-4-6",
|
|
22
|
+
"claude-opus-4-7",
|
|
23
|
+
"gpt-5-5",
|
|
22
24
|
"claude-code",
|
|
23
25
|
"codex",
|
|
24
26
|
"opencode",
|
package/src/cli.mjs
CHANGED
|
@@ -7,22 +7,26 @@ import {
|
|
|
7
7
|
DEFAULT_VALIDATION_URL,
|
|
8
8
|
VERSION,
|
|
9
9
|
} from "./constants.mjs";
|
|
10
|
-
import { printDoctor, printToolList, runNonInteractiveConfigure, runWizard } from "./wizard.mjs";
|
|
10
|
+
import { printDoctor, printToolList, runNonInteractiveConfigure, runWizard, runUpdateFlow } from "./wizard.mjs";
|
|
11
11
|
import { scanForMigration, migrateAllTools } from "./migrate.mjs";
|
|
12
12
|
|
|
13
13
|
function printHelp() {
|
|
14
14
|
console.log(`Omega Plus CLI ${VERSION}
|
|
15
15
|
|
|
16
16
|
Usage:
|
|
17
|
-
omega-plus
|
|
18
|
-
omega-plus setup
|
|
17
|
+
omega-plus Interactive setup wizard
|
|
18
|
+
omega-plus setup New setup with menu
|
|
19
|
+
omega-plus update Update existing tool configs
|
|
19
20
|
omega-plus configure --tool <id> --api-key <key>
|
|
20
|
-
omega-plus list
|
|
21
|
-
omega-plus doctor
|
|
21
|
+
omega-plus list List tools and status
|
|
22
|
+
omega-plus doctor Diagnostic info
|
|
23
|
+
omega-plus docs Open documentation
|
|
24
|
+
omega-plus migrate Migrate old configs
|
|
22
25
|
|
|
23
26
|
Options:
|
|
24
27
|
--api-key <key> Omega API key
|
|
25
28
|
--tool <id> claude, codex, opencode, cline, kilo, droid
|
|
29
|
+
--update Skip menu and go directly to update flow
|
|
26
30
|
--base-url <url> Default: ${DEFAULT_BASE_URL}
|
|
27
31
|
--openai-base-url Codex/OpenAI-compatible default: ${DEFAULT_OPENAI_BASE_URL}
|
|
28
32
|
--anthropic-base-url Anthropic-compatible default: ${DEFAULT_ANTHROPIC_BASE_URL}
|
|
@@ -31,10 +35,10 @@ Options:
|
|
|
31
35
|
--fast-model <id> Default: ${DEFAULT_FAST_MODEL}
|
|
32
36
|
--skip-key-validation Skip server-side API key validation
|
|
33
37
|
--dry-run Preview files without writing
|
|
34
|
-
--yes Auto-confirm
|
|
38
|
+
--yes Auto-confirm prompts
|
|
35
39
|
--no-install Do not install missing tools
|
|
36
|
-
--migrate-all Auto-migrate old omega-v1 configs
|
|
37
|
-
--skip-migration-check
|
|
40
|
+
--migrate-all Auto-migrate old omega-v1 configs
|
|
41
|
+
--skip-migration-check Skip stale config detection
|
|
38
42
|
--help Show help
|
|
39
43
|
--version Show version
|
|
40
44
|
`);
|
|
@@ -55,6 +59,7 @@ function parseArgs(argv) {
|
|
|
55
59
|
else if (arg === "--no-install") options.noInstall = true;
|
|
56
60
|
else if (arg === "--migrate-all") options.migrateAll = true;
|
|
57
61
|
else if (arg === "--skip-migration-check") options.skipMigrationCheck = true;
|
|
62
|
+
else if (arg === "--update") options.update = true;
|
|
58
63
|
else if (arg === "--api-key") options.apiKey = args[++i];
|
|
59
64
|
else if (arg.startsWith("--api-key=")) options.apiKey = arg.slice("--api-key=".length);
|
|
60
65
|
else if (arg === "--tool") options.tool = args[++i];
|
|
@@ -95,6 +100,14 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
95
100
|
case "setup":
|
|
96
101
|
await runWizard(options);
|
|
97
102
|
break;
|
|
103
|
+
case "update":
|
|
104
|
+
options.update = true;
|
|
105
|
+
await runWizard(options);
|
|
106
|
+
break;
|
|
107
|
+
case "docs":
|
|
108
|
+
options.command = "docs";
|
|
109
|
+
await runWizard(options);
|
|
110
|
+
break;
|
|
98
111
|
case "configure":
|
|
99
112
|
await runNonInteractiveConfigure(options);
|
|
100
113
|
break;
|
package/src/constants.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export const VERSION = "2.0.
|
|
1
|
+
export const VERSION = "2.0.6";
|
|
2
2
|
export const DEFAULT_ORIGIN = "https://omega.kesarcloud.in";
|
|
3
3
|
export const DEFAULT_BASE_URL = `${DEFAULT_ORIGIN}/v1`;
|
|
4
4
|
export const DEFAULT_ANTHROPIC_BASE_URL = `${DEFAULT_ORIGIN}/v1`;
|
|
5
5
|
export const DEFAULT_OPENAI_BASE_URL = `${DEFAULT_ORIGIN}/api/v1`;
|
|
6
6
|
export const DEFAULT_VALIDATION_URL = `${DEFAULT_ORIGIN}/api/omega/validate-key`;
|
|
7
|
+
export const DOCS_URL = `${DEFAULT_ORIGIN}/documentation`;
|
|
7
8
|
export const DEFAULT_MODEL = "omega-plus";
|
|
8
9
|
export const DEFAULT_FAST_MODEL = "omega-plus";
|
|
9
10
|
export const OMEGA_CONTEXT_WINDOW = 1_000_000;
|
|
@@ -11,6 +12,9 @@ export const OMEGA_MAX_OUTPUT_TOKENS = 32000;
|
|
|
11
12
|
|
|
12
13
|
export const OMEGA_MODELS = [
|
|
13
14
|
{ id: "omega-plus", name: "Omega Plus" },
|
|
15
|
+
{ id: "KesarCloud/anthropic/claude-opus-4-6", name: "Claude Opus 4.6" },
|
|
16
|
+
{ id: "KesarCloud/anthropic/claude-opus-4.7", name: "Claude Opus 4.7" },
|
|
17
|
+
{ id: "KesarCloud/openai/gpt-5.5", name: "GPT 5.5" },
|
|
14
18
|
];
|
|
15
19
|
|
|
16
20
|
export const TOOL_IDS = ["claude", "codex", "opencode", "cline", "kilo", "droid"];
|
package/src/wizard.mjs
CHANGED
|
@@ -2,6 +2,8 @@ import {
|
|
|
2
2
|
DEFAULT_BASE_URL,
|
|
3
3
|
DEFAULT_FAST_MODEL,
|
|
4
4
|
DEFAULT_MODEL,
|
|
5
|
+
DEFAULT_ORIGIN,
|
|
6
|
+
DOCS_URL,
|
|
5
7
|
TOOL_DEFINITIONS,
|
|
6
8
|
} from "./constants.mjs";
|
|
7
9
|
import { printBanner } from "./banner.mjs";
|
|
@@ -10,6 +12,21 @@ import { detectAllTools, detectTool, runInstallCommand } from "./detector.mjs";
|
|
|
10
12
|
import { validateApiKey } from "./key-validator.mjs";
|
|
11
13
|
import { ask, askSecret, createPromptInterface } from "./prompts.mjs";
|
|
12
14
|
import { scanForMigration, migrateAllTools } from "./migrate.mjs";
|
|
15
|
+
import { configPath, roamingConfigPath, readJson } from "./fs-utils.mjs";
|
|
16
|
+
import { fileURLToPath } from "node:url";
|
|
17
|
+
import { spawn } from "node:child_process";
|
|
18
|
+
|
|
19
|
+
function openUrl(url) {
|
|
20
|
+
const platform = process.platform;
|
|
21
|
+
try {
|
|
22
|
+
if (platform === "darwin") spawn("open", [url], { stdio: "ignore", detached: true }).unref();
|
|
23
|
+
else if (platform === "win32") spawn("start", ["", url], { stdio: "ignore", detached: true, shell: true }).unref();
|
|
24
|
+
else spawn("xdg-open", [url], { stdio: "ignore", detached: true }).unref();
|
|
25
|
+
return true;
|
|
26
|
+
} catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
13
30
|
|
|
14
31
|
function printHeader() {
|
|
15
32
|
printBanner();
|
|
@@ -58,6 +75,135 @@ async function maybeInstallTool(toolId, options, rl) {
|
|
|
58
75
|
return detectTool(toolId);
|
|
59
76
|
}
|
|
60
77
|
|
|
78
|
+
export async function showMainMenu(rl, options = {}) {
|
|
79
|
+
const lines = [
|
|
80
|
+
"",
|
|
81
|
+
" What would you like to do?",
|
|
82
|
+
"",
|
|
83
|
+
" 1. \u{1F680} New Setup",
|
|
84
|
+
" Connect a new tool with your API key",
|
|
85
|
+
"",
|
|
86
|
+
" 2. \u{1F504} Update Current Setup",
|
|
87
|
+
" Update existing tool configs with latest models",
|
|
88
|
+
"",
|
|
89
|
+
' 3. \u{1F4DA} Documentation',
|
|
90
|
+
` Open Omega Plus docs — ${DOCS_URL}`,
|
|
91
|
+
"",
|
|
92
|
+
];
|
|
93
|
+
for (const line of lines) console.log(line);
|
|
94
|
+
|
|
95
|
+
if (options.update === true) return 2;
|
|
96
|
+
if (options.command === "docs") return 3;
|
|
97
|
+
|
|
98
|
+
const answer = await ask(rl, " Enter option (1-3): ");
|
|
99
|
+
const num = Number.parseInt(answer.trim(), 10);
|
|
100
|
+
if (num === 1 || num === 2 || num === 3) return num;
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async function extractApiKeyFromConfig(toolId) {
|
|
105
|
+
const tool = TOOL_DEFINITIONS[toolId];
|
|
106
|
+
if (!tool) return null;
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
switch (toolId) {
|
|
110
|
+
case "claude": {
|
|
111
|
+
const cfg = await readJson(configPath([".claude", "settings.json"]));
|
|
112
|
+
return cfg?.env?.ANTHROPIC_AUTH_TOKEN || null;
|
|
113
|
+
}
|
|
114
|
+
case "codex": {
|
|
115
|
+
const cfg = await readJson(configPath([".codex", "auth.json"]));
|
|
116
|
+
return cfg?.OPENAI_API_KEY || null;
|
|
117
|
+
}
|
|
118
|
+
case "opencode": {
|
|
119
|
+
const cfg = await readJson(configPath([".config", "opencode", "opencode.json"]));
|
|
120
|
+
return cfg?.provider?.kesarcloud?.options?.apiKey || cfg?.provider?.omega?.options?.apiKey || null;
|
|
121
|
+
}
|
|
122
|
+
case "cline": {
|
|
123
|
+
const cfg = await readJson(configPath([".cline", "data", "secrets.json"]));
|
|
124
|
+
return cfg?.anthropicApiKey || null;
|
|
125
|
+
}
|
|
126
|
+
case "kilo": {
|
|
127
|
+
const cfg = await readJson(roamingConfigPath(["kilo", "auth.json"]));
|
|
128
|
+
return cfg?.anthropic?.apiKey || null;
|
|
129
|
+
}
|
|
130
|
+
case "droid": {
|
|
131
|
+
const cfg = await readJson(configPath([".factory", "settings.json"]));
|
|
132
|
+
return cfg?.customModels?.[0]?.apiKey || null;
|
|
133
|
+
}
|
|
134
|
+
default:
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
} catch {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export async function runUpdateFlow(options = {}) {
|
|
143
|
+
const rl = createPromptInterface();
|
|
144
|
+
try {
|
|
145
|
+
const allTools = await detectAllTools();
|
|
146
|
+
const configured = allTools.filter((t) => t.configStatus === "configured" && t.installed);
|
|
147
|
+
|
|
148
|
+
if (configured.length === 0) {
|
|
149
|
+
console.log("\nNo configured tools found. Run New Setup first to connect a tool.\n");
|
|
150
|
+
return { skipped: true, reason: "no_configured_tools" };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
console.log("\nSelect a tool to update:");
|
|
154
|
+
configured.forEach((tool, index) => {
|
|
155
|
+
console.log(` ${index + 1}. ${tool.name}`);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const answer = options.tool || (await ask(rl, "\nEnter tool number: "));
|
|
159
|
+
const trimmed = String(answer || "").trim();
|
|
160
|
+
let toolId = null;
|
|
161
|
+
if (TOOL_DEFINITIONS[trimmed.toLowerCase()]) {
|
|
162
|
+
toolId = trimmed.toLowerCase();
|
|
163
|
+
} else {
|
|
164
|
+
const num = Number.parseInt(trimmed, 10);
|
|
165
|
+
if (num >= 1 && num <= configured.length) toolId = configured[num - 1].id;
|
|
166
|
+
}
|
|
167
|
+
if (!toolId) throw new Error("Invalid tool selection");
|
|
168
|
+
|
|
169
|
+
// Extract API key from existing config
|
|
170
|
+
let apiKey = await extractApiKeyFromConfig(toolId);
|
|
171
|
+
if (!apiKey) {
|
|
172
|
+
console.log("\nCould not read your existing API key from config.");
|
|
173
|
+
apiKey = await askSecret("Paste your Omega API key to continue: ");
|
|
174
|
+
if (!apiKey) throw new Error("API key is required");
|
|
175
|
+
} else {
|
|
176
|
+
console.log(`\nUsing existing API key from ${toolId} config...`);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
console.log("\nUpdating configuration with latest models...");
|
|
180
|
+
const result = await configureTool(toolId, {
|
|
181
|
+
apiKey,
|
|
182
|
+
baseUrl: options.baseUrl || DEFAULT_BASE_URL,
|
|
183
|
+
openaiBaseUrl: options.openaiBaseUrl,
|
|
184
|
+
anthropicBaseUrl: options.anthropicBaseUrl,
|
|
185
|
+
model: options.model || DEFAULT_MODEL,
|
|
186
|
+
fastModel: options.fastModel || DEFAULT_FAST_MODEL,
|
|
187
|
+
dryRun: options.dryRun,
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
if (options.dryRun) {
|
|
191
|
+
console.log("\nDry run complete. No files were changed.");
|
|
192
|
+
result.files.forEach((file) => console.log(` would write: ${file.path}`));
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
console.log(`\n${result.message}`);
|
|
197
|
+
result.files.forEach((file) => {
|
|
198
|
+
console.log(` updated: ${file.path}`);
|
|
199
|
+
});
|
|
200
|
+
console.log("\nYour models have been updated to the latest Omega Plus endpoints.");
|
|
201
|
+
return result;
|
|
202
|
+
} finally {
|
|
203
|
+
rl.close();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
61
207
|
export async function runWizard(options = {}) {
|
|
62
208
|
printHeader();
|
|
63
209
|
|
|
@@ -81,19 +227,40 @@ export async function runWizard(options = {}) {
|
|
|
81
227
|
}
|
|
82
228
|
}
|
|
83
229
|
|
|
84
|
-
const apiKey = options.apiKey || (await askSecret("Paste your Omega API key: "));
|
|
85
|
-
if (!apiKey) throw new Error("API key is required");
|
|
86
|
-
|
|
87
|
-
console.log("Checking your Omega API key...");
|
|
88
|
-
await validateApiKey(apiKey, {
|
|
89
|
-
baseUrl: options.baseUrl || DEFAULT_BASE_URL,
|
|
90
|
-
validationUrl: options.validationUrl,
|
|
91
|
-
skipKeyValidation: options.skipKeyValidation,
|
|
92
|
-
});
|
|
93
|
-
console.log(options.skipKeyValidation ? "API key validation skipped." : "API key verified.");
|
|
94
|
-
|
|
95
230
|
const rl = createPromptInterface();
|
|
96
231
|
try {
|
|
232
|
+
// ── Show main menu ──
|
|
233
|
+
const menuChoice = await showMainMenu(rl, options);
|
|
234
|
+
|
|
235
|
+
// Option 3: Docs
|
|
236
|
+
if (menuChoice === 3) {
|
|
237
|
+
console.log(`\nOpening ${DOCS_URL} ...`);
|
|
238
|
+
const opened = openUrl(DOCS_URL);
|
|
239
|
+
if (!opened) console.log(`Please visit: ${DOCS_URL}`);
|
|
240
|
+
return { skipped: true, reason: "docs" };
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Option 2: Update
|
|
244
|
+
if (menuChoice === 2) {
|
|
245
|
+
return runUpdateFlow(options);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Option 1 or invalid: New Setup (default)
|
|
249
|
+
if (menuChoice !== 1 && menuChoice !== 0) {
|
|
250
|
+
console.log("\nStarting New Setup...\n");
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const apiKey = options.apiKey || (await askSecret("Paste your Omega API key: "));
|
|
254
|
+
if (!apiKey) throw new Error("API key is required");
|
|
255
|
+
|
|
256
|
+
console.log("Checking your Omega API key...");
|
|
257
|
+
await validateApiKey(apiKey, {
|
|
258
|
+
baseUrl: options.baseUrl || DEFAULT_BASE_URL,
|
|
259
|
+
validationUrl: options.validationUrl,
|
|
260
|
+
skipKeyValidation: options.skipKeyValidation,
|
|
261
|
+
});
|
|
262
|
+
console.log(options.skipKeyValidation ? "API key validation skipped." : "API key verified.");
|
|
263
|
+
|
|
97
264
|
const tools = await detectAllTools();
|
|
98
265
|
printTools(tools);
|
|
99
266
|
const answer = options.tool || (await ask(rl, "\nEnter tool number: "));
|