@aicopycoders/exodus 2026.10.1200-beta.2 → 2026.10.1600-beta.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.
@@ -1,6 +1,6 @@
1
1
  import { apiGet, getApiUrl } from "../lib/client.js";
2
2
  import { resolveActiveBrand } from "../lib/layout.js";
3
- import { auth401Hint } from "../lib/backend-hint.js";
3
+ import { auth401Hint, describeServer } from "../lib/backend-hint.js";
4
4
  export const helpText = `
5
5
  exodus whoami — show identity and brand context for the current API key
6
6
 
@@ -9,6 +9,7 @@ Usage:
9
9
 
10
10
  Reads EXODUS_API_KEY from your .env (or env var) and asks the dashboard which
11
11
  workspace this key is bound to. Prints:
12
+ • Server (the EXODUS_API_URL host it talks to, and whether that is live or dev)
12
13
  • Brand (workspace slug + name)
13
14
  • User email + role
14
15
  • Whether the brand has full Genesis foundation knowledge filled in
@@ -44,6 +45,7 @@ export async function run() {
44
45
  ? `\nactive: (key default)`
45
46
  : "";
46
47
  console.log(`
48
+ server: ${describeServer(getApiUrl())}
47
49
  brand: ${d.workspaceName ?? "—"} (${d.workspaceSlug ?? "—"})
48
50
  user: ${d.userEmail ?? "—"} (${d.userRole ?? "—"})
49
51
  key: ${d.keyPrefix ?? "—"}${activeLine}
@@ -1,2 +1,3 @@
1
1
  export declare function isPlaceholderApiUrl(apiUrl: string): boolean;
2
+ export declare function describeServer(apiUrl: string): string;
2
3
  export declare function auth401Hint(apiUrl: string): string;
@@ -4,13 +4,27 @@ const PLACEHOLDER_MARK = "YOUR-EXODUS-BACKEND";
4
4
  export function isPlaceholderApiUrl(apiUrl) {
5
5
  return !apiUrl || apiUrl.includes(PLACEHOLDER_MARK);
6
6
  }
7
- export function auth401Hint(apiUrl) {
8
- let host = apiUrl || "(no EXODUS_API_URL set)";
7
+ function hostLabel(apiUrl) {
9
8
  try {
10
- host = new URL(apiUrl).host;
9
+ return new URL(apiUrl).host;
11
10
  }
12
11
  catch {
12
+ return apiUrl || "(no EXODUS_API_URL set)";
13
13
  }
14
+ }
15
+ export function describeServer(apiUrl) {
16
+ const host = hostLabel(apiUrl);
17
+ if (isConvexHostOf(host, PROD_BACKEND))
18
+ return `${host} (live, xo.copycoders.ai)`;
19
+ if (isConvexHostOf(host, DEV_BACKEND))
20
+ return `${host} (dev, dev.xo.copycoders.ai)`;
21
+ return host;
22
+ }
23
+ function isConvexHostOf(host, deployment) {
24
+ return host === `${deployment}.convex.site` || host === `${deployment}.convex.cloud`;
25
+ }
26
+ export function auth401Hint(apiUrl) {
27
+ const host = hostLabel(apiUrl);
14
28
  return [
15
29
  `This API key was rejected by ${host} (HTTP 401).`,
16
30
  `Keys are environment-bound — this key may belong to the other environment.`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aicopycoders/exodus",
3
- "version": "2026.10.1200-beta.2",
3
+ "version": "2026.10.1600-beta.1",
4
4
  "description": "CLI + Claude Code skills for the Copycoders Exodus ad pipeline",
5
5
  "repository": {
6
6
  "type": "git",