@leaperone/cli 0.1.9 → 0.1.11

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.
@@ -3,10 +3,39 @@ import os from "node:os";
3
3
  import path from "node:path";
4
4
  const CONFIG_DIR = path.join(os.homedir(), ".leaperone");
5
5
  const CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
6
+ const OFFICIAL_LEGACY_URL = "https://leaper.one";
6
7
  const DEFAULT_CONFIG = {
7
- baseUrl: "https://leaper.one",
8
+ apiBaseUrl: "https://api.leaper.one",
9
+ dashboardUrl: "https://dashboard.leaper.one",
10
+ siteUrl: OFFICIAL_LEGACY_URL,
8
11
  outputFormat: "text",
9
12
  };
13
+ let legacyWarningPrinted = false;
14
+ function normalizeBaseUrl(value) {
15
+ return value.replace(/\/+$/, "");
16
+ }
17
+ function warnLegacyConfig() {
18
+ if (legacyWarningPrinted)
19
+ return;
20
+ legacyWarningPrinted = true;
21
+ process.stderr.write("Warning: LEAPERONE_BASE_URL/baseUrl is deprecated; configure apiBaseUrl, dashboardUrl, and siteUrl instead.\n");
22
+ }
23
+ function splitLegacyBaseUrl(value) {
24
+ const normalized = normalizeBaseUrl(value);
25
+ if (normalized === OFFICIAL_LEGACY_URL) {
26
+ return {
27
+ apiBaseUrl: DEFAULT_CONFIG.apiBaseUrl,
28
+ dashboardUrl: DEFAULT_CONFIG.dashboardUrl,
29
+ siteUrl: DEFAULT_CONFIG.siteUrl,
30
+ };
31
+ }
32
+ // Custom/self-hosted legacy installs remain single-domain. Never guess subdomains.
33
+ return {
34
+ apiBaseUrl: normalized,
35
+ dashboardUrl: normalized,
36
+ siteUrl: normalized,
37
+ };
38
+ }
10
39
  function ensureConfigDir() {
11
40
  if (!fs.existsSync(CONFIG_DIR)) {
12
41
  fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
@@ -16,7 +45,20 @@ export function loadConfig() {
16
45
  try {
17
46
  if (fs.existsSync(CONFIG_FILE)) {
18
47
  const raw = fs.readFileSync(CONFIG_FILE, "utf-8");
19
- return { ...DEFAULT_CONFIG, ...JSON.parse(raw) };
48
+ const parsed = JSON.parse(raw);
49
+ if (parsed.baseUrl)
50
+ warnLegacyConfig();
51
+ const legacy = parsed.baseUrl
52
+ ? splitLegacyBaseUrl(parsed.baseUrl)
53
+ : DEFAULT_CONFIG;
54
+ return {
55
+ ...DEFAULT_CONFIG,
56
+ ...legacy,
57
+ ...parsed,
58
+ apiBaseUrl: normalizeBaseUrl(parsed.apiBaseUrl || legacy.apiBaseUrl),
59
+ dashboardUrl: normalizeBaseUrl(parsed.dashboardUrl || legacy.dashboardUrl),
60
+ siteUrl: normalizeBaseUrl(parsed.siteUrl || legacy.siteUrl),
61
+ };
20
62
  }
21
63
  }
22
64
  catch {
@@ -32,8 +74,16 @@ export function saveConfig(config) {
32
74
  }
33
75
  export function setConfigValue(key, value) {
34
76
  const config = loadConfig();
77
+ if (key === "baseUrl") {
78
+ warnLegacyConfig();
79
+ Object.assign(config, splitLegacyBaseUrl(value), {
80
+ baseUrl: normalizeBaseUrl(value),
81
+ });
82
+ saveConfig(config);
83
+ return;
84
+ }
35
85
  const mutable = { ...config };
36
- mutable[key] = value;
86
+ mutable[key] = key.endsWith("Url") ? normalizeBaseUrl(value) : value;
37
87
  saveConfig(mutable);
38
88
  }
39
89
  export function clearAuth() {
@@ -56,8 +106,52 @@ export function requireCredential() {
56
106
  }
57
107
  return cred;
58
108
  }
109
+ function getLegacyEnvironmentUrls() {
110
+ const legacyBaseUrl = process.env.LEAPERONE_BASE_URL;
111
+ if (!legacyBaseUrl)
112
+ return undefined;
113
+ warnLegacyConfig();
114
+ return splitLegacyBaseUrl(legacyBaseUrl);
115
+ }
116
+ export function getApiBaseUrl() {
117
+ const explicit = process.env.LEAPERONE_API_BASE_URL;
118
+ if (explicit)
119
+ return normalizeBaseUrl(explicit);
120
+ const legacyEnvironment = getLegacyEnvironmentUrls();
121
+ if (legacyEnvironment)
122
+ return legacyEnvironment.apiBaseUrl;
123
+ const config = loadConfig();
124
+ if (config.baseUrl && !config.apiBaseUrl)
125
+ warnLegacyConfig();
126
+ return config.apiBaseUrl;
127
+ }
128
+ export function getDashboardUrl() {
129
+ const explicit = process.env.LEAPERONE_DASHBOARD_URL;
130
+ if (explicit)
131
+ return normalizeBaseUrl(explicit);
132
+ const legacyEnvironment = getLegacyEnvironmentUrls();
133
+ if (legacyEnvironment)
134
+ return legacyEnvironment.dashboardUrl;
135
+ const config = loadConfig();
136
+ if (config.baseUrl && !config.dashboardUrl)
137
+ warnLegacyConfig();
138
+ return config.dashboardUrl;
139
+ }
140
+ export function getSiteUrl() {
141
+ const explicit = process.env.LEAPERONE_SITE_URL;
142
+ if (explicit)
143
+ return normalizeBaseUrl(explicit);
144
+ const legacyEnvironment = getLegacyEnvironmentUrls();
145
+ if (legacyEnvironment)
146
+ return legacyEnvironment.siteUrl;
147
+ const config = loadConfig();
148
+ if (config.baseUrl && !config.siteUrl)
149
+ warnLegacyConfig();
150
+ return config.siteUrl;
151
+ }
152
+ /** @deprecated Use getApiBaseUrl, getDashboardUrl, or getSiteUrl. */
59
153
  export function getBaseUrl() {
60
- return process.env.LEAPERONE_BASE_URL || loadConfig().baseUrl;
154
+ return getApiBaseUrl();
61
155
  }
62
156
  export { CONFIG_DIR, CONFIG_FILE };
63
157
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AACzD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEzD,MAAM,cAAc,GAAc;IAChC,OAAO,EAAE,oBAAoB;IAC7B,YAAY,EAAE,MAAM;CACrB,CAAC;AAEF,SAAS,eAAe;IACtB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC;QACH,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YAClD,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACnD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sCAAsC;IACxC,CAAC;IACD,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAiB;IAC1C,eAAe,EAAE,CAAC;IAClB,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;QAC7D,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,KAAa;IACvD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,OAAO,GAA4B,EAAE,GAAG,MAAM,EAAE,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACrB,UAAU,CAAC,OAA+B,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,MAAM,CAAC,KAAK,CAAC;IACpB,UAAU,CAAC,MAAM,CAAC,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,UAAU,EAAE,CAAC,KAAK,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CACX,uFAAuF,CACxF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,UAAU,EAAE,CAAC,OAAO,CAAC;AAChE,CAAC;AAED,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  export interface CLIConfig {
2
2
  token?: string;
3
- baseUrl: string;
3
+ /** @deprecated Use apiBaseUrl/dashboardUrl/siteUrl instead. */
4
+ baseUrl?: string;
5
+ apiBaseUrl: string;
6
+ dashboardUrl: string;
7
+ siteUrl: string;
4
8
  outputFormat: "text" | "json";
5
9
  }
6
10
  export interface ApiKeyInfo {
@@ -96,5 +100,14 @@ export interface AnalyticsData {
96
100
  export interface ApiResponse<T> {
97
101
  success: boolean;
98
102
  data?: T;
99
- error?: string;
103
+ meta?: {
104
+ requestId?: string;
105
+ nextCursor?: string | null;
106
+ hasMore?: boolean;
107
+ };
108
+ error?: string | {
109
+ code?: string;
110
+ message?: string;
111
+ requestId?: string;
112
+ };
100
113
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leaperone/cli",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "LEAPERone CLI - Manage API keys, credits, and access documentation",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,6 +8,8 @@
8
8
  "lpr": "./bin/leaperone.js"
9
9
  },
10
10
  "scripts": {
11
+ "check": "tsc --noEmit",
12
+ "test": "tsx --test --test-concurrency=1 tests/*.test.ts",
11
13
  "build": "tsc",
12
14
  "dev": "tsc --watch"
13
15
  },
@@ -40,6 +42,7 @@
40
42
  "devDependencies": {
41
43
  "@types/node": "^22.0.0",
42
44
  "@types/update-notifier": "^6.0.8",
45
+ "tsx": "^4.21.0",
43
46
  "typescript": "^5.7.0"
44
47
  }
45
48
  }
@@ -91,9 +91,20 @@ leaperone feedback reply <id> -m "<message>" # reply
91
91
 
92
92
  ```bash
93
93
  leaperone config show # show current config
94
- leaperone config set baseUrl <url> # set custom API base URL
94
+ leaperone config set apiBaseUrl <url> # external API/control plane
95
+ leaperone config set dashboardUrl <url> # browser authentication UI
96
+ leaperone config set siteUrl <url> # public docs/site
95
97
  ```
96
98
 
99
+ Environment overrides: `LEAPERONE_API_BASE_URL`, `LEAPERONE_DASHBOARD_URL`, and
100
+ `LEAPERONE_SITE_URL`. The old `baseUrl` / `LEAPERONE_BASE_URL` setting remains a
101
+ temporary compatibility fallback. Custom legacy URLs stay single-domain; the CLI
102
+ never guesses custom `api.` or `dashboard.` subdomains.
103
+
104
+ Browser login opens the Dashboard authorization UI and exchanges the one-time code
105
+ with the API using PKCE S256. A legacy atomic exchange is attempted only when the
106
+ configured API does not expose the canonical exchange route yet.
107
+
97
108
  Config file location: `~/.leaperone/config.json`
98
109
 
99
110
  ## JSON Output
@@ -154,10 +165,10 @@ const response = await client.chat.completions.create({
154
165
  ## Error Recovery
155
166
 
156
167
  - **401 Unauthorized** → API key is invalid or expired. Run `leaperone auth status` to check, then `leaperone auth login` or create a new key.
157
- - **402 / "Insufficient credits"** → Balance below $0.10. User needs to top up at https://leaper.one/dashboard/settings/credit-and-usage.
168
+ - **402 / "Insufficient credits"** → Balance below $0.10. User needs to top up at https://dashboard.leaper.one/dashboard/settings/credit-and-usage.
158
169
  - **429 Too Many Requests** → Rate limit hit. Wait and retry, or check tier limits with `leaperone endpoints`.
159
170
  - **Model unavailable** → Run `leaperone endpoints` to check which models are currently operational.
160
- - **Network error / timeout** → Verify `leaperone config show` has the correct baseUrl. Default: `https://api.leaper.one`.
171
+ - **Network error / timeout** → Verify `leaperone config show` has the correct `apiBaseUrl`. Default: `https://api.leaper.one`.
161
172
 
162
173
  ## Tips
163
174