@mutagent/cli 0.1.380 → 0.1.382

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/bin/cli.js CHANGED
@@ -16680,12 +16680,14 @@ var init_config = __esm(() => {
16680
16680
  // src/lib/organization-scope.ts
16681
16681
  var exports_organization_scope = {};
16682
16682
  __export(exports_organization_scope, {
16683
+ unreachableServerError: () => unreachableServerError,
16683
16684
  tenancyHeaders: () => tenancyHeaders,
16684
16685
  tenancyFailure: () => tenancyFailure,
16685
16686
  setWorkspaceFlag: () => setWorkspaceFlag,
16686
16687
  setOrgAssertion: () => setOrgAssertion,
16687
16688
  resolveKeyTenancy: () => resolveKeyTenancy,
16688
16689
  otherOrganizationHint: () => otherOrganizationHint,
16690
+ orgMismatch: () => orgMismatch,
16689
16691
  noWorkspaceSelected: () => noWorkspaceSelected,
16690
16692
  matchesOrganization: () => matchesOrganization,
16691
16693
  looksLikeWorkspaceId: () => looksLikeWorkspaceId,
@@ -16694,6 +16696,7 @@ __export(exports_organization_scope, {
16694
16696
  fetchOrganizations: () => fetchOrganizations,
16695
16697
  fetchKeySelf: () => fetchKeySelf,
16696
16698
  envKeyHasNoSelection: () => envKeyHasNoSelection,
16699
+ deadKeyError: () => deadKeyError,
16697
16700
  configTenancyHeaders: () => configTenancyHeaders,
16698
16701
  TenancyError: () => TenancyError,
16699
16702
  TENANCY_DENIED: () => TENANCY_DENIED
@@ -16731,11 +16734,13 @@ function parseBody(body) {
16731
16734
  } catch {}
16732
16735
  return {};
16733
16736
  }
16737
+ function deadKeyError() {
16738
+ return new TenancyError("AUTH_EXPIRED", "Your CLI key expired or was revoked.", "Run: mutagent login", 2);
16739
+ }
16734
16740
  function tenancyFailure(status, body, ctx) {
16735
16741
  const parsed = parseBody(body);
16736
- if (status === 401) {
16737
- return new TenancyError("AUTH_EXPIRED", "Your CLI key expired or was revoked.", "Run: mutagent login", 2);
16738
- }
16742
+ if (status === 401)
16743
+ return deadKeyError();
16739
16744
  if (status === 403 && parsed.code === TENANCY_DENIED) {
16740
16745
  const shown = ctx.workspaceName ?? ctx.workspaceId ?? "workspace";
16741
16746
  if (ctx.workspaceOrigin === "selection") {
@@ -16763,9 +16768,16 @@ async function tenancyFetch(url, init) {
16763
16768
  try {
16764
16769
  return await fetch(url, init);
16765
16770
  } catch {
16766
- throw new MutagentError("REQUEST_FAILED", `Unable to connect to the Mutagent server at ${new URL(url).origin}.`, "Check your connection and the endpoint: mutagent config get endpoint");
16771
+ throw unreachableServerError(url);
16767
16772
  }
16768
16773
  }
16774
+ function unreachableServerError(url) {
16775
+ let origin = url;
16776
+ try {
16777
+ origin = new URL(url).origin;
16778
+ } catch {}
16779
+ return new MutagentError("REQUEST_FAILED", `Unable to connect to the Mutagent server at ${origin}.`, "Check your connection and the endpoint: mutagent config get endpoint");
16780
+ }
16769
16781
  async function fetchKeySelf(apiKey, endpoint, opts = {}) {
16770
16782
  const response = await tenancyFetch(`${endpoint}/api/api-keys/self`, {
16771
16783
  headers: { "x-api-key": apiKey, ...opts.headers }
@@ -16792,7 +16804,13 @@ async function fetchOrganizations(apiKey, endpoint) {
16792
16804
  function matchesOrganization(value2, org) {
16793
16805
  if (!org)
16794
16806
  return false;
16795
- return value2 === org.id || org.slug !== undefined && value2 === org.slug;
16807
+ if (value2 === org.id || org.slug !== undefined && value2 === org.slug)
16808
+ return true;
16809
+ return org.name !== undefined && value2.toLowerCase() === org.name.toLowerCase();
16810
+ }
16811
+ function orgMismatch(value2, org) {
16812
+ const shown = org.slug ? `${org.name} (${org.slug})` : org.name;
16813
+ return new TenancyError("ORG_MISMATCH", `Your key is for ${shown}.`, `Run: mutagent login --org ${value2}`);
16796
16814
  }
16797
16815
  function otherOrganizationHint(wanted, keyOrg, orgs) {
16798
16816
  const others = orgs.filter((o) => o.id !== keyOrg?.id);
@@ -16842,7 +16860,7 @@ function enforceOrgAssertion(org) {
16842
16860
  throw new TenancyError("ORG_UNKNOWN", "This key's organization is unknown, so --org cannot be checked.", "Run: mutagent workspaces current");
16843
16861
  }
16844
16862
  if (!matchesOrganization(orgAssertion, org)) {
16845
- throw new TenancyError("ORG_MISMATCH", `Your key is for ${org.name}.`, `Run: mutagent login --org ${orgAssertion}`);
16863
+ throw orgMismatch(orgAssertion, org);
16846
16864
  }
16847
16865
  }
16848
16866
  async function resolveKeyTenancy(apiKey, opts = {}) {
@@ -17165,6 +17183,9 @@ class SDKClientWrapper {
17165
17183
  });
17166
17184
  }
17167
17185
  handleError(error3) {
17186
+ if (error3 instanceof Error && SDK_TRANSPORT_ERRORS.has(error3.name)) {
17187
+ throw unreachableServerError(this.endpoint);
17188
+ }
17168
17189
  if (error3 && typeof error3 === "object") {
17169
17190
  const err = error3;
17170
17191
  if (err.statusCode) {
@@ -17192,7 +17213,7 @@ class SDKClientWrapper {
17192
17213
  }
17193
17214
  if (error3 instanceof TypeError && typeof error3.message === "string") {
17194
17215
  if (error3.message.includes("fetch") || error3.message.includes("network") || error3.message.includes("ECONNREFUSED")) {
17195
- throw new MutagentError("NETWORK_ERROR", "Unable to connect to the Mutagent server", "Check your internet connection and verify the server URL with: mutagent config list");
17216
+ throw unreachableServerError(this.endpoint);
17196
17217
  }
17197
17218
  }
17198
17219
  if (error3 instanceof Error) {
@@ -17210,15 +17231,20 @@ class SDKClientWrapper {
17210
17231
  } else if (optHeaders) {
17211
17232
  extraHeaders = optHeaders;
17212
17233
  }
17213
- const response = await fetch(`${this.endpoint}${path}`, {
17214
- ...options,
17215
- headers: {
17216
- "x-api-key": this.apiKey,
17217
- "Content-Type": "application/json",
17218
- ...this.tenancyHeaders(),
17219
- ...extraHeaders
17220
- }
17221
- });
17234
+ let response;
17235
+ try {
17236
+ response = await fetch(`${this.endpoint}${path}`, {
17237
+ ...options,
17238
+ headers: {
17239
+ "x-api-key": this.apiKey,
17240
+ "Content-Type": "application/json",
17241
+ ...this.tenancyHeaders(),
17242
+ ...extraHeaders
17243
+ }
17244
+ });
17245
+ } catch {
17246
+ throw unreachableServerError(this.endpoint);
17247
+ }
17222
17248
  if (!response.ok) {
17223
17249
  const error3 = await response.text();
17224
17250
  const tenancy = tenancyFailure(response.status, error3, this.tenancy);
@@ -17507,7 +17533,7 @@ async function validateApiKey(apiKey, endpoint) {
17507
17533
  return false;
17508
17534
  }
17509
17535
  }
17510
- var sdkClient = null;
17536
+ var SDK_TRANSPORT_ERRORS, sdkClient = null;
17511
17537
  var init_sdk_client = __esm(() => {
17512
17538
  init_errors();
17513
17539
  init_config();
@@ -17516,6 +17542,7 @@ var init_sdk_client = __esm(() => {
17516
17542
  init_known_secrets();
17517
17543
  init_sdk_mappers();
17518
17544
  init_organization_scope();
17545
+ SDK_TRANSPORT_ERRORS = new Set(["ConnectionError", "RequestTimeoutError", "RequestAbortedError", "UnexpectedClientError"]);
17519
17546
  });
17520
17547
 
17521
17548
  // src/lib/agent/sdk.ts
@@ -19263,7 +19290,7 @@ The CLI key from \`mutagent login\` works in every workspace you are a member of
19263
19290
  organization. Workspace precedence: --workspace, then MUTAGENT_WORKSPACE_ID, then the
19264
19291
  workspace chosen with \`workspaces use\`.
19265
19292
  To work in another organization: mutagent login --org <slug>
19266
- Create or change workspaces in the dashboard: https://app.mutagent.io
19293
+ Create or change workspaces in the dashboard: ${getAppBaseUrl()}
19267
19294
  `);
19268
19295
  workspaces.command("list").description("List your workspaces in the key's organization (* = selected)").option("-l, --limit <n>", "Limit results", "50").option("-o, --offset <n>", "Offset for pagination").addHelpText("after", `
19269
19296
  Examples:
@@ -19507,7 +19534,7 @@ ${chalk7.dim("Another organization: sign in for it with mutagent login --org <id
19507
19534
  throw new MutagentError("ORG_UNKNOWN", "This key's organization is unknown.", "Run: mutagent workspaces current");
19508
19535
  }
19509
19536
  if (!matchesOrganization(value2, organization)) {
19510
- throw new TenancyError("ORG_MISMATCH", `Your key is for ${organization.name}.`, `Run: mutagent login --org ${value2}`);
19537
+ throw orgMismatch(value2, organization);
19511
19538
  }
19512
19539
  if (isJson) {
19513
19540
  output.output({ success: true, organization });
@@ -24808,6 +24835,7 @@ init_errors();
24808
24835
  init_secure_file();
24809
24836
  init_errors();
24810
24837
  init_known_secrets();
24838
+ init_organization_scope();
24811
24839
  import { existsSync as existsSync12, readFileSync as readFileSync12, mkdirSync as mkdirSync5, rmSync as rmSync2 } from "fs";
24812
24840
  import { homedir as homedir6 } from "os";
24813
24841
  import { join as join20, dirname as dirname6 } from "path";
@@ -24888,9 +24916,8 @@ async function exchangeToken(input2, deps = {}) {
24888
24916
  const detail = error3 instanceof Error ? error3.message : String(error3);
24889
24917
  throw new MutagentError("SANDBOX_UNREACHABLE", `Could not reach the MutagenT API at ${input2.endpoint}: ${detail}`, "Check your connection, then verify the endpoint with: mutagent config list", 5);
24890
24918
  }
24891
- if (response.status === 401) {
24892
- throw new AuthenticationError("Your MutagenT API key was rejected. It may have been revoked or expired.", { suggestions: ["mutagent auth login --browser", "mutagent auth status"] });
24893
- }
24919
+ if (response.status === 401)
24920
+ throw deadKeyError();
24894
24921
  if (response.status === 403) {
24895
24922
  const detail = scrubKnown(messageFrom(await response.text().catch(() => "")));
24896
24923
  throw new MutagentError("SANDBOX_WORKSPACE_FORBIDDEN", detail !== "" ? detail : `Your API key is valid, but this account cannot use workspace "${input2.workspaceId}".`, `Pick a workspace you belong to: mutagent workspaces list, then mutagent workspaces use <name>`, 3);
@@ -29403,7 +29430,7 @@ var program = new Command18;
29403
29430
  program.name("mutagent").description(`Mutagent CLI - command-line client for the Mutagent platform
29404
29431
 
29405
29432
  Documentation: https://docs.mutagent.io/cli
29406
- Dashboard: https://app.mutagent.io`).option("--json", "Output results as JSON (for AI agents)").option("--api-key <key>", "Mutagent API key").option("--endpoint <url>", "Mutagent server endpoint").option("--workspace <name|id>", "Workspace for this command only (beats MUTAGENT_WORKSPACE_ID and the selection)").option("--org <id|slug>", "Check that the key belongs to this organization; a mismatch exits 1 and sends nothing (with login: the organization to sign in to)").option("--non-interactive", "Disable interactive prompts (for CI/AI agents)").configureHelp({
29433
+ Dashboard: https://app.mutagent.io`).option("--json", "Output results as JSON (for AI agents)").option("--api-key <key>", "Mutagent API key").option("--endpoint <url>", "Mutagent server endpoint").option("--workspace <name|id>", "Workspace for this command only (beats MUTAGENT_WORKSPACE_ID and the selection)").option("--org <id|slug>", "Check that the key belongs to this organization (its id, slug or name); a mismatch exits 1 and sends nothing (with login: the organization to sign in to)").option("--non-interactive", "Disable interactive prompts (for CI/AI agents)").configureHelp({
29407
29434
  sortSubcommands: true,
29408
29435
  showGlobalOptions: true
29409
29436
  });
@@ -29546,4 +29573,4 @@ if (isAgentInvocation(rawArgs)) {
29546
29573
  program.parse(argvForCommander, { from: "user" });
29547
29574
  }
29548
29575
 
29549
- //# debugId=005A5989779CDE4E64756E2164756E21
29576
+ //# debugId=22EA0CB4BCE602F064756E2164756E21
package/dist/index.js CHANGED
@@ -605,12 +605,14 @@ var init_errors = __esm(() => {
605
605
  // src/lib/organization-scope.ts
606
606
  var exports_organization_scope = {};
607
607
  __export(exports_organization_scope, {
608
+ unreachableServerError: () => unreachableServerError,
608
609
  tenancyHeaders: () => tenancyHeaders,
609
610
  tenancyFailure: () => tenancyFailure,
610
611
  setWorkspaceFlag: () => setWorkspaceFlag,
611
612
  setOrgAssertion: () => setOrgAssertion,
612
613
  resolveKeyTenancy: () => resolveKeyTenancy,
613
614
  otherOrganizationHint: () => otherOrganizationHint,
615
+ orgMismatch: () => orgMismatch,
614
616
  noWorkspaceSelected: () => noWorkspaceSelected,
615
617
  matchesOrganization: () => matchesOrganization,
616
618
  looksLikeWorkspaceId: () => looksLikeWorkspaceId,
@@ -619,6 +621,7 @@ __export(exports_organization_scope, {
619
621
  fetchOrganizations: () => fetchOrganizations,
620
622
  fetchKeySelf: () => fetchKeySelf,
621
623
  envKeyHasNoSelection: () => envKeyHasNoSelection,
624
+ deadKeyError: () => deadKeyError,
622
625
  configTenancyHeaders: () => configTenancyHeaders,
623
626
  TenancyError: () => TenancyError,
624
627
  TENANCY_DENIED: () => TENANCY_DENIED
@@ -656,11 +659,13 @@ function parseBody(body) {
656
659
  } catch {}
657
660
  return {};
658
661
  }
662
+ function deadKeyError() {
663
+ return new TenancyError("AUTH_EXPIRED", "Your CLI key expired or was revoked.", "Run: mutagent login", 2);
664
+ }
659
665
  function tenancyFailure(status, body, ctx) {
660
666
  const parsed = parseBody(body);
661
- if (status === 401) {
662
- return new TenancyError("AUTH_EXPIRED", "Your CLI key expired or was revoked.", "Run: mutagent login", 2);
663
- }
667
+ if (status === 401)
668
+ return deadKeyError();
664
669
  if (status === 403 && parsed.code === TENANCY_DENIED) {
665
670
  const shown = ctx.workspaceName ?? ctx.workspaceId ?? "workspace";
666
671
  if (ctx.workspaceOrigin === "selection") {
@@ -688,9 +693,16 @@ async function tenancyFetch(url, init) {
688
693
  try {
689
694
  return await fetch(url, init);
690
695
  } catch {
691
- throw new MutagentError("REQUEST_FAILED", `Unable to connect to the Mutagent server at ${new URL(url).origin}.`, "Check your connection and the endpoint: mutagent config get endpoint");
696
+ throw unreachableServerError(url);
692
697
  }
693
698
  }
699
+ function unreachableServerError(url) {
700
+ let origin = url;
701
+ try {
702
+ origin = new URL(url).origin;
703
+ } catch {}
704
+ return new MutagentError("REQUEST_FAILED", `Unable to connect to the Mutagent server at ${origin}.`, "Check your connection and the endpoint: mutagent config get endpoint");
705
+ }
694
706
  async function fetchKeySelf(apiKey, endpoint, opts = {}) {
695
707
  const response = await tenancyFetch(`${endpoint}/api/api-keys/self`, {
696
708
  headers: { "x-api-key": apiKey, ...opts.headers }
@@ -717,7 +729,13 @@ async function fetchOrganizations(apiKey, endpoint) {
717
729
  function matchesOrganization(value, org) {
718
730
  if (!org)
719
731
  return false;
720
- return value === org.id || org.slug !== undefined && value === org.slug;
732
+ if (value === org.id || org.slug !== undefined && value === org.slug)
733
+ return true;
734
+ return org.name !== undefined && value.toLowerCase() === org.name.toLowerCase();
735
+ }
736
+ function orgMismatch(value, org) {
737
+ const shown = org.slug ? `${org.name} (${org.slug})` : org.name;
738
+ return new TenancyError("ORG_MISMATCH", `Your key is for ${shown}.`, `Run: mutagent login --org ${value}`);
721
739
  }
722
740
  function otherOrganizationHint(wanted, keyOrg, orgs) {
723
741
  const others = orgs.filter((o) => o.id !== keyOrg?.id);
@@ -767,7 +785,7 @@ function enforceOrgAssertion(org) {
767
785
  throw new TenancyError("ORG_UNKNOWN", "This key's organization is unknown, so --org cannot be checked.", "Run: mutagent workspaces current");
768
786
  }
769
787
  if (!matchesOrganization(orgAssertion, org)) {
770
- throw new TenancyError("ORG_MISMATCH", `Your key is for ${org.name}.`, `Run: mutagent login --org ${orgAssertion}`);
788
+ throw orgMismatch(orgAssertion, org);
771
789
  }
772
790
  }
773
791
  async function resolveKeyTenancy(apiKey, opts = {}) {
@@ -1090,6 +1108,9 @@ class SDKClientWrapper {
1090
1108
  });
1091
1109
  }
1092
1110
  handleError(error) {
1111
+ if (error instanceof Error && SDK_TRANSPORT_ERRORS.has(error.name)) {
1112
+ throw unreachableServerError(this.endpoint);
1113
+ }
1093
1114
  if (error && typeof error === "object") {
1094
1115
  const err = error;
1095
1116
  if (err.statusCode) {
@@ -1117,7 +1138,7 @@ class SDKClientWrapper {
1117
1138
  }
1118
1139
  if (error instanceof TypeError && typeof error.message === "string") {
1119
1140
  if (error.message.includes("fetch") || error.message.includes("network") || error.message.includes("ECONNREFUSED")) {
1120
- throw new MutagentError("NETWORK_ERROR", "Unable to connect to the Mutagent server", "Check your internet connection and verify the server URL with: mutagent config list");
1141
+ throw unreachableServerError(this.endpoint);
1121
1142
  }
1122
1143
  }
1123
1144
  if (error instanceof Error) {
@@ -1135,15 +1156,20 @@ class SDKClientWrapper {
1135
1156
  } else if (optHeaders) {
1136
1157
  extraHeaders = optHeaders;
1137
1158
  }
1138
- const response = await fetch(`${this.endpoint}${path}`, {
1139
- ...options,
1140
- headers: {
1141
- "x-api-key": this.apiKey,
1142
- "Content-Type": "application/json",
1143
- ...this.tenancyHeaders(),
1144
- ...extraHeaders
1145
- }
1146
- });
1159
+ let response;
1160
+ try {
1161
+ response = await fetch(`${this.endpoint}${path}`, {
1162
+ ...options,
1163
+ headers: {
1164
+ "x-api-key": this.apiKey,
1165
+ "Content-Type": "application/json",
1166
+ ...this.tenancyHeaders(),
1167
+ ...extraHeaders
1168
+ }
1169
+ });
1170
+ } catch {
1171
+ throw unreachableServerError(this.endpoint);
1172
+ }
1147
1173
  if (!response.ok) {
1148
1174
  const error = await response.text();
1149
1175
  const tenancy = tenancyFailure(response.status, error, this.tenancy);
@@ -1432,7 +1458,7 @@ async function validateApiKey(apiKey, endpoint) {
1432
1458
  return false;
1433
1459
  }
1434
1460
  }
1435
- var sdkClient = null;
1461
+ var SDK_TRANSPORT_ERRORS, sdkClient = null;
1436
1462
  var init_sdk_client = __esm(() => {
1437
1463
  init_errors();
1438
1464
  init_config();
@@ -1441,6 +1467,7 @@ var init_sdk_client = __esm(() => {
1441
1467
  init_known_secrets();
1442
1468
  init_sdk_mappers();
1443
1469
  init_organization_scope();
1470
+ SDK_TRANSPORT_ERRORS = new Set(["ConnectionError", "RequestTimeoutError", "RequestAbortedError", "UnexpectedClientError"]);
1444
1471
  });
1445
1472
 
1446
1473
  // src/index.ts
@@ -1664,4 +1691,4 @@ export {
1664
1691
  ApiError
1665
1692
  };
1666
1693
 
1667
- //# debugId=E203EEB55C5F59D464756E2164756E21
1694
+ //# debugId=6C0EFE359421B56964756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutagent/cli",
3
- "version": "0.1.380",
3
+ "version": "0.1.382",
4
4
  "description": "Bun-native CLI for the MutagenT AI platform - auth, provider config, and lifecycle-tool installer for AI-native workflows",
5
5
  "type": "module",
6
6
  "bin": {
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@inquirer/prompts": "^8.7.2",
45
- "@mutagent/sdk": "0.6.14",
45
+ "@mutagent/sdk": "0.6.15",
46
46
  "chalk": "^5.3.0",
47
47
  "commander": "^12.1.0",
48
48
  "cosmiconfig": "^9.0.0",