@levr-one/cli 0.1.1 → 0.3.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.
@@ -1,8 +1,8 @@
1
- import "./credentials-Ciq9mA7N.js";
2
- import { authGetSitesV1, configureClient } from "./sdk-client-rpUEykDw.js";
1
+ import "./env-NxtzJJPk.js";
2
+ import { authGetSitesV1, configureClient } from "./sdk-client-BeE6mXns.js";
3
3
  import { saveWorkspace } from "./workspace-store-4hfvsEHS.js";
4
- import "./token-refresh-Pl6Adngb.js";
5
- import { resolveToken } from "./resolve-token-CQU55U6J.js";
4
+ import "./token-refresh-Cz-FqDtC.js";
5
+ import { resolveToken } from "./resolve-token-BRPrqdG-.js";
6
6
 
7
7
  //#region src/commands/workspace/selectHandler.ts
8
8
  async function selectHandler(_flags, workspaceId) {
@@ -1,6 +1,6 @@
1
- import { getApiUrl, getPatToken, readCredentials } from "./credentials-Ciq9mA7N.js";
2
- import { authGetProfileV1, configureClient } from "./sdk-client-rpUEykDw.js";
3
- import { isTokenExpired } from "./token-refresh-Pl6Adngb.js";
1
+ import { getApiUrl, getPatToken, readCredentials } from "./env-NxtzJJPk.js";
2
+ import { authGetProfileV1, configureClient } from "./sdk-client-BeE6mXns.js";
3
+ import { isTokenExpired } from "./token-refresh-Cz-FqDtC.js";
4
4
  import chalk from "chalk";
5
5
 
6
6
  //#region src/commands/auth/statusHandler.ts
@@ -23,6 +23,12 @@ async function statusHandler() {
23
23
  this.process.exitCode = 1;
24
24
  return;
25
25
  }
26
+ const storedUrl = creds.api_url.replace(/\/+$/, "");
27
+ if (storedUrl !== apiUrl) {
28
+ this.process.stdout.write(`${chalk.red("error")} Stored credentials are for ${storedUrl}, but the current target is ${apiUrl}. Run 'levr auth login' to authenticate against this server.\n`);
29
+ this.process.exitCode = 1;
30
+ return;
31
+ }
26
32
  if (isTokenExpired(creds)) {
27
33
  this.process.stdout.write(`${chalk.red("error")} Token expired. Run 'levr auth login' to re-authenticate.\n`);
28
34
  this.process.exitCode = 1;
@@ -1,4 +1,4 @@
1
- import { CLI_CLIENT_ID, deleteCredentials, getApiUrl, writeCredentials } from "./credentials-Ciq9mA7N.js";
1
+ import { CLI_CLIENT_ID, deleteCredentials, getApiUrl, writeCredentials } from "./env-NxtzJJPk.js";
2
2
 
3
3
  //#region src/auth/token-refresh.ts
4
4
  const REFRESH_BUFFER_MS = 300 * 1e3;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@levr-one/cli",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "The command-line interface for Levr",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -13,9 +13,11 @@
13
13
  "README.md"
14
14
  ],
15
15
  "dependencies": {
16
+ "@clack/prompts": "^1.7.0",
16
17
  "@stricli/auto-complete": "^1.2.0",
17
18
  "@stricli/core": "^1.2.0",
18
19
  "chalk": "^5.6.2",
20
+ "jsonc-parser": "^3.3.1",
19
21
  "open": "^10.1.0",
20
22
  "ora": "^9.0.0",
21
23
  "zod": "^3.25.0"
@@ -1,54 +0,0 @@
1
- import { mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
2
- import { homedir } from "node:os";
3
- import { dirname, join } from "node:path";
4
-
5
- //#region src/utils/env.ts
6
- const DEFAULT_API_URL = "https://api.levr.one";
7
- const DEFAULT_AUTH_URL = "https://auth.levr.one";
8
- /** OAuth client ID for the CLI (seeded in oauth_clients table) */
9
- const CLI_CLIENT_ID = "3";
10
- function getApiUrl() {
11
- return process.env["LEVR_URL"] || DEFAULT_API_URL;
12
- }
13
- function getAuthUrl() {
14
- return process.env["LEVR_AUTH_URL"] || DEFAULT_AUTH_URL;
15
- }
16
- function getTeamId(flagValue) {
17
- return flagValue || process.env["LEVR_TEAM_ID"] || void 0;
18
- }
19
- function getPatToken() {
20
- return process.env["LEVR_TOKEN"];
21
- }
22
- function getSourceOverride() {
23
- return process.env["LEVR_SOURCE"];
24
- }
25
- function getAutomationSourceIdOverride() {
26
- return process.env["LEVR_AUTOMATION_SOURCE_ID"];
27
- }
28
-
29
- //#endregion
30
- //#region src/auth/credentials.ts
31
- const CREDENTIALS_PATH = join(join(homedir(), ".config", "levr"), "credentials.json");
32
- function readCredentials() {
33
- try {
34
- const raw = readFileSync(CREDENTIALS_PATH, "utf8");
35
- return JSON.parse(raw);
36
- } catch {
37
- return null;
38
- }
39
- }
40
- function writeCredentials(creds) {
41
- mkdirSync(dirname(CREDENTIALS_PATH), { recursive: true });
42
- writeFileSync(CREDENTIALS_PATH, JSON.stringify(creds, null, 2), { mode: 384 });
43
- }
44
- function deleteCredentials() {
45
- try {
46
- unlinkSync(CREDENTIALS_PATH);
47
- return true;
48
- } catch {
49
- return false;
50
- }
51
- }
52
-
53
- //#endregion
54
- export { CLI_CLIENT_ID, deleteCredentials, getApiUrl, getAuthUrl, getAutomationSourceIdOverride, getPatToken, getSourceOverride, getTeamId, readCredentials, writeCredentials };
@@ -1,44 +0,0 @@
1
- import "./credentials-Ciq9mA7N.js";
2
- import { authGetSitesV1, configureClient } from "./sdk-client-rpUEykDw.js";
3
- import { loadWorkspace } from "./workspace-store-4hfvsEHS.js";
4
- import "./token-refresh-Pl6Adngb.js";
5
- import { resolveToken } from "./resolve-token-CQU55U6J.js";
6
-
7
- //#region src/commands/workspace/listHandler.ts
8
- async function listHandler() {
9
- let auth;
10
- try {
11
- auth = await resolveToken();
12
- } catch {
13
- this.logger.error("Not authenticated. Run 'levr auth login' first.");
14
- this.process.exitCode = 1;
15
- return;
16
- }
17
- if (auth.type === "pat") {
18
- this.logger.error("Workspace listing requires JWT auth. Run 'levr auth login'.");
19
- this.process.exitCode = 1;
20
- return;
21
- }
22
- configureClient(auth);
23
- const result = await authGetSitesV1();
24
- if (result.error) {
25
- this.logger.error("Failed to list workspaces.");
26
- this.process.exitCode = 1;
27
- return;
28
- }
29
- const sites = result.data.sites;
30
- if (sites.length === 0) {
31
- this.logger.info("No workspaces available.");
32
- return;
33
- }
34
- const currentWs = loadWorkspace();
35
- this.process.stdout.write("\nWorkspaces:\n\n");
36
- for (const site of sites) {
37
- const indicator = site.workspace_id === currentWs ? " *" : "";
38
- this.process.stdout.write(` ${site.workspace_name} (${site.workspace_id}) [${site.role}]${indicator}\n`);
39
- }
40
- this.process.stdout.write("\n");
41
- }
42
-
43
- //#endregion
44
- export { listHandler };
@@ -1,33 +0,0 @@
1
- import { getPatToken, readCredentials } from "./credentials-Ciq9mA7N.js";
2
- import { isTokenExpired, refreshToken } from "./token-refresh-Pl6Adngb.js";
3
-
4
- //#region src/auth/resolve-token.ts
5
- /**
6
- * Resolve auth token in priority order:
7
- * 1. LEVR_TOKEN env var (PAT) — long-lived, no refresh
8
- * 2. Stored credentials (JWT) — auto-refresh if expired
9
- * 3. Error — not authenticated
10
- */
11
- async function resolveToken() {
12
- const pat = getPatToken();
13
- if (pat) return {
14
- token: pat,
15
- type: "pat"
16
- };
17
- let creds = readCredentials();
18
- if (creds) {
19
- if (isTokenExpired(creds)) {
20
- const refreshed = await refreshToken(creds);
21
- if (!refreshed) throw new Error("Token expired and refresh failed. Run 'levr auth login' to re-authenticate.");
22
- creds = refreshed;
23
- }
24
- return {
25
- token: creds.access_token,
26
- type: "jwt"
27
- };
28
- }
29
- throw new Error("Not authenticated. Run 'levr auth login' or set LEVR_TOKEN environment variable.");
30
- }
31
-
32
- //#endregion
33
- export { resolveToken };