@mutagent/cli 0.1.380 → 0.1.381
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 +51 -24
- package/dist/index.js +45 -18
- package/package.json +1 -1
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
17214
|
-
|
|
17215
|
-
|
|
17216
|
-
|
|
17217
|
-
|
|
17218
|
-
|
|
17219
|
-
|
|
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:
|
|
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
|
|
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
|
|
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=
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
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=
|
|
1694
|
+
//# debugId=6C0EFE359421B56964756E2164756E21
|
package/package.json
CHANGED