@relyio/cli 0.3.0 → 0.3.3

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/index.js +150 -94
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import * as yaml2 from 'js-yaml';
15
15
  import { glob } from 'glob';
16
16
  import { createJiti } from 'jiti';
17
17
  import { fileURLToPath } from 'url';
18
- import { execFileSync, execSync, spawn } from 'child_process';
18
+ import { execFileSync, spawn, execSync } from 'child_process';
19
19
  import Handlebars from 'handlebars';
20
20
  import 'object-hash';
21
21
  import 'semver';
@@ -320,6 +320,61 @@ var init_secret_store = __esm({
320
320
  }
321
321
  });
322
322
 
323
+ // src/config/dashboard-url.ts
324
+ function withDashboardUrl(url, command) {
325
+ return `${DASHBOARD_URL_ENV}=${url} relyio ${command}`;
326
+ }
327
+ function requireDashboardUrl(url) {
328
+ if (!URL.canParse(url)) {
329
+ throw new Error(
330
+ `Dashboard URL ${JSON.stringify(url)} is not an address. Set ${DASHBOARD_URL_ENV} to one, or unset it to use ${DEFAULT_DASHBOARD_URL}.`
331
+ );
332
+ }
333
+ return url;
334
+ }
335
+ var DASHBOARD_URL_ENV, DEFAULT_DASHBOARD_URL;
336
+ var init_dashboard_url = __esm({
337
+ "src/config/dashboard-url.ts"() {
338
+ DASHBOARD_URL_ENV = "RELYIO_DASHBOARD_URL";
339
+ DEFAULT_DASHBOARD_URL = "https://dashboard.relyio.com";
340
+ }
341
+ });
342
+
343
+ // src/config/service-origins.ts
344
+ function configuredOrigin(service) {
345
+ switch (service) {
346
+ case "manage": {
347
+ return process.env.RELYIO_MANAGE_URL;
348
+ }
349
+ case "api": {
350
+ return process.env.RELYIO_API_URL;
351
+ }
352
+ case "ai-gateway": {
353
+ return process.env.RELYIO_AI_GATEWAY_URL;
354
+ }
355
+ }
356
+ }
357
+ function serviceOrigin(service) {
358
+ const configured = configuredOrigin(service);
359
+ if (configured) return configured.replaceAll("http://localhost", "http://127.0.0.1");
360
+ if (service !== "api" && process.env.RELYIO_API_URL) return LOCAL[service];
361
+ return DEPLOYED[service];
362
+ }
363
+ var DEPLOYED, LOCAL;
364
+ var init_service_origins = __esm({
365
+ "src/config/service-origins.ts"() {
366
+ DEPLOYED = {
367
+ manage: "https://manage.relyio.com",
368
+ api: "https://api.relyio.com",
369
+ "ai-gateway": "https://ai.relyio.com"
370
+ };
371
+ LOCAL = {
372
+ manage: "http://127.0.0.1:3100",
373
+ "ai-gateway": "http://127.0.0.1:3600"
374
+ };
375
+ }
376
+ });
377
+
323
378
  // src/config/config-manager.ts
324
379
  var config_manager_exports = {};
325
380
  __export(config_manager_exports, {
@@ -332,6 +387,7 @@ __export(config_manager_exports, {
332
387
  getAuthToken: () => getAuthToken,
333
388
  getAuthTokenAsync: () => getAuthTokenAsync,
334
389
  getDashboardUrl: () => getDashboardUrl,
390
+ getManageUrl: () => getManageUrl,
335
391
  getOrganizationId: () => getOrganizationId,
336
392
  getPATMetadata: () => getPATMetadata,
337
393
  getProjectId: () => getProjectId,
@@ -502,16 +558,15 @@ async function deleteApiKey() {
502
558
  async function loadAuthSecrets() {
503
559
  await prefetchSecrets();
504
560
  }
561
+ function getManageUrl() {
562
+ return serviceOrigin("manage");
563
+ }
505
564
  function getApiUrl() {
506
- const fromEnv = process.env.RELYIO_API_URL;
507
- if (fromEnv) {
508
- return fromEnv.replaceAll("http://localhost", "http://127.0.0.1");
509
- }
510
- return PROD_API_URL;
565
+ return serviceOrigin("api");
511
566
  }
512
567
  function getDashboardUrl() {
513
568
  const fromEnv = process.env.RELYIO_DASHBOARD_URL;
514
- return fromEnv || PROD_DASHBOARD_URL;
569
+ return fromEnv || DEFAULT_DASHBOARD_URL;
515
570
  }
516
571
  function getProjectId() {
517
572
  const config = readProjectConfig();
@@ -545,19 +600,19 @@ async function isAuthenticated() {
545
600
  const token = await getSecret("authToken");
546
601
  return token !== null;
547
602
  }
548
- var isDebug, GLOBAL_CONFIG_DIR, GLOBAL_CONFIG_FILE, PROJECT_CONFIG_FILE, LOCAL_CONFIG_DIR, LOCAL_CONFIG_FILE, PROD_API_URL, PROD_DASHBOARD_URL, defaultGlobalConfig, defaultProjectConfig, defaultLocalConfig, getAuthTokenAsync, getApiKeyAsync, config_manager_default;
603
+ var isDebug, GLOBAL_CONFIG_DIR, GLOBAL_CONFIG_FILE, PROJECT_CONFIG_FILE, LOCAL_CONFIG_DIR, LOCAL_CONFIG_FILE, defaultGlobalConfig, defaultProjectConfig, defaultLocalConfig, getAuthTokenAsync, getApiKeyAsync, config_manager_default;
549
604
  var init_config_manager = __esm({
550
605
  "src/config/config-manager.ts"() {
551
606
  init_dist();
552
607
  init_secret_store();
608
+ init_dashboard_url();
609
+ init_service_origins();
553
610
  isDebug = () => process.env.DEBUG === "true" || process.env.DEBUG === "1";
554
611
  GLOBAL_CONFIG_DIR = path5.join(os.homedir(), ".relyio");
555
612
  GLOBAL_CONFIG_FILE = path5.join(GLOBAL_CONFIG_DIR, "config.json");
556
613
  PROJECT_CONFIG_FILE = ".relyio-context.json";
557
614
  LOCAL_CONFIG_DIR = "relyio";
558
615
  LOCAL_CONFIG_FILE = path5.join(LOCAL_CONFIG_DIR, "config.yaml");
559
- PROD_API_URL = "https://api.relyio.com";
560
- PROD_DASHBOARD_URL = "https://dashboard.relyio.com";
561
616
  defaultGlobalConfig = {};
562
617
  defaultProjectConfig = {};
563
618
  defaultLocalConfig = {
@@ -597,7 +652,8 @@ var init_config_manager = __esm({
597
652
  deleteApiKey,
598
653
  isAuthenticated,
599
654
  loadAuthSecrets,
600
- // API and Dashboard (read-only, configured via env vars)
655
+ // Services and Dashboard (read-only, configured via env vars)
656
+ getManageUrl,
601
657
  getApiUrl,
602
658
  getDashboardUrl,
603
659
  // Project and org
@@ -610,7 +666,7 @@ var init_config_manager = __esm({
610
666
  });
611
667
 
612
668
  // src/config/config.ts
613
- var readGlobalConfig2, writeGlobalConfig2, readProjectConfig2, writeProjectConfig2, readLocalConfig2, writeLocalConfig2, isProjectInitialized2, isProjectLinked2, storeAuthToken2, getAuthToken2, getAuthTokenAsync2, deleteAuthToken2, storePAT2, getPATMetadata2, storeApiKey2, getApiKey2, getApiKeyAsync2, deleteApiKey2, isAuthenticated2, loadAuthSecrets2, getApiUrl2, getDashboardUrl2, getProjectId2, setProjectId2, getOrganizationId2, setOrganizationId2, config_default;
669
+ var readGlobalConfig2, writeGlobalConfig2, readProjectConfig2, writeProjectConfig2, readLocalConfig2, writeLocalConfig2, isProjectInitialized2, isProjectLinked2, storeAuthToken2, getAuthToken2, getAuthTokenAsync2, deleteAuthToken2, storePAT2, getPATMetadata2, storeApiKey2, getApiKey2, getApiKeyAsync2, deleteApiKey2, isAuthenticated2, loadAuthSecrets2, getManageUrl2, getApiUrl2, getDashboardUrl2, getProjectId2, setProjectId2, getOrganizationId2, setOrganizationId2, config_default;
614
670
  var init_config = __esm({
615
671
  "src/config/config.ts"() {
616
672
  init_config_manager();
@@ -647,10 +703,11 @@ var init_config = __esm({
647
703
  deleteApiKey: deleteApiKey2,
648
704
  isAuthenticated: isAuthenticated2,
649
705
  loadAuthSecrets: loadAuthSecrets2,
650
- getApiUrl: (
651
- // API and Dashboard (read-only, configured via env vars)
652
- getApiUrl2
706
+ getManageUrl: (
707
+ // Services and Dashboard (read-only, configured via env vars)
708
+ getManageUrl2
653
709
  ),
710
+ getApiUrl: getApiUrl2,
654
711
  getDashboardUrl: getDashboardUrl2,
655
712
  getProjectId: (
656
713
  // Project and org
@@ -686,16 +743,15 @@ var DEFAULT_TIMEOUT_MS, isDebug2, SECRET_FIELD, ApiClient, apiClient, client_def
686
743
  var init_client = __esm({
687
744
  "src/api/client.ts"() {
688
745
  init_config();
746
+ init_service_origins();
689
747
  DEFAULT_TIMEOUT_MS = 3e4;
690
748
  isDebug2 = () => process.env.DEBUG === "true" || process.env.DEBUG === "1";
691
749
  SECRET_FIELD = /secret|token|password/i;
692
750
  ApiClient = class {
693
751
  client;
694
752
  constructor() {
695
- let apiUrl = config_default.getApiUrl() || "http://localhost:3100";
696
- apiUrl = apiUrl.replaceAll("http://localhost", "http://127.0.0.1");
697
753
  this.client = axios.create({
698
- baseURL: apiUrl,
754
+ baseURL: serviceOrigin("manage"),
699
755
  headers: {
700
756
  "Content-Type": "application/json",
701
757
  Accept: "application/json",
@@ -815,7 +871,7 @@ var init_client = __esm({
815
871
  }
816
872
  } else if (error2.code === "ECONNREFUSED" || error2.code === "ENOTFOUND") {
817
873
  throw new Error(
818
- `Could not connect to API server at ${this.client.defaults.baseURL}. Please check your connection or API URL configuration.`
874
+ `Could not connect to RelyIO at ${this.client.defaults.baseURL}. Please check your connection, or RELYIO_MANAGE_URL if you set it.`
819
875
  );
820
876
  }
821
877
  throw error2.message ? new Error(error2.message) : error2;
@@ -854,10 +910,10 @@ var init_client = __esm({
854
910
  }
855
911
  });
856
912
 
857
- // ../../platform/api-contract/dist/chunk-MFO7NR2F.js
913
+ // ../../platform/api-contract/dist/chunk-HN42AOXD.js
858
914
  var ERROR_CODES;
859
- var init_chunk_MFO7NR2F = __esm({
860
- "../../platform/api-contract/dist/chunk-MFO7NR2F.js"() {
915
+ var init_chunk_HN42AOXD = __esm({
916
+ "../../platform/api-contract/dist/chunk-HN42AOXD.js"() {
861
917
  ERROR_CODES = {
862
918
  MISSING_API_KEY: { status: 401 },
863
919
  INVALID_API_KEY: { status: 401 },
@@ -918,6 +974,24 @@ var init_chunk_MFO7NR2F = __esm({
918
974
  * 2026-09-24 (REL-1080).
919
975
  */
920
976
  PLAN_DOWNGRADE_BLOCKED: { status: 409 },
977
+ /**
978
+ * Added by REL-1294, the fourth name added to §4's approved seventeen.
979
+ *
980
+ * Deleting an Organization whose Pro subscription is still live — active,
981
+ * ending at period end, past due or unpaid — is refused, because nothing
982
+ * would be left to downgrade and Stripe would keep renewing a subscription
983
+ * for an Organization that no longer exists. It is not `ACCESS_DENIED` (the
984
+ * Owner may delete) and not `PLAN_DOWNGRADE_BLOCKED` (nothing was asked of
985
+ * the Plan): a client reading it does something no other code tells it —
986
+ * names the subscription's state from `details` and sends the Owner to
987
+ * downgrade first, then delete once Pro has ended. 409 because the request
988
+ * conflicts with the Organization's current state and succeeds unchanged
989
+ * once that state does.
990
+ *
991
+ * A **customer-facing naming decision**, approved by the product owner on
992
+ * 2026-09-27 (REL-1316).
993
+ */
994
+ ORGANIZATION_DELETE_BLOCKED: { status: 409 },
921
995
  RESOURCE_NOT_FOUND: { status: 404 },
922
996
  RESOURCE_CONFLICT: { status: 409 },
923
997
  RESOURCE_EXPIRED: { status: 410 },
@@ -964,7 +1038,7 @@ function readError(body) {
964
1038
  var ContractBodyError;
965
1039
  var init_client2 = __esm({
966
1040
  "../../platform/api-contract/dist/client/index.js"() {
967
- init_chunk_MFO7NR2F();
1041
+ init_chunk_HN42AOXD();
968
1042
  ContractBodyError = class extends Error {
969
1043
  body;
970
1044
  constructor(message, body) {
@@ -7169,17 +7243,11 @@ var init_diff_service = __esm({
7169
7243
 
7170
7244
  // src/ai/core/gateway-url.ts
7171
7245
  function getGatewayUrl() {
7172
- if (process.env.RELYIO_AI_GATEWAY_URL) {
7173
- return process.env.RELYIO_AI_GATEWAY_URL.replaceAll("http://localhost", "http://127.0.0.1");
7174
- }
7175
- if (process.env.RELYIO_API_URL) return LOCAL_GATEWAY_URL;
7176
- return PRODUCTION_GATEWAY_URL;
7246
+ return serviceOrigin("ai-gateway");
7177
7247
  }
7178
- var PRODUCTION_GATEWAY_URL, LOCAL_GATEWAY_URL;
7179
7248
  var init_gateway_url = __esm({
7180
7249
  "src/ai/core/gateway-url.ts"() {
7181
- PRODUCTION_GATEWAY_URL = "https://ai.relyio.com";
7182
- LOCAL_GATEWAY_URL = "http://127.0.0.1:3600";
7250
+ init_service_origins();
7183
7251
  }
7184
7252
  });
7185
7253
 
@@ -8920,8 +8988,8 @@ var init_context_provider = __esm({
8920
8988
  }
8921
8989
  async getCurrentGitBranch() {
8922
8990
  try {
8923
- const { execSync: execSync3 } = await import('child_process');
8924
- const branch = execSync3("git rev-parse --abbrev-ref HEAD", {
8991
+ const { execSync: execSync2 } = await import('child_process');
8992
+ const branch = execSync2("git rev-parse --abbrev-ref HEAD", {
8925
8993
  encoding: "utf8",
8926
8994
  stdio: ["pipe", "pipe", "pipe"]
8927
8995
  }).trim();
@@ -10719,7 +10787,7 @@ var init_banner = __esm({
10719
10787
  init_dev_cockpit_context();
10720
10788
  init_dev_cockpit_format();
10721
10789
  init_startup_info();
10722
- CLI_VERSION2 = "0.3.0" ;
10790
+ CLI_VERSION2 = "0.3.3" ;
10723
10791
  BRAND_GLYPH = "\u25B6";
10724
10792
  BRAND_NAME = "RelyIO";
10725
10793
  LABEL_WIDTH = 9;
@@ -17222,21 +17290,12 @@ function confirm(message) {
17222
17290
  // src/api/auth.ts
17223
17291
  init_client();
17224
17292
  init_config();
17293
+ init_dashboard_url();
17225
17294
  init_dist();
17226
17295
  var isDebug3 = () => process.env.DEBUG === "true" || process.env.DEBUG === "1";
17227
17296
  var LOGIN_TIMEOUT_MS = 5 * 60 * 1e3;
17228
- async function login(email, password) {
17229
- const response = await client_default.post("/auth/login", { email, password });
17230
- await config_default.storeAuthToken(response.token);
17231
- return response;
17232
- }
17233
17297
  async function browserLogin() {
17234
- const dashboardUrl = config_default.getDashboardUrl();
17235
- if (!dashboardUrl) {
17236
- throw new Error(
17237
- "Dashboard URL is not configured. Please run the command with --dashboard-url option."
17238
- );
17239
- }
17298
+ const dashboardUrl = requireDashboardUrl(config_default.getDashboardUrl());
17240
17299
  const state = randomBytes(32).toString("base64url");
17241
17300
  const server = await startCallbackServer({ callbackPath: "/" });
17242
17301
  try {
@@ -17301,7 +17360,6 @@ async function validateApiKey(apiKey) {
17301
17360
  }
17302
17361
  }
17303
17362
  var auth_default = {
17304
- login,
17305
17363
  browserLogin,
17306
17364
  logout,
17307
17365
  getCurrentUser,
@@ -17974,6 +18032,7 @@ function initCommand(program2) {
17974
18032
  ).option("--dataset <name>", "With --template next: the dataset the site reads").option("--project <id>", "With --template next: the project id (default: the linked project)");
17975
18033
  }
17976
18034
  init_config();
18035
+ init_dashboard_url();
17977
18036
  async function handleLogin(options) {
17978
18037
  if (options.token) {
17979
18038
  console.log(heading("Login to RelyIO with API Key"));
@@ -18054,8 +18113,12 @@ async function handleLogin(options) {
18054
18113
  spin.fail("Authentication failed");
18055
18114
  const errorMessage = error2.message;
18056
18115
  if (errorMessage.includes("Dashboard URL")) {
18057
- console.log(info("Specify a dashboard URL with:"));
18058
- console.log(commandExample("relyio login --dashboard-url=https://dashboard.relyio.app"));
18116
+ console.log(
18117
+ info(
18118
+ `${DASHBOARD_URL_ENV} names the Dashboard; unset, it is ${DEFAULT_DASHBOARD_URL}:`
18119
+ )
18120
+ );
18121
+ console.log(commandExample(withDashboardUrl(DEFAULT_DASHBOARD_URL, "login")));
18059
18122
  }
18060
18123
  throw error2;
18061
18124
  }
@@ -19522,7 +19585,10 @@ function promoteCommand(program2) {
19522
19585
  "Promote your sandbox schema (and optionally its draft entries) into a real branch",
19523
19586
  handlePromote
19524
19587
  );
19525
- command.option("-b, --branch <target>", "Target branch to promote into (defaults to your git branch)").option("--with-entries", "Also copy the sandbox draft entries into the target").option("--schema-only", "Promote only the schema (skip entries)").option("-y, --yes", "Skip confirmation prompts (schema-only unless --with-entries)");
19588
+ command.option(
19589
+ "-b, --branch <target>",
19590
+ "Target branch to promote into (defaults to the sandbox's parent branch)"
19591
+ ).option("--with-entries", "Also copy the sandbox draft entries into the target").option("--schema-only", "Promote only the schema (skip entries)").option("-y, --yes", "Skip confirmation prompts (schema-only unless --with-entries)");
19526
19592
  command.addHelpText(
19527
19593
  "after",
19528
19594
  `
@@ -20440,7 +20506,7 @@ function sandboxCommands(program2) {
20440
20506
  }
20441
20507
 
20442
20508
  // src/commands/version.ts
20443
- var CLI_VERSION = "0.3.0" ;
20509
+ var CLI_VERSION = "0.3.3" ;
20444
20510
  async function handleVersion(_options) {
20445
20511
  console.log(heading("RelyIO CLI Version Information"));
20446
20512
  const versionInfo = [
@@ -22179,13 +22245,13 @@ async function checkAuthentication() {
22179
22245
  };
22180
22246
  }
22181
22247
  async function checkApiConnectivity() {
22182
- const apiUrl = config_default.getApiUrl();
22248
+ const manageUrl = config_default.getManageUrl();
22183
22249
  try {
22184
22250
  await auth_default.getCurrentUser();
22185
22251
  return {
22186
22252
  name: "API connectivity",
22187
22253
  status: "pass",
22188
- message: `Connected to ${apiUrl}`
22254
+ message: `Connected to ${manageUrl}`
22189
22255
  };
22190
22256
  } catch (error2) {
22191
22257
  const err = error2;
@@ -22193,7 +22259,7 @@ async function checkApiConnectivity() {
22193
22259
  return {
22194
22260
  name: "API connectivity",
22195
22261
  status: "fail",
22196
- message: `Cannot connect to ${apiUrl}`,
22262
+ message: `Cannot connect to ${manageUrl}`,
22197
22263
  suggestion: "Check if the RelyIO API server is running"
22198
22264
  };
22199
22265
  }
@@ -22209,7 +22275,7 @@ async function checkApiConnectivity() {
22209
22275
  name: "API connectivity",
22210
22276
  status: "fail",
22211
22277
  message: `Connection error: ${error2.message}`,
22212
- suggestion: `Verify API URL: ${apiUrl}`
22278
+ suggestion: `Verify API URL: ${manageUrl}`
22213
22279
  };
22214
22280
  }
22215
22281
  }
@@ -22347,6 +22413,7 @@ function doctorCommand(program2) {
22347
22413
 
22348
22414
  // src/commands/open.ts
22349
22415
  init_config();
22416
+ init_dashboard_url();
22350
22417
  init_manage();
22351
22418
  var THEME5 = {
22352
22419
  success: chalk12.green,
@@ -22354,41 +22421,28 @@ var THEME5 = {
22354
22421
  bold: chalk12.bold,
22355
22422
  link: chalk12.cyan.underline
22356
22423
  };
22424
+ function dashboard() {
22425
+ return requireDashboardUrl(config_default.getDashboardUrl()).replace(/\/+$/, "");
22426
+ }
22357
22427
  async function getDashboardPath(target) {
22358
- const dashboardUrl = config_default.getDashboardUrl();
22359
- const projectId = config_default.getProjectId();
22360
- const organizationId = config_default.getOrganizationId();
22361
22428
  switch (target) {
22362
22429
  case "dashboard": {
22363
- return dashboardUrl;
22364
- }
22365
- case "project": {
22366
- if (!projectId) {
22367
- throw new Error("No project linked. Run 'relyio link' first.");
22368
- }
22369
- return `${dashboardUrl}/projects/${projectId}`;
22430
+ return dashboard();
22370
22431
  }
22432
+ // The Dashboard has no page per branch, so a branch opens the Project it belongs to.
22433
+ case "project":
22371
22434
  case "branch": {
22372
- if (!projectId) {
22373
- throw new Error("No project linked. Run 'relyio link' first.");
22374
- }
22375
- const currentBranch = getCurrentGitBranch2();
22376
- if (currentBranch) {
22377
- try {
22378
- const branches = await manage_default.getProjectBranches(projectId, { name: currentBranch });
22379
- if (branches.length > 0) {
22380
- return `${dashboardUrl}/projects/${projectId}/branches/${branches[0].id}`;
22381
- }
22382
- } catch {
22383
- }
22384
- }
22385
- return `${dashboardUrl}/projects/${projectId}`;
22435
+ const dashboardUrl = dashboard();
22436
+ const { organizationId, projectId } = await linkedProject();
22437
+ return `${dashboardUrl}/o/${encodeURIComponent(organizationId)}/${encodeURIComponent(projectId)}`;
22386
22438
  }
22387
22439
  case "settings": {
22440
+ const dashboardUrl = dashboard();
22441
+ const organizationId = config_default.getOrganizationId();
22388
22442
  if (organizationId) {
22389
- return `${dashboardUrl}/organizations/${organizationId}/settings`;
22443
+ return `${dashboardUrl}/o/${encodeURIComponent(organizationId)}/settings`;
22390
22444
  }
22391
- return `${dashboardUrl}/settings`;
22445
+ return `${dashboardUrl}/account/settings`;
22392
22446
  }
22393
22447
  case "docs": {
22394
22448
  return "https://docs.relyio.com";
@@ -22397,16 +22451,19 @@ async function getDashboardPath(target) {
22397
22451
  return config_default.getApiUrl() + "/docs";
22398
22452
  }
22399
22453
  default: {
22400
- return dashboardUrl;
22454
+ return dashboard();
22401
22455
  }
22402
22456
  }
22403
22457
  }
22404
- function getCurrentGitBranch2() {
22405
- try {
22406
- return execSync("git rev-parse --abbrev-ref HEAD", { encoding: "utf8" }).trim();
22407
- } catch {
22408
- return null;
22458
+ async function linkedProject() {
22459
+ const projectId = config_default.getProjectId();
22460
+ if (!projectId) {
22461
+ throw new Error("No project linked. Run 'relyio link' first.");
22409
22462
  }
22463
+ const linked = config_default.getOrganizationId();
22464
+ if (linked) return { organizationId: linked, projectId };
22465
+ const project = await manage_default.getProject(projectId);
22466
+ return { organizationId: project.organizationId, projectId };
22410
22467
  }
22411
22468
  async function handleOpen(target, options) {
22412
22469
  const resolvedTarget = target || options.target || "dashboard";
@@ -22421,6 +22478,9 @@ async function handleOpen(target, options) {
22421
22478
  console.log();
22422
22479
  console.log(THEME5.success("\u2713") + ` Opening ${THEME5.bold(resolvedTarget)} in browser...`);
22423
22480
  console.log(THEME5.muted(` ${url}`));
22481
+ if (resolvedTarget === "branch") {
22482
+ console.log(THEME5.muted(" The Dashboard has no page per branch, so this is the project."));
22483
+ }
22424
22484
  await open(url);
22425
22485
  } catch (error2) {
22426
22486
  console.error(chalk12.red(`Failed to open: ${error2.message}`));
@@ -22441,7 +22501,7 @@ function openCommand(program2) {
22441
22501
  Targets:
22442
22502
  dashboard Open the main dashboard (default)
22443
22503
  project Open the current project
22444
- branch Open the current branch
22504
+ branch Open the current branch's project (the Dashboard has no page per branch)
22445
22505
  settings Open settings page
22446
22506
  docs Open documentation
22447
22507
  api Open API documentation
@@ -22452,14 +22512,10 @@ Examples:
22452
22512
  $ relyio open docs # Opens documentation
22453
22513
 
22454
22514
  Configuration:
22455
- The dashboard URL can be configured using:
22456
- relyio config set dashboardUrl <url>
22515
+ The Dashboard is ${DEFAULT_DASHBOARD_URL} unless ${DASHBOARD_URL_ENV} names another.
22457
22516
 
22458
22517
  For local development:
22459
- relyio config set dashboardUrl http://localhost:3920
22460
-
22461
- For production:
22462
- relyio config set dashboardUrl https://dashboard.relyio.com
22518
+ ${withDashboardUrl("http://localhost:3920", "open")}
22463
22519
  `
22464
22520
  );
22465
22521
  }
@@ -24603,7 +24659,7 @@ Examples:
24603
24659
  }
24604
24660
 
24605
24661
  // src/index.ts
24606
- var CLI_VERSION3 = "0.3.0" ;
24662
+ var CLI_VERSION3 = "0.3.3" ;
24607
24663
  var program = new Command();
24608
24664
  program.name("relyio").description("RelyIO CLI - Content Management, Simplified").version(CLI_VERSION3);
24609
24665
  registerGlobalOptions(program);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@relyio/cli",
3
- "version": "0.3.0",
3
+ "version": "0.3.3",
4
4
  "description": "RelyIO is coming soon — this package is not ready for general use yet.",
5
5
  "bugs": {
6
6
  "email": "team@relyio.com"
@@ -65,14 +65,14 @@
65
65
  "typescript": "npm:@typescript/typescript6@6.0.2",
66
66
  "typescript-eslint": "8.69.0",
67
67
  "vitest": "4.1.11",
68
- "@relyio/codegen-python": "0.1.0",
69
- "@relyio/codegen-core": "1.0.0",
70
68
  "@relyio/api-contract": "0.1.0",
69
+ "@relyio/codegen-typescript": "1.0.0",
70
+ "@relyio/codegen-core": "1.0.0",
71
+ "@relyio/codegen-python": "0.1.0",
71
72
  "@relyio/device-auth": "0.0.0",
72
73
  "@relyio/eslint-config": "0.0.0",
73
74
  "@relyio/schema": "0.0.1",
74
- "@relyio/sdk": "0.4.0",
75
- "@relyio/codegen-typescript": "1.0.0",
75
+ "@relyio/sdk": "0.6.0",
76
76
  "@relyio/tenancy": "0.1.0"
77
77
  },
78
78
  "publishConfig": {