@wanghuimvp/axon 0.4.0 → 0.4.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.
Files changed (2) hide show
  1. package/dist/cli.js +59 -22
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -23,6 +23,20 @@ var DEFAULTS = {
23
23
  gemini: { apiKey: "env:GEMINI_API_KEY" }
24
24
  }
25
25
  };
26
+ var ENV_VARS = {
27
+ anthropic: "ANTHROPIC_API_KEY",
28
+ openai: "OPENAI_API_KEY",
29
+ gemini: "GEMINI_API_KEY"
30
+ };
31
+ function detectProvider(fileCfg) {
32
+ for (const name of ["anthropic", "openai", "gemini"]) {
33
+ const literal = fileCfg.providers?.[name]?.apiKey;
34
+ const hasLiteral = typeof literal === "string" && !literal.startsWith("env:") && literal.trim().length > 0;
35
+ const hasEnv = (process.env[ENV_VARS[name]] ?? "").trim().length > 0;
36
+ if (hasLiteral || hasEnv) return name;
37
+ }
38
+ return "anthropic";
39
+ }
26
40
  function resolveModel(cfg) {
27
41
  const model = cfg.model ?? cfg.providers[cfg.provider]?.model ?? DEFAULT_MODELS[cfg.provider];
28
42
  if (!model) {
@@ -46,7 +60,7 @@ function loadConfig() {
46
60
  } catch {
47
61
  }
48
62
  const merged = {
49
- provider: fileCfg.provider ?? DEFAULTS.provider,
63
+ provider: fileCfg.provider ?? detectProvider(fileCfg),
50
64
  model: fileCfg.model,
51
65
  providers: { ...DEFAULTS.providers, ...fileCfg.providers ?? {} }
52
66
  };
@@ -1046,36 +1060,54 @@ function App({ engine, controller, provider, model, yolo }) {
1046
1060
 
1047
1061
  // src/ui/Setup.tsx
1048
1062
  import { useState as useState2 } from "react";
1049
- import { Box as Box5, Text as Text5 } from "ink";
1063
+ import { Box as Box5, Text as Text5, useInput as useInput3 } from "ink";
1050
1064
  import TextInput2 from "ink-text-input";
1051
1065
  import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1066
+ var SETUP_PROVIDERS = ["anthropic", "openai", "gemini"];
1052
1067
  function trimmedKey(v) {
1053
1068
  const t = v.trim();
1054
1069
  return t ? t : null;
1055
1070
  }
1071
+ function providerForDigit(input) {
1072
+ const idx = Number(input) - 1;
1073
+ return Number.isInteger(idx) && idx >= 0 && idx < SETUP_PROVIDERS.length ? SETUP_PROVIDERS[idx] : null;
1074
+ }
1056
1075
  function Setup({
1057
- provider,
1058
- info,
1076
+ initialProvider,
1059
1077
  onSubmit
1060
1078
  }) {
1079
+ const start = SETUP_PROVIDERS.includes(initialProvider) ? initialProvider : "anthropic";
1080
+ const [provider, setProvider] = useState2(start);
1061
1081
  const [value, setValue] = useState2("");
1082
+ useInput3((input) => {
1083
+ const picked = providerForDigit(input);
1084
+ if (picked) setProvider(picked);
1085
+ });
1086
+ const info = keyProviderInfo(provider);
1062
1087
  const submit = (v) => {
1063
1088
  const k = trimmedKey(v);
1064
- if (k) onSubmit(k);
1089
+ if (k) onSubmit(provider, k);
1065
1090
  };
1066
1091
  return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
1067
- /* @__PURE__ */ jsxs5(Text5, { color: "yellow", children: [
1068
- 'No API key found for "',
1069
- provider,
1070
- '".'
1071
- ] }),
1092
+ /* @__PURE__ */ jsx5(Text5, { color: "yellow", children: "Welcome to Axon. Pick a provider, then paste its API key." }),
1093
+ SETUP_PROVIDERS.map((p, i) => /* @__PURE__ */ jsxs5(Text5, { color: p === provider ? "cyan" : "gray", children: [
1094
+ p === provider ? "\u276F" : " ",
1095
+ " [",
1096
+ i + 1,
1097
+ "] ",
1098
+ p
1099
+ ] }, p)),
1072
1100
  /* @__PURE__ */ jsxs5(Text5, { children: [
1073
- "Set ",
1101
+ "Active: ",
1102
+ /* @__PURE__ */ jsx5(Text5, { bold: true, children: provider }),
1103
+ " \u2014 set ",
1074
1104
  /* @__PURE__ */ jsx5(Text5, { bold: true, children: info.envVar }),
1075
- " in your environment, or paste a key below to save it to ~/.axon/config.json."
1105
+ ", or paste a key below to save it to ~/.axon/config.json."
1076
1106
  ] }),
1077
1107
  info.url ? /* @__PURE__ */ jsxs5(Text5, { color: "gray", children: [
1078
- "Get a key at: ",
1108
+ "Get a ",
1109
+ provider,
1110
+ " key at: ",
1079
1111
  info.url
1080
1112
  ] }) : null,
1081
1113
  /* @__PURE__ */ jsxs5(Box5, { children: [
@@ -1089,27 +1121,32 @@ function Setup({
1089
1121
  import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1090
1122
  var TUI_SYSTEM = `You are Axon, an interactive agentic coding assistant. Use the tools to inspect and modify the project: read_file, list_dir, glob, grep (read-only) and write_file, edit_file, shell (these change the workspace; the user is prompted to approve each). Prefer edit_file for surgical changes. Explain briefly what you are doing.`;
1091
1123
  function Root({ deps }) {
1092
- const { cfg, controller, yolo, welcome, buildEngine, persistKey } = deps;
1124
+ const { cfg, controller, yolo, buildEngine, persistKey } = deps;
1093
1125
  const [ready, setReady] = useState3(hasUsableKey(cfg));
1094
1126
  const engineRef = useRef(null);
1095
1127
  if (ready && !engineRef.current) engineRef.current = buildEngine();
1096
1128
  if (!ready || !engineRef.current) {
1097
- const info = keyProviderInfo(cfg.provider);
1098
1129
  return /* @__PURE__ */ jsx6(
1099
1130
  Setup,
1100
1131
  {
1101
- provider: cfg.provider,
1102
- info,
1103
- onSubmit: (key) => {
1104
- persistKey(cfg.provider, key);
1105
- cfg.providers[cfg.provider] = { ...cfg.providers[cfg.provider] ?? {}, apiKey: key };
1132
+ initialProvider: cfg.provider,
1133
+ onSubmit: (provider, key) => {
1134
+ persistKey(provider, key);
1135
+ cfg.provider = provider;
1136
+ cfg.providers[provider] = { ...cfg.providers[provider] ?? {}, apiKey: key };
1106
1137
  setReady(true);
1107
1138
  }
1108
1139
  }
1109
1140
  );
1110
1141
  }
1111
1142
  return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
1112
- /* @__PURE__ */ jsx6(Text6, { color: "green", children: welcome }),
1143
+ /* @__PURE__ */ jsxs6(Text6, { color: "green", children: [
1144
+ "Axon \xB7 ",
1145
+ cfg.provider,
1146
+ "/",
1147
+ resolveModel(cfg),
1148
+ " \xB7 type a request, Ctrl+C to quit"
1149
+ ] }),
1113
1150
  /* @__PURE__ */ jsx6(
1114
1151
  App,
1115
1152
  {
@@ -1131,10 +1168,10 @@ function runTui(opts) {
1131
1168
  cfg,
1132
1169
  controller,
1133
1170
  yolo: Boolean(opts.yolo),
1134
- welcome: `Axon \xB7 ${cfg.provider}/${resolveModel(cfg)} \xB7 type a request, Ctrl+C to quit`,
1135
1171
  persistKey: (provider, key) => {
1136
1172
  try {
1137
1173
  setApiKey(provider, key);
1174
+ setConfigValue("provider", provider);
1138
1175
  } catch {
1139
1176
  }
1140
1177
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wanghuimvp/axon",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Axon — a multi-provider agentic coding CLI (Anthropic, OpenAI + OpenAI-compatible endpoints, Gemini). Runs a multi-step tool loop over your codebase.",
5
5
  "type": "module",
6
6
  "bin": {