@overscore/cli 0.13.8 → 0.13.9

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.
package/dist/index.js CHANGED
@@ -41,10 +41,17 @@ function parseEnv(content) {
41
41
  function safeApiUrl(apiUrl) {
42
42
  try {
43
43
  const h = new URL(apiUrl).hostname;
44
+ // Also allow the configured hub's host — prod by default, or a staging host
45
+ // only if the operator set OVERSCORE_HUB_URL (a trusted, user-set env var).
46
+ // If OVERSCORE_HUB_URL is unset, hubHost === overscore.dev and behavior is
47
+ // identical to before, so real users are unaffected.
48
+ const hubHost = new URL(HUB_URL).hostname;
44
49
  if (h === "overscore.dev" ||
45
50
  h.endsWith(".overscore.dev") ||
46
51
  h === "localhost" ||
47
- h === "127.0.0.1") {
52
+ h === "127.0.0.1" ||
53
+ h === hubHost ||
54
+ h.endsWith("." + hubHost)) {
48
55
  return apiUrl;
49
56
  }
50
57
  }
@@ -911,8 +918,8 @@ async function pull(slug) {
911
918
  process.exit(1);
912
919
  }
913
920
  }
914
- const apiUrl = "https://overscore.dev/api";
915
- const baseUrl = apiUrl.replace(/\/api$/, "");
921
+ const apiUrl = `${HUB_URL}/api`;
922
+ const baseUrl = HUB_URL;
916
923
  const versionQuery = versionParam ? `?version=${versionParam}` : "";
917
924
  const url = `${baseUrl}/api/dashboards/${slug}/source${versionQuery}`;
918
925
  console.log(`\n Pulling source for: ${slug}${versionParam ? ` (v${versionParam})` : ""}...`);
@@ -963,7 +970,7 @@ async function pull(slug) {
963
970
  const envContent = `# Overscore Configuration
964
971
  VITE_OVERSCORE_PROJECT_SLUG=${projectSlug}
965
972
  VITE_OVERSCORE_DASHBOARD_SLUG=${dashboardSlug}
966
- VITE_OVERSCORE_API_URL=https://overscore.dev/api
973
+ VITE_OVERSCORE_API_URL=${HUB_URL}/api
967
974
  `;
968
975
  fs.writeFileSync(path.join(targetDir, ".env"), envContent, { mode: 0o600 });
969
976
  const rulesDir = path.join(targetDir, ".claude", "rules");
@@ -1125,7 +1132,23 @@ function collectFiles(dir, prefix) {
1125
1132
  return files;
1126
1133
  }
1127
1134
  // ── Analysis commands ──────────────────────────────────────────────
1128
- const HUB_URL = "https://overscore.dev";
1135
+ // Hub the CLI talks to. Defaults to production. A TRUSTED override — the
1136
+ // OVERSCORE_HUB_URL env var, set deliberately by the operator (e.g. to point at
1137
+ // a staging environment during a security audit) — can repoint it. This is
1138
+ // distinct from the project-.env override (VITE_OVERSCORE_API_URL), which stays
1139
+ // restricted by safeApiUrl() so a poisoned project can't redirect the API key +
1140
+ // bundle to an attacker host (audit L6).
1141
+ const HUB_URL = (process.env.OVERSCORE_HUB_URL || "https://overscore.dev").replace(/\/+$/, "");
1142
+ // Bare host of the hub (overscore.dev, or overscore-test.com on staging) for
1143
+ // building the {slug}.<host> URLs we print back to the user.
1144
+ const HUB_HOST = (() => {
1145
+ try {
1146
+ return new URL(HUB_URL).hostname;
1147
+ }
1148
+ catch {
1149
+ return "overscore.dev";
1150
+ }
1151
+ })();
1129
1152
  function slugify(input) {
1130
1153
  return input
1131
1154
  .toLowerCase()
@@ -1792,7 +1815,7 @@ async function analysisNew(title) {
1792
1815
  npx @overscore/cli analysis publish
1793
1816
 
1794
1817
  The analysis will go live at:
1795
- https://${data.project_slug}.overscore.dev/analysis/${data.slug}
1818
+ https://${data.project_slug}.${HUB_HOST}/analysis/${data.slug}
1796
1819
  `);
1797
1820
  }
1798
1821
  function loadAnalysisMetadata() {
@@ -2385,7 +2408,7 @@ async function dev() {
2385
2408
  apiKey = keyData.raw_key ?? null;
2386
2409
  }
2387
2410
  catch {
2388
- console.error("\n Error: Could not reach overscore.dev to create dev session key.\n");
2411
+ console.error(`\n Error: Could not reach ${HUB_HOST} to create dev session key.\n`);
2389
2412
  process.exit(1);
2390
2413
  }
2391
2414
  if (!apiKey) {
@@ -2644,7 +2667,7 @@ async function templatePull(slug) {
2644
2667
  ? apiSlug.slice(apiSlug.indexOf("_") + 1)
2645
2668
  : apiSlug;
2646
2669
  const targetDir = path.resolve(process.cwd(), process.argv[5] || localSlug);
2647
- const url = `https://overscore.dev/api/templates/${apiSlug}/source`;
2670
+ const url = `${HUB_URL}/api/templates/${apiSlug}/source`;
2648
2671
  console.log(`\n Pulling template: ${slug}...`);
2649
2672
  let res;
2650
2673
  try {
@@ -2663,7 +2686,7 @@ async function templatePull(slug) {
2663
2686
  });
2664
2687
  }
2665
2688
  catch {
2666
- console.error(`\n Error: Could not reach overscore.dev\n`);
2689
+ console.error(`\n Error: Could not reach ${HUB_HOST}\n`);
2667
2690
  process.exit(1);
2668
2691
  }
2669
2692
  if (!res.ok) {
@@ -34,7 +34,8 @@
34
34
  import fs from "fs";
35
35
  import path from "path";
36
36
  import { execSync } from "child_process";
37
- const HUB_URL = "https://overscore.dev";
37
+ // Trusted operator override (e.g. staging audit); defaults to production.
38
+ const HUB_URL = (process.env.OVERSCORE_HUB_URL || "https://overscore.dev").replace(/\/+$/, "");
38
39
  // Mirrors the templates_slug_format CHECK in the marketplace migration.
39
40
  // `_` is the handle namespace delimiter in the stored slug ({handle}_{local}).
40
41
  const TEMPLATE_SLUG_RE = /^[a-z0-9]([a-z0-9_-]*[a-z0-9])?$/;
@@ -263,7 +264,7 @@ export async function templatePush(slugArg) {
263
264
  });
264
265
  }
265
266
  catch {
266
- console.error(`\n Error: Could not reach overscore.dev\n`);
267
+ console.error(`\n Error: Could not reach ${new URL(HUB_URL).hostname}\n`);
267
268
  process.exit(1);
268
269
  }
269
270
  const data = (await res.json().catch(() => ({})));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@overscore/cli",
3
- "version": "0.13.8",
3
+ "version": "0.13.9",
4
4
  "description": "CLI for deploying Overscore dashboards and publishing analyses",
5
5
  "bin": {
6
6
  "overscore": "dist/index.js"