@cbuk100011/claude-mode 1.2.0 → 1.4.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.
Files changed (3) hide show
  1. package/README.md +13 -10
  2. package/dist/index.js +682 -67
  3. package/package.json +2 -1
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Claude Mode
2
2
 
3
+ ![npm version](https://img.shields.io/npm/v/%40cbuk100011%2Fclaude-mode)
4
+
3
5
  A Node.js CLI launcher for Claude Code that supports multiple AI providers and models.
4
6
 
5
7
  ## Features
@@ -17,12 +19,19 @@ A Node.js CLI launcher for Claude Code that supports multiple AI providers and m
17
19
 
18
20
  ## Installation
19
21
 
22
+ ### npm Package (Recommended)
23
+
24
+ ```bash
25
+ # Install globally
26
+ npm install -g @cbuk100011/claude-mode
27
+ ```
28
+
20
29
  ### From Source
21
30
 
22
31
  ```bash
23
32
  # Clone the repository
24
- git clone <repo-url>
25
- cd claude-mode
33
+ git clone https://github.com/Cam10001110101/claude-mode-cli.git
34
+ cd claude-mode-cli
26
35
 
27
36
  # Install dependencies
28
37
  npm install
@@ -30,16 +39,10 @@ npm install
30
39
  # Build
31
40
  npm run build
32
41
 
33
- # Link globally (optional)
42
+ # Link globally
34
43
  npm link
35
44
  ```
36
45
 
37
- ### Global Installation (after npm publish)
38
-
39
- ```bash
40
- npm install -g claude-mode
41
- ```
42
-
43
46
  ## Usage
44
47
 
45
48
  ### Interactive Menu
@@ -293,7 +296,7 @@ npm run typecheck
293
296
  ## Project Structure
294
297
 
295
298
  ```
296
- claude-mode/
299
+ claude-mode-cli/
297
300
  ├── src/
298
301
  │ ├── index.ts # Main CLI entry point
299
302
  │ ├── providers.ts # Provider and model configurations
package/dist/index.js CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  // src/index.ts
4
4
  import { Command } from "commander";
5
- import chalk2 from "chalk";
6
- import { select, input } from "@inquirer/prompts";
5
+ import chalk3 from "chalk";
6
+ import { select as select2, input as input2, confirm as confirm2 } from "@inquirer/prompts";
7
7
  import { spawn, execSync } from "child_process";
8
8
  import { config } from "dotenv";
9
9
  import { fileURLToPath } from "url";
10
- import path2 from "path";
10
+ import path3 from "path";
11
11
 
12
12
  // src/config.ts
13
13
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
@@ -37,6 +37,7 @@ var DEFAULT_CONFIG = {
37
37
  healthCheckTimeout: 2e3,
38
38
  cacheTTL: 3e4,
39
39
  customProviders: [],
40
+ configuredProviders: [],
40
41
  skipHealthCheck: false,
41
42
  offlineMode: false,
42
43
  headlessAllowedTools: "Read,Edit,Write,Bash,Glob,Grep"
@@ -210,6 +211,33 @@ function claudeNotFoundError() {
210
211
  hint: "Install Claude Code CLI: npm install -g @anthropic-ai/claude-code\nOr check that it is in your PATH."
211
212
  };
212
213
  }
214
+ function setupConfigWriteError(message, hint) {
215
+ return {
216
+ code: "SETUP_CONFIG_WRITE_FAILED" /* SETUP_CONFIG_WRITE_FAILED */,
217
+ message: `Failed to write config: ${message}`,
218
+ hint: hint || "Check file permissions and try again, or use a different config location."
219
+ };
220
+ }
221
+ function setupEnvWriteError(message, hint) {
222
+ return {
223
+ code: "SETUP_ENV_WRITE_FAILED" /* SETUP_ENV_WRITE_FAILED */,
224
+ message: `Failed to write .env file: ${message}`,
225
+ hint: hint || "Check file permissions or specify a different location."
226
+ };
227
+ }
228
+ function setupCancelledError() {
229
+ return {
230
+ code: "SETUP_CANCELLED" /* SETUP_CANCELLED */,
231
+ message: "Setup cancelled"
232
+ };
233
+ }
234
+ function setupIncompleteError(message) {
235
+ return {
236
+ code: "SETUP_INCOMPLETE" /* SETUP_INCOMPLETE */,
237
+ message,
238
+ hint: "Run claude-mode setup to complete configuration."
239
+ };
240
+ }
213
241
 
214
242
  // src/providers.ts
215
243
  var builtInProviders = {
@@ -249,10 +277,10 @@ var builtInProviders = {
249
277
  "ollama-custom": {
250
278
  name: "Ollama Custom",
251
279
  key: "ollama-custom",
252
- getBaseUrl: () => process.env.OLLAMA_BASE_URL_CUSTOM || "http://192.168.86.101:11434",
280
+ getBaseUrl: () => process.env.OLLAMA_BASE_URL_CUSTOM || "",
253
281
  getAuthToken: () => "ollama",
254
282
  getDescription: () => {
255
- const url = process.env.OLLAMA_BASE_URL_CUSTOM || "http://192.168.86.101:11434";
283
+ const url = process.env.OLLAMA_BASE_URL_CUSTOM || "not configured";
256
284
  return `Ollama Custom (${url})`;
257
285
  },
258
286
  isBuiltIn: true
@@ -508,12 +536,57 @@ async function checkAllProvidersHealth() {
508
536
  return results;
509
537
  }
510
538
 
511
- // src/index.ts
512
- config();
513
- var __filename = fileURLToPath(import.meta.url);
514
- var __dirname = path2.dirname(__filename);
515
- config({ path: path2.join(__dirname, "..", ".env") });
516
- var program = new Command();
539
+ // src/setup.ts
540
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
541
+ import { homedir as homedir2 } from "os";
542
+ import path2 from "path";
543
+ import chalk2 from "chalk";
544
+ import {
545
+ confirm,
546
+ select,
547
+ checkbox,
548
+ input,
549
+ password
550
+ } from "@inquirer/prompts";
551
+ function getConfigDir2() {
552
+ return path2.join(homedir2(), ".claude-mode");
553
+ }
554
+ function getConfigPath() {
555
+ return path2.join(getConfigDir2(), "claude-mode.json");
556
+ }
557
+ function getEnvPath(envPath) {
558
+ return envPath || path2.join(process.cwd(), ".env");
559
+ }
560
+ function detectSetupStatus() {
561
+ const configPath = getConfigPath();
562
+ const envPath = getEnvPath();
563
+ if (!existsSync2(configPath)) {
564
+ return "first-time";
565
+ }
566
+ try {
567
+ const config2 = loadConfig();
568
+ const hasDefaults = !!(config2.defaultProvider && config2.defaultModel);
569
+ const hasProviders = !!config2.configuredProviders && config2.configuredProviders.length > 0;
570
+ if (!hasDefaults || !hasProviders) {
571
+ return "incomplete";
572
+ }
573
+ if (config2.configuredProviders) {
574
+ for (const providerKey of config2.configuredProviders) {
575
+ const provider = getProvider(providerKey);
576
+ if (provider) {
577
+ const hasKey = !!provider.getAuthToken();
578
+ const needsKey = providerKey === "openrouter" || providerKey === "ollama-cloud";
579
+ if (needsKey && !hasKey) {
580
+ return "incomplete";
581
+ }
582
+ }
583
+ }
584
+ }
585
+ return "complete";
586
+ } catch {
587
+ return "first-time";
588
+ }
589
+ }
517
590
  function printHeader(text) {
518
591
  console.log("");
519
592
  console.log(chalk2.bold.blue("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
@@ -521,13 +594,538 @@ function printHeader(text) {
521
594
  console.log(chalk2.bold.blue("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
522
595
  console.log("");
523
596
  }
597
+ function printSection(title) {
598
+ console.log("");
599
+ console.log(chalk2.bold.cyan("\u2501\u2501\u2501 " + title + " \u2501\u2501\u2501"));
600
+ console.log("");
601
+ }
602
+ function printProviderInfo() {
603
+ console.log(chalk2.bold("Available Providers:"));
604
+ console.log("");
605
+ console.log(" " + chalk2.green("OpenRouter") + " - Access to Claude, GPT-5, DeepSeek, and more");
606
+ console.log(" " + chalk2.gray("Requires: API key"));
607
+ console.log("");
608
+ console.log(" " + chalk2.green("Ollama Local") + " - Run models locally on your machine");
609
+ console.log(" " + chalk2.gray("Requires: Local Ollama instance"));
610
+ console.log("");
611
+ console.log(" " + chalk2.green("Ollama Cloud") + " - Managed Ollama service");
612
+ console.log(" " + chalk2.gray("Requires: API key"));
613
+ console.log("");
614
+ console.log(" " + chalk2.green("Ollama Custom") + " - Connect to remote Ollama instance");
615
+ console.log(" " + chalk2.gray("Requires: Custom URL"));
616
+ console.log("");
617
+ }
618
+ async function displayWelcome(isFirstTime) {
619
+ console.clear();
620
+ if (isFirstTime) {
621
+ printHeader("Welcome to Claude Mode Setup");
622
+ console.log(chalk2.bold.cyan("Claude Mode") + " is a CLI launcher for Claude Code");
623
+ console.log("that supports multiple AI providers.");
624
+ console.log("");
625
+ console.log("This wizard will help you configure your providers");
626
+ console.log("and set up your default settings.");
627
+ console.log("");
628
+ } else {
629
+ printHeader("Claude Mode Configuration");
630
+ console.log("Update your configuration or add new providers.");
631
+ console.log("");
632
+ }
633
+ printProviderInfo();
634
+ const ready = await confirm({
635
+ message: "Ready to configure?",
636
+ default: true
637
+ });
638
+ if (!ready) {
639
+ throw setupCancelledError();
640
+ }
641
+ }
642
+ async function displayUpdatePrompt() {
643
+ console.clear();
644
+ printHeader("Configuration Found");
645
+ console.log("A configuration file already exists.");
646
+ console.log("");
647
+ console.log("You can:");
648
+ console.log(" " + chalk2.cyan("\u2022") + " Re-run full setup to reconfigure all providers");
649
+ console.log(" " + chalk2.cyan("\u2022") + " Configure a single provider");
650
+ console.log(" " + chalk2.cyan("\u2022") + " Skip and use existing configuration");
651
+ console.log("");
652
+ const action = await select({
653
+ message: "What would you like to do?",
654
+ choices: [
655
+ { name: "Re-run full setup", value: "full" },
656
+ { name: "Configure specific provider", value: "single" },
657
+ { name: "Skip (use existing config)", value: "skip" }
658
+ ]
659
+ });
660
+ return action !== "skip";
661
+ }
662
+ async function selectProviders(forceProvider) {
663
+ if (forceProvider) {
664
+ const provider = getProvider(forceProvider);
665
+ if (!provider) {
666
+ console.error(chalk2.red(`Unknown provider: ${forceProvider}`));
667
+ throw setupIncompleteError(`Provider "${forceProvider}" not found`);
668
+ }
669
+ return [forceProvider];
670
+ }
671
+ const allProviders = getProviders();
672
+ const choices = Object.entries(allProviders).map(([key, provider]) => ({
673
+ name: provider.name,
674
+ value: key,
675
+ description: provider.getDescription()
676
+ }));
677
+ const selected = await checkbox({
678
+ message: "Select providers to configure:",
679
+ choices,
680
+ validate: (value) => value.length > 0 ? true : "Select at least one provider"
681
+ });
682
+ return selected;
683
+ }
684
+ async function configureProvider(providerKey, skipValidation) {
685
+ const provider = getProvider(providerKey);
686
+ if (!provider) {
687
+ throw setupIncompleteError(`Provider "${providerKey}" not found`);
688
+ }
689
+ printSection(`Configuring ${provider.name}`);
690
+ const config2 = {
691
+ key: providerKey,
692
+ name: provider.name,
693
+ validated: false
694
+ };
695
+ if (providerKey === "openrouter" || providerKey === "ollama-cloud") {
696
+ const existingKey = provider.getAuthToken();
697
+ const keyMsg = existingKey ? `Enter API key (current: ${existingKey.substring(0, 8)}...)` : "Enter API key:";
698
+ config2.apiKey = await password({
699
+ message: keyMsg,
700
+ validate: (value) => {
701
+ if (existingKey && !value) return true;
702
+ return value.length > 0 ? true : "API key is required";
703
+ }
704
+ });
705
+ if (config2.apiKey) {
706
+ if (providerKey === "openrouter") {
707
+ process.env.ANTHROPIC_AUTH_TOKEN = config2.apiKey;
708
+ } else if (providerKey === "ollama-cloud") {
709
+ process.env.OLLAMA_API_KEY = config2.apiKey;
710
+ }
711
+ }
712
+ }
713
+ if (providerKey === "ollama-custom") {
714
+ const existingUrl = provider.getBaseUrl();
715
+ config2.customUrl = await input({
716
+ message: "Enter Ollama URL:",
717
+ default: existingUrl || "",
718
+ validate: (value) => {
719
+ try {
720
+ new URL(value);
721
+ return true;
722
+ } catch {
723
+ return "Please enter a valid URL";
724
+ }
725
+ }
726
+ });
727
+ if (config2.customUrl) {
728
+ process.env.OLLAMA_BASE_URL_CUSTOM = config2.customUrl;
729
+ }
730
+ }
731
+ if (!skipValidation) {
732
+ config2.validated = await validateProvider(providerKey);
733
+ } else {
734
+ config2.validated = true;
735
+ }
736
+ return config2;
737
+ }
738
+ async function validateProvider(providerKey) {
739
+ console.log(chalk2.gray("Validating provider connection..."));
740
+ const result = await checkProviderHealth(providerKey);
741
+ if (result.healthy) {
742
+ const latency = result.latencyMs ? ` (${result.latencyMs}ms)` : "";
743
+ console.log(chalk2.green(`\u2713 ${providerKey} is reachable${latency}`));
744
+ return true;
745
+ } else {
746
+ console.log(chalk2.yellow(`\u26A0 ${providerKey} validation failed`));
747
+ if (result.error) {
748
+ console.log(chalk2.gray(` ${result.error.message}`));
749
+ }
750
+ const retry = await confirm({
751
+ message: "Continue anyway?",
752
+ default: false
753
+ });
754
+ return retry;
755
+ }
756
+ }
757
+ async function selectDefaults(configuredProviders, currentDefaults) {
758
+ printSection("Set Defaults");
759
+ let defaultProvider;
760
+ let defaultModel;
761
+ if (currentDefaults && configuredProviders.includes(currentDefaults.provider)) {
762
+ const useCurrent = await confirm({
763
+ message: `Keep default provider as ${currentDefaults.provider}?`,
764
+ default: true
765
+ });
766
+ if (useCurrent) {
767
+ defaultProvider = currentDefaults.provider;
768
+ } else {
769
+ defaultProvider = await select({
770
+ message: "Select default provider:",
771
+ choices: configuredProviders.map((key) => ({
772
+ name: getProvider(key)?.name || key,
773
+ value: key
774
+ }))
775
+ });
776
+ }
777
+ } else {
778
+ defaultProvider = await select({
779
+ message: "Select default provider:",
780
+ choices: configuredProviders.map((key) => ({
781
+ name: getProvider(key)?.name || key,
782
+ value: key
783
+ }))
784
+ });
785
+ }
786
+ const models3 = await getModels(defaultProvider);
787
+ console.log("");
788
+ console.log(chalk2.gray("Available models for " + getProvider(defaultProvider)?.name + ":"));
789
+ if (models3.length === 0) {
790
+ console.log(" " + chalk2.gray("(no models found - will use manual input)"));
791
+ console.log("");
792
+ const modelInput = await input({
793
+ message: "Enter default model ID:",
794
+ validate: (value) => value.length > 0 ? true : "Model ID cannot be empty"
795
+ });
796
+ defaultModel = modelInput;
797
+ } else {
798
+ for (const model of models3) {
799
+ console.log(` ${chalk2.green(model.shortcut.padEnd(20))} ${chalk2.gray(model.id)}`);
800
+ }
801
+ console.log("");
802
+ defaultModel = await select({
803
+ message: "Select default model:",
804
+ choices: models3.map((model) => ({
805
+ name: `${model.name} (${model.shortcut})`,
806
+ value: model.id
807
+ }))
808
+ });
809
+ }
810
+ return { provider: defaultProvider, model: defaultModel };
811
+ }
812
+ function formatProviderConfig(config2) {
813
+ const lines = [];
814
+ lines.push(chalk2.cyan(` ${config2.name} (${config2.key})`));
815
+ if (config2.apiKey) {
816
+ const masked = config2.apiKey.substring(0, 8) + "..." + config2.apiKey.slice(-4);
817
+ lines.push(` API Key: ${chalk2.gray(masked)}`);
818
+ }
819
+ if (config2.customUrl) {
820
+ lines.push(` URL: ${chalk2.gray(config2.customUrl)}`);
821
+ }
822
+ if (config2.validated) {
823
+ lines.push(` Status: ${chalk2.green("\u2713 Validated")}`);
824
+ } else {
825
+ lines.push(` Status: ${chalk2.yellow("\u26A0 Not validated")}`);
826
+ }
827
+ return lines.join("\n");
828
+ }
829
+ async function reviewAndConfirm(providerConfigs, defaults, currentConfig) {
830
+ printSection("Review Configuration");
831
+ console.log(chalk2.bold("Configured Providers:"));
832
+ console.log("");
833
+ for (const config2 of providerConfigs) {
834
+ console.log(formatProviderConfig(config2));
835
+ }
836
+ console.log("");
837
+ console.log(chalk2.bold("Defaults:"));
838
+ console.log(` ${chalk2.cyan("Provider:")} ${defaults.provider}`);
839
+ console.log(` ${chalk2.cyan("Model:")} ${defaults.model}`);
840
+ console.log("");
841
+ console.log(chalk2.bold("Files to be created/updated:"));
842
+ console.log(` ${chalk2.cyan("Config:")} ${getConfigPath()}`);
843
+ console.log(` ${chalk2.cyan("Env:")} ${getEnvPath()}`);
844
+ console.log("");
845
+ const confirmed = await confirm({
846
+ message: "Save this configuration?",
847
+ default: true
848
+ });
849
+ return confirmed;
850
+ }
851
+ function buildEnvVars(providerConfigs) {
852
+ const envVars = {};
853
+ for (const config2 of providerConfigs) {
854
+ switch (config2.key) {
855
+ case "openrouter":
856
+ if (config2.apiKey) {
857
+ envVars.ANTHROPIC_BASE_URL = "https://openrouter.ai/api";
858
+ envVars.ANTHROPIC_AUTH_TOKEN = config2.apiKey;
859
+ envVars.OPEN_ROUTER_API_KEY = config2.apiKey;
860
+ }
861
+ break;
862
+ case "ollama-cloud":
863
+ if (config2.apiKey) {
864
+ envVars.OLLAMA_HOST = "https://ollama.com";
865
+ envVars.OLLAMA_API_KEY = config2.apiKey;
866
+ }
867
+ break;
868
+ case "ollama-local":
869
+ envVars.OLLAMA_BASE_URL_LOCAL = "http://localhost:11434";
870
+ break;
871
+ case "ollama-custom":
872
+ if (config2.customUrl && config2.customUrl.trim()) {
873
+ envVars.OLLAMA_BASE_URL_CUSTOM = config2.customUrl;
874
+ }
875
+ break;
876
+ }
877
+ }
878
+ return envVars;
879
+ }
880
+ function formatEnvFile(envVars) {
881
+ const lines = [];
882
+ lines.push("# claude-mode configuration");
883
+ lines.push("# Generated by: claude-mode setup");
884
+ lines.push(`# Date: ${(/* @__PURE__ */ new Date()).toISOString()}`);
885
+ lines.push("");
886
+ if (envVars.ANTHROPIC_BASE_URL || envVars.ANTHROPIC_AUTH_TOKEN) {
887
+ lines.push("# OpenRouter");
888
+ if (envVars.ANTHROPIC_BASE_URL) {
889
+ lines.push(`ANTHROPIC_BASE_URL=${envVars.ANTHROPIC_BASE_URL}`);
890
+ }
891
+ if (envVars.ANTHROPIC_AUTH_TOKEN) {
892
+ lines.push(`ANTHROPIC_AUTH_TOKEN=${envVars.ANTHROPIC_AUTH_TOKEN}`);
893
+ }
894
+ if (envVars.OPEN_ROUTER_API_KEY) {
895
+ lines.push(`OPEN_ROUTER_API_KEY=${envVars.OPEN_ROUTER_API_KEY}`);
896
+ }
897
+ lines.push("");
898
+ }
899
+ if (envVars.OLLAMA_HOST || envVars.OLLAMA_API_KEY) {
900
+ lines.push("# Ollama Cloud");
901
+ if (envVars.OLLAMA_HOST) {
902
+ lines.push(`OLLAMA_HOST=${envVars.OLLAMA_HOST}`);
903
+ }
904
+ if (envVars.OLLAMA_API_KEY) {
905
+ lines.push(`OLLAMA_API_KEY=${envVars.OLLAMA_API_KEY}`);
906
+ }
907
+ lines.push("");
908
+ }
909
+ if (envVars.OLLAMA_BASE_URL_LOCAL) {
910
+ lines.push("# Ollama Local");
911
+ lines.push(`OLLAMA_BASE_URL_LOCAL=${envVars.OLLAMA_BASE_URL_LOCAL}`);
912
+ lines.push("");
913
+ }
914
+ if (envVars.OLLAMA_BASE_URL_CUSTOM) {
915
+ lines.push("# Ollama Custom");
916
+ lines.push(`OLLAMA_BASE_URL_CUSTOM=${envVars.OLLAMA_BASE_URL_CUSTOM}`);
917
+ lines.push("");
918
+ }
919
+ return lines.join("\n");
920
+ }
921
+ function mergeEnvFile(envVars, envPath) {
922
+ const targetPath = getEnvPath(envPath);
923
+ const existingVars = loadEnvFile(targetPath);
924
+ const merged = { ...existingVars, ...envVars };
925
+ const lines = [];
926
+ lines.push("# claude-mode configuration");
927
+ lines.push("# Generated by: claude-mode setup");
928
+ lines.push(`# Date: ${(/* @__PURE__ */ new Date()).toISOString()}`);
929
+ lines.push("");
930
+ for (const [key, value] of Object.entries(merged)) {
931
+ if (!key.startsWith("_claude_mode_")) {
932
+ lines.push(`${key}=${value}`);
933
+ }
934
+ }
935
+ try {
936
+ writeFileSync2(targetPath, lines.join("\n") + "\n", "utf-8");
937
+ } catch (error) {
938
+ const classified = classifyError(error);
939
+ throw setupEnvWriteError(classified.message, classified.hint);
940
+ }
941
+ }
942
+ function saveEnvFile(envVars, envPath) {
943
+ const targetPath = getEnvPath(envPath);
944
+ try {
945
+ const content = formatEnvFile(envVars);
946
+ writeFileSync2(targetPath, content + "\n", "utf-8");
947
+ } catch (error) {
948
+ const classified = classifyError(error);
949
+ throw setupEnvWriteError(classified.message, classified.hint);
950
+ }
951
+ }
952
+ function loadEnvFile(envPath) {
953
+ const targetPath = getEnvPath(envPath);
954
+ if (!existsSync2(targetPath)) {
955
+ return {};
956
+ }
957
+ try {
958
+ const content = readFileSync2(targetPath, "utf-8");
959
+ const vars = {};
960
+ for (const line of content.split("\n")) {
961
+ const trimmed = line.trim();
962
+ if (trimmed === "" || trimmed.startsWith("#")) {
963
+ continue;
964
+ }
965
+ const eqIndex = trimmed.indexOf("=");
966
+ if (eqIndex > 0) {
967
+ const key = trimmed.substring(0, eqIndex).trim();
968
+ let value = trimmed.substring(eqIndex + 1).trim();
969
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
970
+ value = value.slice(1, -1);
971
+ }
972
+ vars[key] = value;
973
+ }
974
+ }
975
+ return vars;
976
+ } catch {
977
+ return {};
978
+ }
979
+ }
980
+ function saveConfiguration(providerConfigs, defaults, currentConfig) {
981
+ const envVars = buildEnvVars(providerConfigs);
982
+ let config2 = currentConfig || loadConfig();
983
+ config2.defaultProvider = defaults.provider;
984
+ config2.defaultModel = defaults.model;
985
+ config2.configuredProviders = providerConfigs.map((c) => c.key);
986
+ try {
987
+ const configDir = getConfigDir2();
988
+ if (!existsSync2(configDir)) {
989
+ mkdirSync2(configDir, { recursive: true });
990
+ }
991
+ const configPath = getConfigPath();
992
+ writeFileSync2(configPath, JSON.stringify(config2, null, 2), "utf-8");
993
+ } catch (error) {
994
+ const classified = classifyError(error);
995
+ throw setupConfigWriteError(classified.message, classified.hint);
996
+ }
997
+ if (existsSync2(getEnvPath())) {
998
+ mergeEnvFile(envVars);
999
+ } else {
1000
+ saveEnvFile(envVars);
1001
+ }
1002
+ }
1003
+ function displaySuccess(providerConfigs, defaults) {
1004
+ console.clear();
1005
+ printHeader("Setup Complete!");
1006
+ console.log(chalk2.green("\u2713") + " Configuration saved successfully!");
1007
+ console.log("");
1008
+ console.log(chalk2.bold("Configured Providers:"));
1009
+ for (const config2 of providerConfigs) {
1010
+ const status = config2.validated ? chalk2.green("\u2713") : chalk2.yellow("\u26A0");
1011
+ console.log(` ${status} ${config2.name}`);
1012
+ }
1013
+ console.log("");
1014
+ console.log(chalk2.bold("Default Configuration:"));
1015
+ console.log(` Provider: ${chalk2.cyan(defaults.provider)}`);
1016
+ console.log(` Model: ${chalk2.cyan(defaults.model)}`);
1017
+ console.log("");
1018
+ console.log(chalk2.bold("Next Steps:"));
1019
+ console.log(" Run " + chalk2.cyan("claude-mode") + " to start using Claude Code");
1020
+ console.log(" Run " + chalk2.cyan("claude-mode --list") + " to see all available models");
1021
+ console.log(" Run " + chalk2.cyan('claude-mode -p "your prompt"') + " for headless mode");
1022
+ console.log("");
1023
+ console.log(chalk2.gray("Configuration files:"));
1024
+ console.log(chalk2.gray(` Config: ${getConfigPath()}`));
1025
+ console.log(chalk2.gray(` Env: ${getEnvPath()}`));
1026
+ console.log("");
1027
+ }
1028
+ async function runSetup(options = {}) {
1029
+ try {
1030
+ const { force = false, provider: forceProvider, skipValidation = false } = options;
1031
+ const status = detectSetupStatus();
1032
+ const isFirstTime = status === "first-time";
1033
+ if (!force && !isFirstTime) {
1034
+ const shouldContinue = await displayUpdatePrompt();
1035
+ if (!shouldContinue) {
1036
+ return;
1037
+ }
1038
+ }
1039
+ await displayWelcome(isFirstTime);
1040
+ const providerKeys = await selectProviders(forceProvider);
1041
+ const providerConfigs = [];
1042
+ const currentConfig = loadConfig();
1043
+ for (const providerKey of providerKeys) {
1044
+ try {
1045
+ const config2 = await configureProvider(providerKey, skipValidation);
1046
+ providerConfigs.push(config2);
1047
+ } catch (error) {
1048
+ console.log("");
1049
+ const errorMessage = error instanceof Error ? error.message : String(error);
1050
+ console.log(chalk2.yellow(`Failed to configure ${providerKey}: ${errorMessage}`));
1051
+ const shouldContinue = await confirm({
1052
+ message: "Continue with remaining providers?",
1053
+ default: true
1054
+ });
1055
+ if (!shouldContinue) {
1056
+ throw setupCancelledError();
1057
+ }
1058
+ }
1059
+ }
1060
+ if (providerConfigs.length === 0) {
1061
+ throw setupIncompleteError("No providers were configured");
1062
+ }
1063
+ let currentDefaults;
1064
+ if (currentConfig.defaultProvider && currentConfig.defaultModel) {
1065
+ currentDefaults = {
1066
+ provider: currentConfig.defaultProvider,
1067
+ model: currentConfig.defaultModel
1068
+ };
1069
+ }
1070
+ const configuredProviderKeys = providerConfigs.map((c) => c.key);
1071
+ const defaults = await selectDefaults(configuredProviderKeys, currentDefaults);
1072
+ const confirmed = await reviewAndConfirm(providerConfigs, defaults, currentConfig);
1073
+ if (!confirmed) {
1074
+ throw setupCancelledError();
1075
+ }
1076
+ console.log("");
1077
+ console.log(chalk2.gray("Saving configuration..."));
1078
+ saveConfiguration(providerConfigs, defaults, currentConfig);
1079
+ displaySuccess(providerConfigs, defaults);
1080
+ } catch (error) {
1081
+ const classified = classifyError(error);
1082
+ if (classified.message === "Setup cancelled") {
1083
+ console.log("");
1084
+ console.log(chalk2.yellow("Setup cancelled."));
1085
+ console.log("Run " + chalk2.cyan("claude-mode setup") + " to try again.");
1086
+ console.log("");
1087
+ return;
1088
+ }
1089
+ console.log("");
1090
+ console.log(chalk2.red("Setup failed:"));
1091
+ printError(classified);
1092
+ console.log("");
1093
+ console.log(chalk2.gray("You can run " + chalk2.cyan("claude-mode setup") + " to try again."));
1094
+ console.log("");
1095
+ process.exit(1);
1096
+ }
1097
+ }
1098
+
1099
+ // src/index.ts
1100
+ config();
1101
+ var __filename = fileURLToPath(import.meta.url);
1102
+ var __dirname = path3.dirname(__filename);
1103
+ config({ path: path3.join(__dirname, "..", ".env") });
1104
+ var program = new Command();
1105
+ function printHeader2(text) {
1106
+ console.log("");
1107
+ console.log(chalk3.bold.blue("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
1108
+ console.log(chalk3.bold.blue("\u2551") + " " + chalk3.cyan(text));
1109
+ console.log(chalk3.bold.blue("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
1110
+ console.log("");
1111
+ }
524
1112
  function printConfig(provider, modelId, mode) {
525
- console.log(chalk2.cyan("Provider:") + " " + provider.name);
526
- console.log(chalk2.cyan("Model:") + " " + modelId);
527
- console.log(chalk2.cyan("Base URL:") + " " + provider.getBaseUrl());
528
- console.log(chalk2.cyan("Mode:") + " " + mode);
1113
+ console.log(chalk3.cyan("Provider:") + " " + provider.name);
1114
+ console.log(chalk3.cyan("Model:") + " " + modelId);
1115
+ console.log(chalk3.cyan("Base URL:") + " " + provider.getBaseUrl());
1116
+ console.log(chalk3.cyan("Mode:") + " " + mode);
529
1117
  console.log("");
530
1118
  }
1119
+ function shouldTriggerSetup() {
1120
+ const status = detectSetupStatus();
1121
+ if (status === "first-time") {
1122
+ return true;
1123
+ }
1124
+ if (status === "incomplete") {
1125
+ return true;
1126
+ }
1127
+ return false;
1128
+ }
531
1129
  function isClaudeInstalled() {
532
1130
  try {
533
1131
  execSync("which claude", { stdio: "ignore" });
@@ -602,16 +1200,16 @@ function formatHealthStatus(result) {
602
1200
  const name = provider?.name || result.provider;
603
1201
  if (result.healthy) {
604
1202
  const latency = result.latencyMs ? ` (${result.latencyMs}ms)` : "";
605
- return `${chalk2.green("\u2713")} ${name}${chalk2.gray(latency)}`;
1203
+ return `${chalk3.green("\u2713")} ${name}${chalk3.gray(latency)}`;
606
1204
  } else {
607
1205
  const error = result.error?.message || "unavailable";
608
- return `${chalk2.red("\u2717")} ${name} ${chalk2.gray(`- ${error}`)}`;
1206
+ return `${chalk3.red("\u2717")} ${name} ${chalk3.gray(`- ${error}`)}`;
609
1207
  }
610
1208
  }
611
1209
  async function displayHealthCheck() {
612
1210
  const skipHealthCheck = getConfig("skipHealthCheck");
613
1211
  if (skipHealthCheck) return;
614
- console.log(chalk2.gray("Checking provider availability..."));
1212
+ console.log(chalk3.gray("Checking provider availability..."));
615
1213
  const results = await checkAllProvidersHealth();
616
1214
  console.log("");
617
1215
  for (const result of results) {
@@ -621,10 +1219,10 @@ async function displayHealthCheck() {
621
1219
  }
622
1220
  async function interactiveMode(skipPermissions) {
623
1221
  console.clear();
624
- printHeader("Claude Mode");
1222
+ printHeader2("Claude Mode");
625
1223
  await displayHealthCheck();
626
1224
  const allProviders = getProviders();
627
- const providerKey = await select({
1225
+ const providerKey = await select2({
628
1226
  message: "Select Provider:",
629
1227
  choices: getProviderKeys().map((key) => ({
630
1228
  name: allProviders[key].name,
@@ -633,20 +1231,20 @@ async function interactiveMode(skipPermissions) {
633
1231
  }))
634
1232
  });
635
1233
  const provider = getProvider(providerKey);
636
- console.log(chalk2.yellow("\u2192 Selected:") + " " + provider.name);
1234
+ console.log(chalk3.yellow("\u2192 Selected:") + " " + provider.name);
637
1235
  const providerModels = await getModels(providerKey);
638
1236
  if (providerModels.length === 0) {
639
- console.log(chalk2.yellow("No models available for this provider."));
640
- console.log(chalk2.gray("You can enter a model ID manually."));
641
- const modelId2 = await input({
1237
+ console.log(chalk3.yellow("No models available for this provider."));
1238
+ console.log(chalk3.gray("You can enter a model ID manually."));
1239
+ const modelId2 = await input2({
642
1240
  message: "Enter model ID:",
643
1241
  validate: (value) => value.length > 0 ? true : "Model ID cannot be empty"
644
1242
  });
645
- console.log(chalk2.yellow("\u2192 Model:") + " " + modelId2);
1243
+ console.log(chalk3.yellow("\u2192 Model:") + " " + modelId2);
646
1244
  await continueInteractiveMode(provider, modelId2, skipPermissions);
647
1245
  return;
648
1246
  }
649
- const modelId = await select({
1247
+ const modelId = await select2({
650
1248
  message: "Select Model:",
651
1249
  choices: providerModels.map((model) => ({
652
1250
  name: model.name,
@@ -655,11 +1253,11 @@ async function interactiveMode(skipPermissions) {
655
1253
  }))
656
1254
  });
657
1255
  const selectedModel = providerModels.find((m) => m.id === modelId);
658
- console.log(chalk2.yellow("\u2192 Selected:") + " " + selectedModel?.name + ` (${modelId})`);
1256
+ console.log(chalk3.yellow("\u2192 Selected:") + " " + selectedModel?.name + ` (${modelId})`);
659
1257
  await continueInteractiveMode(provider, modelId, skipPermissions);
660
1258
  }
661
1259
  async function continueInteractiveMode(provider, modelId, skipPermissions) {
662
- const mode = await select({
1260
+ const mode = await select2({
663
1261
  message: "Select Mode:",
664
1262
  choices: [
665
1263
  { name: "Terminal (interactive)", value: "terminal" },
@@ -668,13 +1266,13 @@ async function continueInteractiveMode(provider, modelId, skipPermissions) {
668
1266
  });
669
1267
  let prompt;
670
1268
  if (mode === "headless") {
671
- prompt = await input({
1269
+ prompt = await input2({
672
1270
  message: "Enter your prompt:",
673
1271
  validate: (value) => value.length > 0 ? true : "Prompt cannot be empty"
674
1272
  });
675
1273
  }
676
1274
  if (!skipPermissions) {
677
- skipPermissions = await select({
1275
+ skipPermissions = await select2({
678
1276
  message: "Skip permission prompts when executing commands?",
679
1277
  choices: [
680
1278
  { name: "No (ask for permission)", value: false },
@@ -683,19 +1281,19 @@ async function continueInteractiveMode(provider, modelId, skipPermissions) {
683
1281
  });
684
1282
  }
685
1283
  console.log(
686
- chalk2.yellow("\u2192 Skip permissions:") + " " + (skipPermissions ? chalk2.red("Yes (\u26A0\uFE0F auto-approve)") : chalk2.green("No (ask)"))
1284
+ chalk3.yellow("\u2192 Skip permissions:") + " " + (skipPermissions ? chalk3.red("Yes (\u26A0\uFE0F auto-approve)") : chalk3.green("No (ask)"))
687
1285
  );
688
1286
  const isHeadless = mode === "headless";
689
1287
  if (isHeadless) {
690
- printHeader("Executing Claude Code (Headless)");
1288
+ printHeader2("Executing Claude Code (Headless)");
691
1289
  } else {
692
- printHeader("Launching Claude Code (Interactive)");
1290
+ printHeader2("Launching Claude Code (Interactive)");
693
1291
  }
694
1292
  printConfig(provider, modelId, isHeadless ? "Headless" : "Interactive");
695
1293
  try {
696
1294
  await runClaude(provider, modelId, isHeadless, skipPermissions, prompt);
697
1295
  } catch (error) {
698
- console.error(chalk2.red("Error:"), error);
1296
+ console.error(chalk3.red("Error:"), error);
699
1297
  process.exit(1);
700
1298
  }
701
1299
  }
@@ -703,8 +1301,8 @@ async function quickMode(providerArg, modelArg, skipPermissions, modeArg, prompt
703
1301
  const providerKey = resolveProvider(providerArg);
704
1302
  const provider = getProvider(providerKey);
705
1303
  if (!provider) {
706
- console.error(chalk2.red(`Unknown provider: ${providerArg}`));
707
- console.log(chalk2.gray("Available providers: " + getProviderKeys().join(", ")));
1304
+ console.error(chalk3.red(`Unknown provider: ${providerArg}`));
1305
+ console.log(chalk3.gray("Available providers: " + getProviderKeys().join(", ")));
708
1306
  process.exit(1);
709
1307
  }
710
1308
  const modelId = await resolveModel(providerKey, modelArg);
@@ -729,7 +1327,7 @@ async function quickMode(providerArg, modelArg, skipPermissions, modeArg, prompt
729
1327
  }
730
1328
  }
731
1329
  if (isHeadless && !prompt) {
732
- prompt = await input({
1330
+ prompt = await input2({
733
1331
  message: "Enter your prompt:",
734
1332
  validate: (value) => value.length > 0 ? true : "Prompt cannot be empty"
735
1333
  });
@@ -738,23 +1336,23 @@ async function quickMode(providerArg, modelArg, skipPermissions, modeArg, prompt
738
1336
  try {
739
1337
  await runClaude(provider, modelId, isHeadless, skipPermissions, prompt);
740
1338
  } catch (error) {
741
- console.error(chalk2.red("Error:"), error);
1339
+ console.error(chalk3.red("Error:"), error);
742
1340
  process.exit(1);
743
1341
  }
744
1342
  }
745
1343
  async function listModels() {
746
- console.log(chalk2.bold("\nAvailable Models by Provider:\n"));
1344
+ console.log(chalk3.bold("\nAvailable Models by Provider:\n"));
747
1345
  const allProviders = getProviders();
748
1346
  for (const providerKey of getProviderKeys()) {
749
1347
  const provider = allProviders[providerKey];
750
1348
  const providerModels = await getModels(providerKey);
751
- console.log(chalk2.cyan(`${provider.name}:`));
752
- console.log(chalk2.gray(` ${provider.getDescription()}`));
1349
+ console.log(chalk3.cyan(`${provider.name}:`));
1350
+ console.log(chalk3.gray(` ${provider.getDescription()}`));
753
1351
  if (providerModels.length === 0) {
754
- console.log(` ${chalk2.gray("(no models found)")}`);
1352
+ console.log(` ${chalk3.gray("(no models found)")}`);
755
1353
  } else {
756
1354
  for (const model of providerModels) {
757
- console.log(` ${chalk2.green(model.shortcut.padEnd(14))} \u2192 ${model.id}`);
1355
+ console.log(` ${chalk3.green(model.shortcut.padEnd(14))} \u2192 ${model.id}`);
758
1356
  }
759
1357
  }
760
1358
  console.log("");
@@ -762,14 +1360,14 @@ async function listModels() {
762
1360
  }
763
1361
  function showConfig() {
764
1362
  const config2 = loadConfig();
765
- console.log(chalk2.bold("\nCurrent Configuration:\n"));
1363
+ console.log(chalk3.bold("\nCurrent Configuration:\n"));
766
1364
  console.log(JSON.stringify(config2, null, 2));
767
1365
  console.log("");
768
1366
  }
769
1367
  function initConfigCommand() {
770
1368
  const configPath = initConfig();
771
- console.log(chalk2.green(`Config file created at: ${configPath}`));
772
- console.log(chalk2.gray("Edit this file to customize your settings."));
1369
+ console.log(chalk3.green(`Config file created at: ${configPath}`));
1370
+ console.log(chalk3.gray("Edit this file to customize your settings."));
773
1371
  }
774
1372
  function generateBashCompletion() {
775
1373
  const providerKeys = getProviderKeys();
@@ -897,13 +1495,13 @@ function printCompletion(shell) {
897
1495
  console.log(generateFishCompletion());
898
1496
  break;
899
1497
  default:
900
- console.error(chalk2.red(`Unknown shell: ${shell}`));
901
- console.log(chalk2.gray("Supported shells: bash, zsh, fish"));
1498
+ console.error(chalk3.red(`Unknown shell: ${shell}`));
1499
+ console.log(chalk3.gray("Supported shells: bash, zsh, fish"));
902
1500
  process.exit(1);
903
1501
  }
904
1502
  }
905
1503
  async function healthCommand() {
906
- console.log(chalk2.bold("\nProvider Health Check:\n"));
1504
+ console.log(chalk3.bold("\nProvider Health Check:\n"));
907
1505
  const results = await checkAllProvidersHealth();
908
1506
  for (const result of results) {
909
1507
  console.log(" " + formatHealthStatus(result));
@@ -912,40 +1510,40 @@ async function healthCommand() {
912
1510
  const healthy = results.filter((r) => r.healthy).length;
913
1511
  const total = results.length;
914
1512
  if (healthy === total) {
915
- console.log(chalk2.green(`All ${total} providers are healthy.`));
1513
+ console.log(chalk3.green(`All ${total} providers are healthy.`));
916
1514
  } else {
917
- console.log(chalk2.yellow(`${healthy}/${total} providers are healthy.`));
1515
+ console.log(chalk3.yellow(`${healthy}/${total} providers are healthy.`));
918
1516
  }
919
1517
  }
920
1518
  program.name("claude-mode").description(
921
1519
  `
922
- ${chalk2.bold("Claude Mode")} - Launch Claude Code with different providers
1520
+ ${chalk3.bold("Claude Mode")} - Launch Claude Code with different providers
923
1521
 
924
- ${chalk2.bold("Providers:")}
1522
+ ${chalk3.bold("Providers:")}
925
1523
  openrouter OpenRouter API
926
1524
  ollama-cloud Ollama Cloud (OLLAMA_HOST)
927
1525
  ollama-local Ollama Local (OLLAMA_BASE_URL_LOCAL)
928
1526
  ollama-custom Ollama Custom (OLLAMA_BASE_URL_CUSTOM)
929
1527
 
930
- ${chalk2.bold("Model shortcuts:")}
1528
+ ${chalk3.bold("Model shortcuts:")}
931
1529
  OpenRouter (Premium): gpt52, gpt52-pro, gpt52-codex, opus, grok
932
1530
  OpenRouter (Value): deepseek, zai-glm47-flash, seed16, sonnet, haiku
933
1531
  OpenRouter (Existing): gpt120, glm47, gemini-pro, gemini-flash
934
1532
  Ollama: Models discovered dynamically via API
935
1533
 
936
- ${chalk2.bold("Mode shortcuts:")}
1534
+ ${chalk3.bold("Mode shortcuts:")}
937
1535
  terminal, t, interactive, i - Interactive terminal mode
938
1536
  headless, h, prompt, p - Headless mode with prompt
939
1537
 
940
- ${chalk2.bold("Options:")}
1538
+ ${chalk3.bold("Options:")}
941
1539
  -p, --prompt <prompt> Headless mode (uses defaults if provider/model not set)
942
1540
  -d, --dangerously-skip-permissions Skip permission prompts (\u26A0\uFE0F use with caution)
943
1541
 
944
- ${chalk2.bold("Default Provider/Model:")}
1542
+ ${chalk3.bold("Default Provider/Model:")}
945
1543
  Set in ~/.claude-mode/claude-mode.json:
946
1544
  { "defaultProvider": "openrouter", "defaultModel": "sonnet" }
947
1545
 
948
- ${chalk2.bold("Examples:")}
1546
+ ${chalk3.bold("Examples:")}
949
1547
  claude-mode Interactive menu
950
1548
  claude-mode -p "perform a code review" Headless with default provider/model
951
1549
  claude-mode openrouter sonnet Interactive with Claude Sonnet
@@ -978,7 +1576,24 @@ program.command("config").description("Manage configuration").argument("[action]
978
1576
  program.command("completion").description("Generate shell completion scripts").argument("<shell>", "Shell type: bash, zsh, fish").action((shell) => {
979
1577
  printCompletion(shell);
980
1578
  });
1579
+ program.command("setup").description("Interactive setup wizard for first-time configuration").option("-f, --force", "Re-run setup even if config exists").option("-p, --provider <provider>", "Configure only this provider").option("--skip-validation", "Skip API key validation").action(async (options) => {
1580
+ await runSetup({
1581
+ force: options.force,
1582
+ provider: options.provider,
1583
+ skipValidation: options.skipValidation
1584
+ });
1585
+ });
981
1586
  program.option("-d, --dangerously-skip-permissions", "Skip permission prompts when executing commands").option("-l, --list", "List all available providers and models").option("-p, --prompt <prompt>", "Run in headless mode with the given prompt (uses defaults if provider/model not specified)").argument("[provider]", "Provider (openrouter, ollama-cloud, ollama-local, ollama-custom)").argument("[model]", "Model ID or shortcut").argument("[mode]", "Mode (terminal/t, headless/h) or prompt for headless").argument("[promptArg]", "Prompt for headless mode").action(async (provider, model, mode, promptArg, options) => {
1587
+ if (shouldTriggerSetup()) {
1588
+ const shouldSetup = await confirm2({
1589
+ message: "No configuration found. Would you like to run setup?",
1590
+ default: true
1591
+ });
1592
+ if (shouldSetup) {
1593
+ await runSetup({ force: false });
1594
+ return;
1595
+ }
1596
+ }
982
1597
  if (options.list) {
983
1598
  await listModels();
984
1599
  return;
@@ -990,14 +1605,14 @@ program.option("-d, --dangerously-skip-permissions", "Skip permission prompts wh
990
1605
  const effectiveProvider = provider || defaultProvider;
991
1606
  const effectiveModel = model || defaultModel;
992
1607
  if (!effectiveProvider || !effectiveModel) {
993
- console.error(chalk2.red("Error: Provider and model are required"));
1608
+ console.error(chalk3.red("Error: Provider and model are required"));
994
1609
  if (!effectiveProvider && !effectiveModel) {
995
- console.log(chalk2.gray("Set defaults in config: claude-mode config init"));
996
- console.log(chalk2.gray("Then edit ~/.claude-mode/claude-mode.json to set defaultProvider and defaultModel"));
1610
+ console.log(chalk3.gray("Set defaults in config: claude-mode config init"));
1611
+ console.log(chalk3.gray("Then edit ~/.claude-mode/claude-mode.json to set defaultProvider and defaultModel"));
997
1612
  } else if (!effectiveProvider) {
998
- console.log(chalk2.gray("Missing: provider (set defaultProvider in config or pass as argument)"));
1613
+ console.log(chalk3.gray("Missing: provider (set defaultProvider in config or pass as argument)"));
999
1614
  } else {
1000
- console.log(chalk2.gray("Missing: model (set defaultModel in config or pass as argument)"));
1615
+ console.log(chalk3.gray("Missing: model (set defaultModel in config or pass as argument)"));
1001
1616
  }
1002
1617
  process.exit(1);
1003
1618
  }
@@ -1011,10 +1626,10 @@ program.option("-d, --dangerously-skip-permissions", "Skip permission prompts wh
1011
1626
  if (defaultModel) {
1012
1627
  await quickMode(provider, defaultModel, skipPermissions, mode, promptArg);
1013
1628
  } else {
1014
- console.error(chalk2.red("Error: Model is required when provider is specified"));
1015
- console.log(chalk2.gray("Usage: claude-mode <provider> <model> [mode] [prompt]"));
1016
- console.log(chalk2.gray("Or set defaultModel in ~/.claude-mode/claude-mode.json"));
1017
- console.log(chalk2.gray("Run claude-mode --list to see available models"));
1629
+ console.error(chalk3.red("Error: Model is required when provider is specified"));
1630
+ console.log(chalk3.gray("Usage: claude-mode <provider> <model> [mode] [prompt]"));
1631
+ console.log(chalk3.gray("Or set defaultModel in ~/.claude-mode/claude-mode.json"));
1632
+ console.log(chalk3.gray("Run claude-mode --list to see available models"));
1018
1633
  process.exit(1);
1019
1634
  }
1020
1635
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cbuk100011/claude-mode",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "CLI launcher for Claude Code with multiple AI providers",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -27,6 +27,7 @@
27
27
  "typecheck": "tsc --noEmit"
28
28
  },
29
29
  "dependencies": {
30
+ "@cbuk100011/claude-mode": "^1.3.0",
30
31
  "@inquirer/prompts": "^7.2.1",
31
32
  "chalk": "^5.4.1",
32
33
  "commander": "^13.1.0",