@getmagical/cli 0.1.11 → 0.1.13

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
@@ -6590,7 +6590,7 @@ import { Help } from "commander";
6590
6590
  var EMPTY_VALUE = "-";
6591
6591
  var TABLE_GAP = " ";
6592
6592
  function applyStyle(value, style, enabled = true) {
6593
- if (!enabled) {
6593
+ if (!enabled || typeof styleText !== "function") {
6594
6594
  return value;
6595
6595
  }
6596
6596
  return styleText(style, value);
@@ -6887,1871 +6887,2072 @@ function getErrorMessage(error) {
6887
6887
  // src/program.ts
6888
6888
  import path6 from "path";
6889
6889
 
6890
- // ../mcp-registry/src/operation-specs.ts
6890
+ // ../common/dist/src/stdlib/json.util.js
6891
+ var import_ts_essentials = __toESM(require_dist(), 1);
6892
+
6893
+ // ../common/dist/src/stdlib/result.util.js
6891
6894
  import { z } from "zod";
6892
6895
 
6893
- // ../mcp-registry/src/operation-spec.ts
6894
- function stripLeadingGraphqlComments(document) {
6895
- return document.replace(/^(?:\s*#.*\n)+/u, "").trimStart();
6896
+ // ../common/dist/src/stdlib/error-user-facing.js
6897
+ var USER_FACING_STATUS_MESSAGES = /* @__PURE__ */ new Map([
6898
+ [400, "Bad Request"],
6899
+ [401, "Unauthorized"],
6900
+ [403, "Forbidden"],
6901
+ [404, "Not Found"],
6902
+ [500, "Internal Server Error"],
6903
+ [503, "Service Unavailable"]
6904
+ ]);
6905
+ var USER_FACING_DEFAULT_ACTIONS = /* @__PURE__ */ new Map([
6906
+ [400, "Review the request payload and retry."],
6907
+ [401, "Authenticate and retry the request."],
6908
+ [403, "Verify your permissions and retry the request."],
6909
+ [404, "Verify the requested resource exists and retry."],
6910
+ [
6911
+ 500,
6912
+ "Retry the request. If this keeps happening, contact support and share the correlation ID."
6913
+ ],
6914
+ [
6915
+ 503,
6916
+ "Retry the request after a brief delay. If this keeps happening, contact support and share the correlation ID."
6917
+ ]
6918
+ ]);
6919
+ var USER_FACING_FALLBACK_CODES = /* @__PURE__ */ new Map([
6920
+ [400, "BAD_REQUEST"],
6921
+ [401, "UNAUTHORIZED"],
6922
+ [403, "FORBIDDEN"],
6923
+ [404, "NOT_FOUND"],
6924
+ [500, "INTERNAL_SERVER_ERROR"],
6925
+ [503, "SERVICE_UNAVAILABLE"]
6926
+ ]);
6927
+ function isCustomerUsageError(appError) {
6928
+ return appError.categories.includes("customer_usage");
6896
6929
  }
6897
- function assertDocumentMatchesOperation({
6898
- document,
6899
- kind,
6900
- operationName
6901
- }) {
6902
- const normalizedDocument = stripLeadingGraphqlComments(document);
6903
- const match = /^(?<actualKind>query|mutation)\s+(?<actualOperationName>[_A-Za-z][_0-9A-Za-z]*)/u.exec(
6904
- normalizedDocument
6905
- );
6906
- const actualKind = match?.groups?.["actualKind"];
6907
- const actualOperationName = match?.groups?.["actualOperationName"];
6908
- if (!actualKind || !actualOperationName) {
6909
- throw new Error(
6910
- `Operation "${operationName}" is missing a top-level GraphQL ${kind} definition.`
6911
- );
6930
+ function getStatusCodeFromAppErrorCode(code) {
6931
+ if (typeof code !== "number" || !Number.isInteger(code)) {
6932
+ return void 0;
6912
6933
  }
6913
- if (actualKind !== kind || actualOperationName !== operationName) {
6914
- throw new Error(
6915
- `Operation "${operationName}" does not match its GraphQL document (${actualKind} ${actualOperationName}).`
6916
- );
6934
+ if (code >= 400 && code <= 599) {
6935
+ return code;
6917
6936
  }
6937
+ return void 0;
6918
6938
  }
6919
- function createOperationSpec(spec) {
6920
- assertDocumentMatchesOperation(spec);
6921
- return spec;
6939
+ function getStatusFamilyFallbackCode(statusCode) {
6940
+ if (statusCode >= 400 && statusCode <= 499) {
6941
+ return 400;
6942
+ }
6943
+ return 500;
6922
6944
  }
6923
-
6924
- // ../mcp-registry/src/operation-specs.ts
6925
- function stringOption({
6926
- description,
6927
- flagName,
6928
- inputKey,
6929
- required = false
6930
- }) {
6931
- return {
6932
- description,
6933
- flagName,
6934
- inputKey,
6935
- required,
6936
- valueType: "string"
6937
- };
6945
+ function getStatusMessage(statusCode) {
6946
+ const directMessage = USER_FACING_STATUS_MESSAGES.get(statusCode);
6947
+ if (directMessage !== void 0) {
6948
+ return directMessage;
6949
+ }
6950
+ return getStatusFamilyFallbackCode(statusCode) === 400 ? "Bad Request" : "Internal Server Error";
6938
6951
  }
6939
- function numberOption({
6940
- description,
6941
- flagName,
6942
- inputKey,
6943
- required = false
6944
- }) {
6945
- return {
6946
- description,
6947
- flagName,
6948
- inputKey,
6949
- required,
6950
- valueType: "number"
6951
- };
6952
+ function getDefaultSuggestedAction(statusCode) {
6953
+ const directAction = USER_FACING_DEFAULT_ACTIONS.get(statusCode);
6954
+ if (directAction !== void 0) {
6955
+ return directAction;
6956
+ }
6957
+ return getStatusFamilyFallbackCode(statusCode) === 400 ? "Review the request payload and retry." : "Retry the request. If this keeps happening, contact support and share the correlation ID.";
6952
6958
  }
6953
- function booleanOption({
6954
- description,
6955
- flagName,
6956
- inputKey
6957
- }) {
6958
- return {
6959
- description,
6960
- flagName,
6961
- inputKey,
6962
- valueType: "boolean"
6963
- };
6959
+ function getFallbackErrorCode(statusCode) {
6960
+ const directCode = USER_FACING_FALLBACK_CODES.get(statusCode);
6961
+ if (directCode !== void 0) {
6962
+ return directCode;
6963
+ }
6964
+ return getStatusFamilyFallbackCode(statusCode) === 400 ? "BAD_REQUEST" : "INTERNAL_SERVER_ERROR";
6964
6965
  }
6965
- function stringArrayOption({
6966
- description,
6967
- flagName,
6968
- inputKey,
6969
- required = false
6970
- }) {
6971
- return {
6972
- description,
6973
- flagName,
6974
- inputKey,
6975
- required,
6976
- valueHint: "comma-separated",
6977
- valueType: "string-array"
6978
- };
6966
+ function shouldExposeMessage({ appError, statusCode }) {
6967
+ if (statusCode >= 500) {
6968
+ return false;
6969
+ }
6970
+ return isCustomerUsageError(appError);
6979
6971
  }
6980
- function jsonOption({
6981
- description,
6982
- flagName,
6983
- inputKey,
6984
- required = false
6985
- }) {
6986
- return {
6987
- description,
6988
- flagName,
6989
- inputKey,
6990
- required,
6991
- valueHint: "JSON",
6992
- valueType: "json"
6993
- };
6972
+ function resolveApiMessage({ appError, statusCode }) {
6973
+ if (!shouldExposeMessage({ appError, statusCode })) {
6974
+ return getStatusMessage(statusCode);
6975
+ }
6976
+ const trimmedMessage = appError.message.trim();
6977
+ if (trimmedMessage.length > 0) {
6978
+ return trimmedMessage;
6979
+ }
6980
+ return getStatusMessage(statusCode);
6994
6981
  }
6995
- var jsonObjectSchema = z.record(z.string(), z.unknown());
6996
- var agentBrowserProviderOptionsSelection = ` browserbase {
6997
- advancedStealth
6998
- contextId
6999
- extensionId
7000
- instanceSize
7001
- blockAds
7002
- solveCaptchas
7003
- viewport {
7004
- width
7005
- height
7006
- }
7007
- }
7008
- agentCore {
7009
- viewport {
7010
- width
7011
- height
7012
- }
7013
- enableWebBotAuth
7014
- }
7015
- local {
7016
- viewport {
7017
- width
7018
- height
7019
- }
7020
- }
7021
- hyperbrowser {
7022
- viewport {
7023
- width
7024
- height
7025
- }
7026
- }
7027
- steel {
7028
- extensionIds
7029
- region
7030
- solveCaptcha
7031
- viewport {
7032
- width
7033
- height
7034
- }
7035
- }`;
7036
- var agentEnvironmentOptionsSelection = ` environmentOptions {
7037
- __typename
7038
- ... on AgentConfig_environmentOptions_Browser {
7039
- environment
7040
- maxMediaToIncludeInMemory
7041
- saveAuthCookiesAfterRun
7042
- startingUrl
7043
- browserProvider
7044
- browserProviderOptions {
7045
- ${agentBrowserProviderOptionsSelection}
7046
- }
7047
- }
7048
- ... on AgentConfig_environmentOptions_Browsercoordinates {
7049
- environment
7050
- maxMediaToIncludeInMemory
7051
- saveAuthCookiesAfterRun
7052
- startingUrl
7053
- browserProvider
7054
- browserProviderOptions {
7055
- ${agentBrowserProviderOptionsSelection}
7056
- }
7057
- }
7058
- ... on AgentConfig_environmentOptions_Desktop {
7059
- environment
7060
- browserProvider
7061
- browserProviderOptions {
7062
- ${agentBrowserProviderOptionsSelection}
7063
- }
7064
- maxMediaToIncludeInMemory
7065
- startingUrl
7066
- useCopyPasteForTyping
7067
- }
7068
- ... on AgentConfig_environmentOptions_Desktopapp {
7069
- environment
7070
- maxMediaToIncludeInMemory
7071
- }
7072
- ... on AgentConfig_environmentOptions_Minimal {
7073
- environment
7074
- }
7075
- }`;
7076
- var agentLimitationsSelection = ` limitations {
7077
- maxDurationSeconds
7078
- maxToolCalls
7079
- allowedUrlRegexes
7080
- }`;
7081
- var operationSpecs = [
7082
- createOperationSpec({
7083
- operationName: "GetAgents",
7084
- kind: "query",
7085
- inputSchema: z.object({
7086
- ids: z.array(z.string().min(1)).min(1)
7087
- }),
7088
- cli: {
7089
- name: "get-agents",
7090
- path: ["agents", "get"],
7091
- description: "Fetch one or more agents with config and schema fields.",
7092
- resultKey: "agents",
7093
- options: [
7094
- stringArrayOption({
7095
- inputKey: "ids",
7096
- flagName: "ids",
7097
- description: "Agent IDs.",
7098
- required: true
7099
- })
7100
- ]
7101
- },
7102
- mcp: { fileName: "agents.graphql" },
7103
- document: `# Query to fetch multiple agents with all fields
7104
- # Includes nested environment and limitation config fields
7105
- query GetAgents($ids: [ID!]!) {
7106
- agents(ids: $ids) {
7107
- id
7108
- name
7109
- description
7110
- instructions
7111
- organizationId
7112
- createdAt
7113
- updatedAt
7114
- sourceAgentId
7115
- inputSchema
7116
- outputSchema
7117
- config {
7118
- type
7119
- language
7120
- model
7121
- tools
7122
- maxSessionMessages
7123
- ${agentEnvironmentOptionsSelection}
7124
- ${agentLimitationsSelection}
7125
- commonParametersSchema
7126
- taskQueue
7127
- waitUponQueueing
7128
- queueableAgentIds
7129
- additionalSystemPrompt
7130
- ignoreUnstableSessionState
7131
- }
7132
- childAgentIds
6982
+ function resolveApiErrorCode({ appError, statusCode }) {
6983
+ if (!shouldExposeMessage({ appError, statusCode })) {
6984
+ return getFallbackErrorCode(statusCode);
7133
6985
  }
7134
- }`
7135
- }),
7136
- createOperationSpec({
7137
- operationName: "GetAgentRun",
7138
- kind: "query",
7139
- inputSchema: z.object({
7140
- id: z.string().min(1)
7141
- }),
7142
- cli: {
7143
- name: "get-agent-run",
7144
- path: ["agent-runs", "get"],
7145
- description: "Fetch a single agent run.",
7146
- resultKey: "agentRun",
7147
- options: [
7148
- stringOption({
7149
- inputKey: "id",
7150
- flagName: "id",
7151
- description: "Agent run ID.",
7152
- required: true
7153
- })
7154
- ]
7155
- },
7156
- mcp: { fileName: "agentRun.graphql" },
7157
- document: `# Query a single agent run
7158
- query GetAgentRun($id: ID!) {
7159
- agentRun(id: $id) {
7160
- id
7161
- agentVersionId
7162
- agentName
7163
- status
7164
- statusDetail
7165
- isChildAgent
7166
- input
7167
- startedAt
7168
- finishedAt
7169
- parentAgentRunId
6986
+ return normalizeUserFacingErrorCode({
6987
+ type: appError.type,
6988
+ fallbackCode: getFallbackErrorCode(statusCode)
6989
+ });
6990
+ }
6991
+ function resolveSuggestedAction({ appError, statusCode }) {
6992
+ const trimmedSuggestedAction = appError.suggestedAction?.trim();
6993
+ if (shouldExposeMessage({ appError, statusCode }) && trimmedSuggestedAction) {
6994
+ return trimmedSuggestedAction;
7170
6995
  }
7171
- }`
7172
- }),
7173
- createOperationSpec({
7174
- operationName: "GetAutomationAgents",
7175
- kind: "query",
7176
- inputSchema: z.object({
7177
- ids: z.array(z.string().min(1)).min(1)
7178
- }),
7179
- cli: {
7180
- name: "get-automation-agents",
7181
- path: ["automations", "agents"],
7182
- description: "Fetch the agents attached to one or more automations.",
7183
- resultKey: "automationAgents",
7184
- options: [
7185
- stringArrayOption({
7186
- inputKey: "ids",
7187
- flagName: "ids",
7188
- description: "Automation IDs.",
7189
- required: true
7190
- })
7191
- ]
7192
- },
7193
- mcp: { fileName: "automationAgents.graphql" },
7194
- document: `# Query automation agent relationships with flat agent fields only
7195
- # Excludes nested agent config and schemas for MCP tool simplicity
7196
- query GetAutomationAgents($ids: [ID!]!) {
7197
- automationAgents(ids: $ids) {
7198
- automationId
7199
- agentId
7200
- isTrigger
7201
- agent {
7202
- id
7203
- name
7204
- description
7205
- instructions
7206
- organizationId
7207
- createdAt
7208
- updatedAt
7209
- sourceAgentId
7210
- childAgentIds
7211
- }
6996
+ return getDefaultSuggestedAction(statusCode);
6997
+ }
6998
+ function getZodIssuesFromCause(cause, maxDepth = 10) {
6999
+ if (maxDepth < 0 || typeof cause !== "object" || cause === null) {
7000
+ return void 0;
7212
7001
  }
7213
- }`
7214
- }),
7215
- createOperationSpec({
7216
- operationName: "GetAutomationRun",
7217
- kind: "query",
7218
- inputSchema: z.object({
7219
- id: z.string().min(1)
7220
- }),
7221
- cli: {
7222
- name: "get-automation-run",
7223
- path: ["automation-runs", "get"],
7224
- description: "Fetch a single automation run.",
7225
- resultKey: "automationRun",
7226
- options: [
7227
- stringOption({
7228
- inputKey: "id",
7229
- flagName: "id",
7230
- description: "Automation run ID.",
7231
- required: true
7232
- })
7233
- ]
7234
- },
7235
- mcp: { fileName: "automationRun.graphql" },
7236
- document: `# Query a full automation run details payload
7237
- query GetAutomationRun($id: ID!) {
7238
- automationRun(id: $id) {
7239
- id
7240
- automationId
7241
- parentAutomationRunId
7242
- status
7243
- statusDetail
7244
- summary
7245
- invocationType
7246
- input
7247
- additionalPrompt
7248
- debugUrl
7249
- createdAt
7250
- startedAt
7251
- pausedAt
7252
- finishedAt
7002
+ if ("issues" in cause && Array.isArray(cause.issues)) {
7003
+ return cause.issues;
7253
7004
  }
7254
- }`
7255
- }),
7256
- createOperationSpec({
7257
- operationName: "GetAutomationRunAgentRuns",
7258
- kind: "query",
7259
- inputSchema: z.object({
7260
- automationRunId: z.string().min(1)
7261
- }),
7262
- cli: {
7263
- name: "get-automation-run-agent-runs",
7264
- path: ["automation-runs", "agent-runs"],
7265
- description: "Fetch ordered agent runs for an automation run.",
7266
- resultKey: "automationRunAgentRuns",
7267
- options: [
7268
- stringOption({
7269
- inputKey: "automationRunId",
7270
- flagName: "automation-run-id",
7271
- description: "Automation run ID.",
7272
- required: true
7273
- })
7274
- ]
7275
- },
7276
- mcp: { fileName: "automationRunAgentRuns.graphql" },
7277
- document: `# Query ordered agent runs for an automation run
7278
- query GetAutomationRunAgentRuns($automationRunId: ID!) {
7279
- automationRunAgentRuns(automationRunId: $automationRunId) {
7280
- id
7281
- agentVersionId
7282
- agentName
7283
- status
7284
- statusDetail
7285
- isChildAgent
7286
- input
7287
- startedAt
7288
- finishedAt
7289
- parentAgentRunId
7005
+ if ("cause" in cause) {
7006
+ return getZodIssuesFromCause(cause.cause, maxDepth - 1);
7290
7007
  }
7291
- }`
7292
- }),
7293
- createOperationSpec({
7294
- operationName: "GetAutomationRunIterations",
7295
- kind: "query",
7296
- inputSchema: z.object({
7297
- automationRunId: z.string().min(1),
7298
- agentRunId: z.string().min(1).optional(),
7299
- limit: z.number().int().positive().optional(),
7300
- reverse: z.boolean().optional()
7301
- }),
7302
- cli: {
7303
- name: "get-automation-run-iterations",
7304
- path: ["automation-runs", "iterations"],
7305
- description: "Fetch ordered iterations for an automation run.",
7306
- resultKey: "automationRunIterations",
7307
- options: [
7308
- stringOption({
7309
- inputKey: "automationRunId",
7310
- flagName: "automation-run-id",
7311
- description: "Automation run ID.",
7312
- required: true
7313
- }),
7314
- stringOption({
7315
- inputKey: "agentRunId",
7316
- flagName: "agent-run-id",
7317
- description: "Optional agent run ID to filter by."
7318
- }),
7319
- numberOption({
7320
- inputKey: "limit",
7321
- flagName: "limit",
7322
- description: "Maximum number of iterations to return."
7323
- }),
7324
- booleanOption({
7325
- inputKey: "reverse",
7326
- flagName: "reverse",
7327
- description: "Return newest iterations first."
7328
- })
7329
- ]
7330
- },
7331
- mcp: { fileName: "automationRunIterations.graphql" },
7332
- document: `# Query iterations for an automation run with optional filtering by agent run
7333
- query GetAutomationRunIterations(
7334
- $automationRunId: ID!
7335
- $agentRunId: ID
7336
- $limit: Int
7337
- $reverse: Boolean
7338
- ) {
7339
- automationRunIterations(
7340
- automationRunId: $automationRunId
7341
- agentRunId: $agentRunId
7342
- limit: $limit
7343
- reverse: $reverse
7344
- ) {
7345
- id
7346
- sequence
7347
- agentRunId
7348
- metadata
7349
- startedAt
7350
- finishedAt
7351
- totalDurationMs
7352
- llmResponseDurationMs
7353
- withMarksScreenshotUrl
7354
- withMarksMimeType
7355
- memories {
7356
- id
7357
- type
7358
- value
7359
- sequence
7360
- screenshotUrl
7361
- screenshotMimeType
7008
+ return void 0;
7009
+ }
7010
+ function toUserFacingDetailsValue(value, depth) {
7011
+ if (depth < 0) {
7012
+ return void 0;
7013
+ }
7014
+ if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
7015
+ return value;
7016
+ }
7017
+ if (Array.isArray(value)) {
7018
+ const serializedValues = value.map((item) => toUserFacingDetailsValue(item, depth - 1)).filter((item) => item !== void 0);
7019
+ return serializedValues;
7020
+ }
7021
+ if (value && typeof value === "object") {
7022
+ const serializedObject = {};
7023
+ for (const [key, itemValue] of Object.entries(value)) {
7024
+ const serializedItemValue = toUserFacingDetailsValue(itemValue, depth - 1);
7025
+ if (serializedItemValue !== void 0) {
7026
+ serializedObject[key] = serializedItemValue;
7027
+ }
7362
7028
  }
7029
+ if (Object.keys(serializedObject).length === 0) {
7030
+ return void 0;
7031
+ }
7032
+ return serializedObject;
7363
7033
  }
7364
- }`
7365
- }),
7366
- createOperationSpec({
7367
- operationName: "GetAutomationRuns",
7368
- kind: "query",
7369
- inputSchema: z.object({
7370
- automationId: z.string().min(1),
7371
- status: z.array(z.string().min(1)).optional(),
7372
- invocationType: z.array(z.string().min(1)).optional(),
7373
- limit: z.number().int().positive().optional(),
7374
- page: z.number().int().positive().optional()
7375
- }),
7376
- cli: {
7377
- name: "get-automation-runs",
7378
- path: ["automation-runs", "list"],
7379
- description: "Fetch automation run history.",
7380
- resultKey: "automationRuns",
7381
- options: [
7382
- stringOption({
7383
- inputKey: "automationId",
7384
- flagName: "automation-id",
7385
- description: "Automation ID.",
7386
- required: true
7387
- }),
7388
- stringArrayOption({
7389
- inputKey: "status",
7390
- flagName: "status",
7391
- description: "Optional run statuses."
7392
- }),
7393
- stringArrayOption({
7394
- inputKey: "invocationType",
7395
- flagName: "invocation-type",
7396
- description: "Optional invocation types."
7397
- }),
7398
- numberOption({
7399
- inputKey: "limit",
7400
- flagName: "limit",
7401
- description: "Maximum number of runs to return."
7402
- }),
7403
- numberOption({
7404
- inputKey: "page",
7405
- flagName: "page",
7406
- description: "Page number."
7407
- })
7408
- ]
7409
- },
7410
- mcp: { fileName: "automationRuns.graphql" },
7411
- document: `# Query automation run history for a specific automation with optional filters
7412
- query GetAutomationRuns(
7413
- $automationId: ID!
7414
- $status: [RunStatus!]
7415
- $invocationType: [InvocationType!]
7416
- $limit: Int
7417
- $page: Int
7418
- ) {
7419
- automationRuns(
7420
- automationId: $automationId
7421
- status: $status
7422
- invocationType: $invocationType
7423
- limit: $limit
7424
- page: $page
7425
- ) {
7426
- id
7427
- automationId
7428
- parentAutomationRunId
7429
- status
7430
- statusDetail
7431
- invocationType
7432
- summary
7433
- createdAt
7434
- startedAt
7435
- pausedAt
7436
- finishedAt
7034
+ return void 0;
7035
+ }
7036
+ function resolveApiDetails({ appError, statusCode }) {
7037
+ if (!shouldExposeMessage({ appError, statusCode })) {
7038
+ return void 0;
7437
7039
  }
7438
- }`
7439
- }),
7440
- createOperationSpec({
7441
- operationName: "ListAutomations",
7442
- kind: "query",
7443
- inputSchema: z.object({
7444
- limit: z.number().positive().optional(),
7445
- order: jsonObjectSchema.optional(),
7446
- where: jsonObjectSchema.optional()
7447
- }),
7448
- cli: {
7449
- name: "list-automations",
7450
- path: ["automations", "list"],
7451
- description: "List automations with optional filters.",
7452
- resultKey: "automations",
7453
- options: [
7454
- numberOption({
7455
- inputKey: "limit",
7456
- flagName: "limit",
7457
- description: "Maximum number of automations to return."
7458
- }),
7459
- jsonOption({
7460
- inputKey: "order",
7461
- flagName: "order-json",
7462
- description: "GraphQL order object."
7463
- }),
7464
- jsonOption({
7465
- inputKey: "where",
7466
- flagName: "where-json",
7467
- description: "GraphQL filter object."
7468
- })
7469
- ]
7470
- },
7471
- mcp: { fileName: "listAutomations.graphql" },
7472
- document: `# Query to list automations with flat fields only (no nested objects)
7473
- # Excludes config and agents for MCP tool simplicity
7474
- query ListAutomations(
7475
- $limit: Float
7476
- $order: AutomationsOrder
7477
- $where: AutomationsWhereInput
7478
- ) {
7479
- automations(limit: $limit, order: $order, where: $where) {
7480
- id
7481
- name
7482
- organizationId
7483
- createdAt
7484
- updatedAt
7485
- environment
7486
- lastSavedAt
7487
- publishedVersionId
7488
- draftVersionId
7040
+ const zodIssues = getZodIssuesFromCause(appError.cause);
7041
+ if (zodIssues && zodIssues.length > 0) {
7042
+ return {
7043
+ validationErrors: zodIssues.map((issue) => ({
7044
+ path: Array.isArray(issue.path) ? issue.path.map(String).join(".") : "",
7045
+ message: typeof issue.message === "string" ? issue.message : "Invalid value",
7046
+ ...typeof issue.code === "string" ? { code: issue.code } : {}
7047
+ }))
7048
+ };
7489
7049
  }
7490
- }`
7491
- }),
7492
- createOperationSpec({
7493
- operationName: "GetAutomations",
7494
- kind: "query",
7495
- inputSchema: z.object({
7496
- ids: z.array(z.string().min(1)).min(1)
7497
- }),
7498
- cli: {
7499
- name: "get-automations",
7500
- path: ["automations", "get"],
7501
- description: "Fetch one or more automations by IDs.",
7502
- resultKey: "automations",
7503
- options: [
7504
- stringArrayOption({
7505
- inputKey: "ids",
7506
- flagName: "ids",
7507
- description: "Automation IDs.",
7508
- required: true
7509
- })
7510
- ]
7511
- },
7512
- mcp: { fileName: "automations.graphql" },
7513
- document: `# Query to fetch automations with flat fields only (no nested objects)
7514
- # Excludes config and agents for MCP tool simplicity
7515
- query GetAutomations($ids: [ID!]!) {
7516
- automations(ids: $ids) {
7517
- id
7518
- name
7519
- organizationId
7520
- createdAt
7521
- updatedAt
7522
- environment
7523
- lastSavedAt
7524
- publishedVersionId
7525
- draftVersionId
7050
+ const rawDetails = toUserFacingDetailsValue(appError.details, 4);
7051
+ if (rawDetails && typeof rawDetails === "object" && !Array.isArray(rawDetails) && Object.keys(rawDetails).length > 0) {
7052
+ return rawDetails;
7526
7053
  }
7527
- }`
7528
- }),
7529
- createOperationSpec({
7530
- operationName: "GetAvailableCommands",
7531
- kind: "query",
7532
- inputSchema: z.object({
7533
- env: z.string().min(1)
7534
- }),
7535
- cli: {
7536
- name: "get-available-commands",
7537
- path: ["catalog", "commands"],
7538
- description: "Fetch available command definitions by environment.",
7539
- resultKey: "availableCommands",
7540
- options: [
7541
- stringOption({
7542
- inputKey: "env",
7543
- flagName: "env",
7544
- description: "Environment name.",
7545
- required: true
7546
- })
7547
- ]
7548
- },
7549
- mcp: { fileName: "availableCommands.graphql" },
7550
- document: `# Query to fetch available command definitions by environment
7551
- query GetAvailableCommands($env: AvailableCommandsEnv!) {
7552
- availableCommands(env: $env) {
7553
- id
7554
- description
7555
- inputSchema
7054
+ return void 0;
7055
+ }
7056
+ function getGraphQLErrorCodeFromAppErrorCode(code) {
7057
+ if (code === 400) {
7058
+ return "BAD_USER_INPUT";
7556
7059
  }
7557
- }`
7558
- }),
7559
- createOperationSpec({
7560
- operationName: "GetAvailableModels",
7561
- kind: "query",
7562
- inputSchema: z.object({
7563
- agentId: z.string().min(1)
7564
- }),
7565
- cli: {
7566
- name: "get-available-models",
7567
- path: ["catalog", "models"],
7568
- description: "Fetch available model definitions for an agent.",
7569
- resultKey: "availableModels",
7570
- options: [
7571
- stringOption({
7572
- inputKey: "agentId",
7573
- flagName: "agent-id",
7574
- description: "Agent ID.",
7575
- required: true
7576
- })
7577
- ]
7578
- },
7579
- mcp: { fileName: "availableModels.graphql" },
7580
- document: `# Query to fetch available model definitions and pools for a specific agent
7581
- query GetAvailableModels($agentId: String!) {
7582
- availableModels(agentId: $agentId) {
7583
- availableModelPools {
7584
- name
7585
- poolId
7586
- models {
7587
- id
7588
- name
7589
- description
7590
- status
7591
- provider
7592
- }
7060
+ if (code === 401) {
7061
+ return "UNAUTHORIZED";
7062
+ }
7063
+ if (code === 403) {
7064
+ return "FORBIDDEN";
7065
+ }
7066
+ if (code === 404) {
7067
+ return "NOT_FOUND";
7068
+ }
7069
+ if (code === 500) {
7070
+ return "INTERNAL_SERVER_ERROR";
7071
+ }
7072
+ return void 0;
7073
+ }
7074
+ function resolveGraphQLErrorCode(appError) {
7075
+ const codeFromAppErrorCode = getGraphQLErrorCodeFromAppErrorCode(appError.statusCode);
7076
+ if (codeFromAppErrorCode !== void 0) {
7077
+ return codeFromAppErrorCode;
7078
+ }
7079
+ const normalizedErrorType = appError.type.toLowerCase();
7080
+ if (normalizedErrorType.includes("unauthorized")) {
7081
+ return "UNAUTHORIZED";
7082
+ }
7083
+ if (normalizedErrorType.includes("forbidden")) {
7084
+ return "FORBIDDEN";
7085
+ }
7086
+ if (normalizedErrorType.includes("not-found")) {
7087
+ return "NOT_FOUND";
7088
+ }
7089
+ if (isCustomerUsageError(appError)) {
7090
+ return "BAD_USER_INPUT";
7091
+ }
7092
+ return "INTERNAL_SERVER_ERROR";
7093
+ }
7094
+ function getStatusCodeFromGraphQLErrorCode(code) {
7095
+ switch (code) {
7096
+ case "BAD_USER_INPUT": {
7097
+ return 400;
7593
7098
  }
7594
- allAvailableModels {
7595
- id
7596
- name
7597
- description
7598
- status
7599
- provider
7099
+ case "UNAUTHORIZED": {
7100
+ return 401;
7101
+ }
7102
+ case "FORBIDDEN": {
7103
+ return 403;
7104
+ }
7105
+ case "NOT_FOUND": {
7106
+ return 404;
7107
+ }
7108
+ case "INTERNAL_SERVER_ERROR": {
7109
+ return 500;
7600
7110
  }
7601
7111
  }
7602
- }`
7603
- }),
7604
- createOperationSpec({
7605
- operationName: "GetAvailableTools",
7606
- kind: "query",
7607
- inputSchema: z.object({
7608
- env: z.string().min(1),
7609
- automationId: z.string().min(1).optional()
7610
- }),
7611
- cli: {
7612
- name: "get-available-tools",
7613
- path: ["catalog", "tools"],
7614
- description: "Fetch available tool definitions by environment.",
7615
- resultKey: "availableTools",
7616
- options: [
7617
- stringOption({
7618
- inputKey: "env",
7619
- flagName: "env",
7620
- description: "Environment name.",
7621
- required: true
7622
- }),
7623
- stringOption({
7624
- inputKey: "automationId",
7625
- flagName: "automation-id",
7626
- description: "Optional automation ID."
7627
- })
7628
- ]
7629
- },
7630
- mcp: { fileName: "availableTools.graphql" },
7631
- document: `# Query to fetch available tool definitions by environment
7632
- query GetAvailableTools($env: AvailableCommandsEnv!, $automationId: String) {
7633
- availableTools(env: $env, automationId: $automationId) {
7634
- id
7635
- description
7636
- inputSchema
7112
+ }
7113
+ function getGraphQLErrorMessage({ code, apiMessage }) {
7114
+ switch (code) {
7115
+ case "BAD_USER_INPUT":
7116
+ case "NOT_FOUND":
7117
+ case "INTERNAL_SERVER_ERROR": {
7118
+ return apiMessage;
7119
+ }
7120
+ case "UNAUTHORIZED": {
7121
+ return "Unauthorized";
7122
+ }
7123
+ case "FORBIDDEN": {
7124
+ return "Forbidden";
7125
+ }
7637
7126
  }
7638
- }`
7639
- }),
7640
- createOperationSpec({
7641
- operationName: "CreateAutomation",
7642
- kind: "mutation",
7643
- inputSchema: z.object({
7644
- input: jsonObjectSchema
7645
- }),
7646
- cli: {
7647
- name: "create-automation",
7648
- path: ["automations", "create"],
7649
- description: "Create a draft automation.",
7650
- resultKey: "createAutomation",
7651
- options: [
7652
- jsonOption({
7653
- inputKey: "input",
7654
- flagName: "input-json",
7655
- description: "CreateAutomationInput payload.",
7656
- required: true
7657
- })
7658
- ]
7659
- },
7660
- mcp: { fileName: "createAutomation.graphql" },
7661
- document: `# Mutation to create a draft automation with optional initial values
7662
- # Returns flat fields only for MCP tool simplicity
7663
- mutation CreateAutomation($input: CreateAutomationInput!) {
7664
- createAutomation(input: $input) {
7665
- id
7666
- name
7667
- organizationId
7668
- createdAt
7669
- updatedAt
7670
- environment
7671
- lastSavedAt
7672
- publishedVersionId
7673
- draftVersionId
7127
+ }
7128
+ function getGraphQLAppErrorCode({ code, apiCode }) {
7129
+ if (code === "INTERNAL_SERVER_ERROR" || code === "UNAUTHORIZED" || code === "FORBIDDEN") {
7130
+ return code;
7674
7131
  }
7675
- }`
7676
- }),
7677
- createOperationSpec({
7678
- operationName: "GetGraphqlSchema",
7679
- kind: "query",
7680
- inputSchema: z.object({}),
7681
- cli: {
7682
- name: "get-graphql-schema",
7683
- path: ["graphql", "schema"],
7684
- description: "Fetch GraphQL schema metadata.",
7685
- resultKey: "graphqlSchema",
7686
- options: []
7687
- },
7688
- mcp: { fileName: "graphqlSchema.graphql" },
7689
- document: `# Query to fetch full GraphQL schema metadata.
7690
- # Uses the first-class graphqlSchema query field to avoid __schema validation
7691
- # issues in MCP tool-load paths while still returning introspection JSON.
7692
- # Response can be large: call sparingly (typically once per task/session) and
7693
- # reuse cached results.
7694
- query GetGraphqlSchema {
7695
- graphqlSchema
7696
- }`
7697
- }),
7698
- createOperationSpec({
7699
- operationName: "PauseAutomationRun",
7700
- kind: "mutation",
7701
- inputSchema: z.object({
7702
- automationRunId: z.string().min(1)
7132
+ return apiCode;
7133
+ }
7134
+ function normalizeErrorCodeSegment(value) {
7135
+ return value.trim().toUpperCase().replaceAll(/[^\dA-Z]+/gu, "_").replaceAll(/^_+/gu, "").replaceAll(/_+$/gu, "");
7136
+ }
7137
+ function getStatusCodeForAppErrorFromAppError(appError) {
7138
+ const statusCodeFromCode = getStatusCodeFromAppErrorCode(appError.statusCode);
7139
+ if (statusCodeFromCode !== void 0) {
7140
+ return statusCodeFromCode;
7141
+ }
7142
+ if (isCustomerUsageError(appError)) {
7143
+ return 400;
7144
+ }
7145
+ return 500;
7146
+ }
7147
+ function normalizeUserFacingErrorCode({ type, fallbackCode, prefix }) {
7148
+ if (!type) {
7149
+ return fallbackCode;
7150
+ }
7151
+ const normalized = normalizeErrorCodeSegment(type);
7152
+ if (normalized.length === 0) {
7153
+ return fallbackCode;
7154
+ }
7155
+ const normalizedPrefix = prefix ? normalizeErrorCodeSegment(prefix) : void 0;
7156
+ if (!normalizedPrefix) {
7157
+ return normalized;
7158
+ }
7159
+ if (normalized.startsWith(`${normalizedPrefix}_`)) {
7160
+ return normalized;
7161
+ }
7162
+ return `${normalizedPrefix}_${normalized}`;
7163
+ }
7164
+ function toUserFacingApiErrorFromAppError({ appError, correlationId, statusCode }) {
7165
+ const resolvedStatusCode = statusCode ?? getStatusCodeForAppErrorFromAppError(appError);
7166
+ const message = resolveApiMessage({
7167
+ appError,
7168
+ statusCode: resolvedStatusCode
7169
+ });
7170
+ const suggestedAction = resolveSuggestedAction({
7171
+ appError,
7172
+ statusCode: resolvedStatusCode
7173
+ });
7174
+ const details = resolveApiDetails({
7175
+ appError,
7176
+ statusCode: resolvedStatusCode
7177
+ });
7178
+ return {
7179
+ code: resolveApiErrorCode({
7180
+ appError,
7181
+ statusCode: resolvedStatusCode
7703
7182
  }),
7704
- cli: {
7705
- name: "pause-automation-run",
7706
- path: ["automation-runs", "pause"],
7707
- description: "Pause an automation run.",
7708
- resultKey: "pauseAutomationRun",
7709
- options: [
7710
- stringOption({
7711
- inputKey: "automationRunId",
7712
- flagName: "automation-run-id",
7713
- description: "Automation run ID.",
7714
- required: true
7715
- })
7716
- ]
7717
- },
7718
- mcp: { fileName: "pauseAutomationRun.graphql" },
7719
- document: `# Mutation to pause an automation run
7720
- mutation PauseAutomationRun($automationRunId: ID!) {
7721
- pauseAutomationRun(automationRunId: $automationRunId)
7722
- }`
7723
- }),
7724
- createOperationSpec({
7725
- operationName: "RerunAutomation",
7726
- kind: "mutation",
7727
- inputSchema: z.object({
7728
- automationRunId: z.string().min(1),
7729
- additionalPrompt: z.string().min(1).optional(),
7730
- idempotencyKey: z.string().min(1)
7731
- }),
7732
- cli: {
7733
- name: "rerun-automation",
7734
- path: ["automation-runs", "rerun"],
7735
- description: "Rerun an existing automation run.",
7736
- resultKey: "rerunAutomation",
7737
- options: [
7738
- stringOption({
7739
- inputKey: "automationRunId",
7740
- flagName: "automation-run-id",
7741
- description: "Automation run ID.",
7742
- required: true
7743
- }),
7744
- stringOption({
7745
- inputKey: "additionalPrompt",
7746
- flagName: "additional-prompt",
7747
- description: "Optional prompt appended to the rerun."
7748
- }),
7749
- stringOption({
7750
- inputKey: "idempotencyKey",
7751
- flagName: "idempotency-key",
7752
- description: "Idempotency key for the rerun request.",
7753
- required: true
7754
- })
7755
- ]
7756
- },
7757
- mcp: { fileName: "rerunAutomation.graphql" },
7758
- document: `# Mutation to rerun an existing automation run
7759
- mutation RerunAutomation(
7760
- $automationRunId: ID!
7761
- $additionalPrompt: String
7762
- $idempotencyKey: String!
7763
- ) {
7764
- rerunAutomation(
7765
- automationRunId: $automationRunId
7766
- additionalPrompt: $additionalPrompt
7767
- idempotencyKey: $idempotencyKey
7768
- ) {
7769
- automationRunId
7770
- workflowId
7771
- workflowRunId
7772
- }
7773
- }`
7774
- }),
7775
- createOperationSpec({
7776
- operationName: "ResumeAutomationRun",
7777
- kind: "mutation",
7778
- inputSchema: z.object({
7779
- automationRunId: z.string().min(1),
7780
- message: z.string().min(1).optional()
7781
- }),
7782
- cli: {
7783
- name: "resume-automation-run",
7784
- path: ["automation-runs", "resume"],
7785
- description: "Resume a paused automation run.",
7786
- resultKey: "resumeAutomationRun",
7787
- options: [
7788
- stringOption({
7789
- inputKey: "automationRunId",
7790
- flagName: "automation-run-id",
7791
- description: "Automation run ID.",
7792
- required: true
7793
- }),
7794
- stringOption({
7795
- inputKey: "message",
7796
- flagName: "message",
7797
- description: "Optional resume message."
7798
- })
7799
- ]
7800
- },
7801
- mcp: { fileName: "resumeAutomationRun.graphql" },
7802
- document: `# Mutation to resume an automation run
7803
- mutation ResumeAutomationRun($automationRunId: ID!, $message: String) {
7804
- resumeAutomationRun(automationRunId: $automationRunId, message: $message)
7805
- }`
7806
- }),
7807
- createOperationSpec({
7808
- operationName: "RunDraftAutomation",
7809
- kind: "mutation",
7810
- inputSchema: z.object({
7811
- draftAutomationId: z.string().min(1),
7812
- agentId: z.string().min(1),
7813
- idempotencyKey: z.string().min(1),
7814
- input: z.unknown().optional(),
7815
- additionalPrompt: z.string().min(1).optional()
7816
- }),
7817
- cli: {
7818
- name: "run-draft-automation",
7819
- path: ["automations", "run-draft"],
7820
- description: "Run a draft automation with an explicit trigger agent.",
7821
- resultKey: "runDraftAutomation",
7822
- options: [
7823
- stringOption({
7824
- inputKey: "draftAutomationId",
7825
- flagName: "draft-automation-id",
7826
- description: "Draft automation ID.",
7827
- required: true
7828
- }),
7829
- stringOption({
7830
- inputKey: "agentId",
7831
- flagName: "agent-id",
7832
- description: "Trigger agent ID.",
7833
- required: true
7834
- }),
7835
- stringOption({
7836
- inputKey: "idempotencyKey",
7837
- flagName: "idempotency-key",
7838
- description: "Idempotency key for the run request.",
7839
- required: true
7840
- }),
7841
- jsonOption({
7842
- inputKey: "input",
7843
- flagName: "input-json",
7844
- description: "Optional JSON input payload."
7845
- }),
7846
- stringOption({
7847
- inputKey: "additionalPrompt",
7848
- flagName: "additional-prompt",
7849
- description: "Optional prompt appended to the run."
7850
- })
7851
- ]
7852
- },
7853
- mcp: { fileName: "runDraftAutomation.graphql" },
7854
- document: `# Mutation to run a draft automation with an explicit agent.
7855
- # \`draftAutomationId\` is the draft automation entity ID (\`Automation.id\`), not \`draftVersionId\`.
7856
- mutation RunDraftAutomation(
7857
- $draftAutomationId: ID!
7858
- $agentId: ID!
7859
- $idempotencyKey: String!
7860
- $input: JSON
7861
- $additionalPrompt: String
7862
- ) {
7863
- runDraftAutomation(
7864
- draftAutomationId: $draftAutomationId
7865
- agentId: $agentId
7866
- idempotencyKey: $idempotencyKey
7867
- input: $input
7868
- additionalPrompt: $additionalPrompt
7869
- ) {
7870
- automationRunId
7871
- workflowId
7872
- workflowRunId
7183
+ message,
7184
+ correlationId,
7185
+ suggestedAction,
7186
+ ...details ? { details } : {}
7187
+ };
7188
+ }
7189
+ function toUserFacingGraphQLErrorFromAppError({ appError, correlationId }) {
7190
+ const code = resolveGraphQLErrorCode(appError);
7191
+ const statusCode = getStatusCodeFromGraphQLErrorCode(code);
7192
+ const apiError = toUserFacingApiErrorFromAppError({
7193
+ appError,
7194
+ correlationId,
7195
+ statusCode
7196
+ });
7197
+ return {
7198
+ code,
7199
+ errorCode: getGraphQLAppErrorCode({ code, apiCode: apiError.code }),
7200
+ message: getGraphQLErrorMessage({ code, apiMessage: apiError.message }),
7201
+ correlationId
7202
+ };
7203
+ }
7204
+
7205
+ // ../common/dist/src/stdlib/error.js
7206
+ var INTERNAL_STACK_PATHS = [
7207
+ "/src/stdlib/result.util.ts",
7208
+ "/src/stdlib/error.ts"
7209
+ ];
7210
+ function stripInternalFrames(stack, internalFrames) {
7211
+ const lines = stack.split("\n");
7212
+ return lines.filter((line) => !internalFrames.some((internalFrame) => line.includes(internalFrame)));
7213
+ }
7214
+ var ORDERED_APP_ERROR_CATEGORIES = [
7215
+ "internal_platform",
7216
+ "customer_usage",
7217
+ "third_party"
7218
+ ];
7219
+ function isAppErrorCategory(category) {
7220
+ return typeof category === "string" && // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
7221
+ ORDERED_APP_ERROR_CATEGORIES.includes(category);
7222
+ }
7223
+ function isNonEmptyAppErrorCategoryArray(categories) {
7224
+ return Array.isArray(categories) && categories.length > 0 && categories.every(isAppErrorCategory);
7225
+ }
7226
+ var APP_ERROR_SEVERITIES = ["warn", "error", "fatal"];
7227
+ function isAppErrorCode(code) {
7228
+ return typeof code === "number" && Number.isInteger(code) && code >= 400 && code <= 599;
7229
+ }
7230
+ function isAppErrorSeverity(severity) {
7231
+ return typeof severity === "string" && // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
7232
+ APP_ERROR_SEVERITIES.includes(severity);
7233
+ }
7234
+ var AppError = class _AppError extends Error {
7235
+ type;
7236
+ categories;
7237
+ severity;
7238
+ statusCode;
7239
+ suggestedAction;
7240
+ nonRetryable;
7241
+ details;
7242
+ constructor({ type, categories, severity, statusCode, code, message, suggestedAction, cause, nonRetryable, stack, internalFrames, ...details }) {
7243
+ super(_AppError.resolveMessage(message, cause, type), { cause });
7244
+ this.type = type;
7245
+ this.name = type;
7246
+ this.details = details;
7247
+ this.categories = categories ?? _AppError.extractCategoriesFromCause(cause);
7248
+ this.severity = severity ?? _AppError.extractSeverityFromCause(cause);
7249
+ this.statusCode = statusCode ?? code ?? _AppError.extractStatusCodeFromCause(cause);
7250
+ this.suggestedAction = suggestedAction ?? _AppError.extractSuggestedActionFromCause(cause);
7251
+ this.nonRetryable = nonRetryable ?? false;
7252
+ _AppError.applyStack(this, stack, internalFrames);
7873
7253
  }
7874
- }`
7875
- }),
7876
- createOperationSpec({
7877
- operationName: "StopAutomationRun",
7878
- kind: "mutation",
7879
- inputSchema: z.object({
7880
- automationRunId: z.string().min(1)
7881
- }),
7882
- cli: {
7883
- name: "stop-automation-run",
7884
- path: ["automation-runs", "stop"],
7885
- description: "Stop an automation run.",
7886
- resultKey: "stopAutomationRun",
7887
- options: [
7888
- stringOption({
7889
- inputKey: "automationRunId",
7890
- flagName: "automation-run-id",
7891
- description: "Automation run ID.",
7892
- required: true
7893
- })
7894
- ]
7895
- },
7896
- mcp: { fileName: "stopAutomationRun.graphql" },
7897
- document: `# Mutation to stop an automation run
7898
- mutation StopAutomationRun($automationRunId: ID!) {
7899
- stopAutomationRun(automationRunId: $automationRunId)
7900
- }`
7901
- }),
7902
- createOperationSpec({
7903
- operationName: "UpdateAutomationById",
7904
- kind: "mutation",
7905
- inputSchema: z.object({
7906
- id: z.string().min(1),
7907
- input: jsonObjectSchema
7908
- }),
7909
- cli: {
7910
- name: "update-automation-by-id",
7911
- path: ["automations", "update"],
7912
- description: "Update an automation.",
7913
- resultKey: "updateAutomation",
7914
- options: [
7915
- stringOption({
7916
- inputKey: "id",
7917
- flagName: "id",
7918
- description: "Automation ID.",
7919
- required: true
7920
- }),
7921
- jsonOption({
7922
- inputKey: "input",
7923
- flagName: "input-json",
7924
- description: "UpdateAutomationInput payload.",
7925
- required: true
7926
- })
7927
- ]
7928
- },
7929
- mcp: { fileName: "updateAutomation.graphql" },
7930
- document: `# Mutation to update an automation
7931
- # Returns only id and lastSavedAt for MCP tool simplicity
7932
- mutation UpdateAutomationById($id: ID!, $input: UpdateAutomationInput!) {
7933
- updateAutomation(id: $id, input: $input) {
7934
- id
7935
- lastSavedAt
7254
+ static resolveMessage(message, cause, type) {
7255
+ if (message) {
7256
+ return message;
7257
+ }
7258
+ if (cause instanceof Error) {
7259
+ return cause.message;
7260
+ }
7261
+ return type;
7936
7262
  }
7937
- }`
7938
- })
7939
- ];
7940
-
7941
- // src/program.ts
7942
- import { Command as Command2, InvalidArgumentError as InvalidArgumentError2, Option as Option2 } from "commander";
7943
-
7944
- // src/api.ts
7945
- import { z as z2 } from "zod";
7946
- var workosOrganizationsResponseSchema = z2.object({
7947
- organizations: z2.array(
7948
- z2.object({
7949
- id: z2.string().min(1),
7950
- name: z2.string().min(1),
7951
- primaryDomain: z2.string().nullable().optional()
7952
- })
7953
- ),
7954
- success: z2.boolean()
7955
- });
7956
- var workosUserSchema = z2.object({
7957
- email: z2.string().nullable(),
7958
- id: z2.string().min(1)
7959
- });
7960
- var graphQlResponseSchema = z2.object({
7961
- data: z2.record(z2.string(), z2.unknown()).optional(),
7962
- errors: z2.array(
7963
- z2.object({
7964
- message: z2.string().min(1)
7965
- })
7966
- ).optional()
7967
- });
7968
- var apiErrorResponseSchema = z2.object({
7969
- errors: z2.array(
7970
- z2.object({
7971
- message: z2.string().min(1)
7972
- })
7973
- ).optional(),
7974
- message: z2.string().min(1).optional()
7975
- });
7976
- function getApiErrorDetail(responseBody) {
7977
- const parsedResponse = apiErrorResponseSchema.safeParse(responseBody);
7978
- if (!parsedResponse.success) {
7979
- return null;
7263
+ static getInheritedCauseField(cause, extractor, seen = /* @__PURE__ */ new Set()) {
7264
+ if (!cause || typeof cause !== "object" || seen.has(cause)) {
7265
+ return void 0;
7266
+ }
7267
+ const causeRecord = cause;
7268
+ const extractedValue = extractor(causeRecord);
7269
+ if (extractedValue !== void 0) {
7270
+ return extractedValue;
7271
+ }
7272
+ return _AppError.getInheritedCauseField(causeRecord["cause"], extractor, new Set(seen).add(cause));
7980
7273
  }
7981
- if (parsedResponse.data.message) {
7982
- return parsedResponse.data.message;
7274
+ static extractCategoriesFromCause(cause) {
7275
+ return _AppError.getInheritedCauseField(cause, (causeRecord) => {
7276
+ const { categories } = causeRecord;
7277
+ if (isNonEmptyAppErrorCategoryArray(categories)) {
7278
+ return categories;
7279
+ }
7280
+ return void 0;
7281
+ }) ?? ["internal_platform"];
7983
7282
  }
7984
- if (!parsedResponse.data.errors || parsedResponse.data.errors.length === 0) {
7985
- return null;
7283
+ static extractSeverityFromCause(cause) {
7284
+ return _AppError.getInheritedCauseField(cause, (causeRecord) => {
7285
+ const { severity } = causeRecord;
7286
+ return isAppErrorSeverity(severity) ? severity : void 0;
7287
+ }) ?? "error";
7986
7288
  }
7987
- return parsedResponse.data.errors.map((error) => error.message).join("\n");
7988
- }
7989
- function trimTrailingSlash(value) {
7990
- return value.replace(/\/+$/u, "");
7991
- }
7992
- function createMagicalApiClient({
7993
- apiBaseUrl,
7994
- fetchFn = fetch
7995
- }) {
7996
- const resolveApiBaseUrl = typeof apiBaseUrl === "string" ? () => apiBaseUrl : apiBaseUrl;
7997
- async function fetchJson({
7998
- accessToken,
7999
- path: path7,
8000
- init
8001
- }) {
8002
- const url = `${trimTrailingSlash(await resolveApiBaseUrl())}${path7}`;
8003
- const headers = new Headers(init?.headers);
8004
- headers.set("authorization", `Bearer ${accessToken}`);
8005
- const response = await fetchFn(url, {
8006
- ...init,
8007
- headers
8008
- }).catch((error) => {
8009
- throw new CliError(
8010
- `Failed to reach Magical API at ${url}. Check your configured base URL and make sure service-main is running.`,
8011
- { cause: error }
8012
- );
7289
+ static extractStatusCodeFromCause(cause) {
7290
+ return _AppError.getInheritedCauseField(cause, (causeRecord) => {
7291
+ const { statusCode } = causeRecord;
7292
+ if (isAppErrorCode(statusCode)) {
7293
+ return statusCode;
7294
+ }
7295
+ const { code: legacyCode } = causeRecord;
7296
+ return isAppErrorCode(legacyCode) ? legacyCode : void 0;
8013
7297
  });
8014
- const responseBody = await response.json().catch((error) => {
8015
- if (!response.ok) {
8016
- throw new CliError(
8017
- `Magical API request to ${url} failed with status ${response.status}.`,
8018
- {
8019
- cause: error
8020
- }
8021
- );
7298
+ }
7299
+ /** @deprecated Use statusCode instead. */
7300
+ get code() {
7301
+ return this.statusCode;
7302
+ }
7303
+ static extractSuggestedActionFromCause(cause) {
7304
+ return _AppError.getInheritedCauseField(cause, (causeRecord) => {
7305
+ const { suggestedAction } = causeRecord;
7306
+ if (typeof suggestedAction !== "string") {
7307
+ return void 0;
8022
7308
  }
8023
- throw new CliError(
8024
- `Magical API returned a non-JSON response for ${url}.`,
8025
- {
8026
- cause: error
8027
- }
8028
- );
7309
+ const trimmedSuggestedAction = suggestedAction.trim();
7310
+ return trimmedSuggestedAction.length > 0 ? trimmedSuggestedAction : void 0;
8029
7311
  });
8030
- if (!response.ok) {
8031
- const errorDetail = getApiErrorDetail(responseBody);
8032
- throw new CliError(
8033
- `Magical API request to ${url} failed with status ${response.status}${errorDetail ? `: ${errorDetail}` : "."}`
8034
- );
7312
+ }
7313
+ static applyStack(error, stack, internalFrames) {
7314
+ if (stack) {
7315
+ error.stack = stack;
8035
7316
  }
8036
- return responseBody;
7317
+ error.stack &&= stripInternalFrames(error.stack, [
7318
+ ...INTERNAL_STACK_PATHS,
7319
+ ...internalFrames ?? []
7320
+ ]).join("\n");
8037
7321
  }
8038
- return {
8039
- async executeGraphQl({
8040
- accessToken,
8041
- query,
8042
- resultKey,
8043
- variables
8044
- }) {
8045
- const headers = new Headers();
8046
- headers.set("content-type", "application/json");
8047
- const parsedResponse = graphQlResponseSchema.safeParse(
8048
- await fetchJson({
8049
- accessToken,
8050
- path: "/graphql",
8051
- init: {
8052
- method: "POST",
8053
- headers,
8054
- body: JSON.stringify({
8055
- query,
8056
- variables
8057
- })
8058
- }
8059
- })
8060
- );
8061
- if (!parsedResponse.success) {
8062
- throw new CliError("GraphQL response payload was invalid.");
8063
- }
8064
- if (parsedResponse.data.errors && parsedResponse.data.errors.length > 0) {
8065
- throw new CliError(
8066
- parsedResponse.data.errors.map((error) => error.message).join("\n")
8067
- );
8068
- }
8069
- return parsedResponse.data.data?.[resultKey] ?? null;
8070
- },
8071
- async fetchOrganizations({ accessToken }) {
8072
- const parsedResponse = workosOrganizationsResponseSchema.safeParse(
8073
- await fetchJson({
8074
- accessToken,
8075
- path: "/workos/organizations"
8076
- })
8077
- );
8078
- if (!parsedResponse.success) {
8079
- throw new CliError("Organization list payload was invalid.");
7322
+ toApiError({ correlationId }) {
7323
+ return toUserFacingApiError({
7324
+ error: this,
7325
+ correlationId,
7326
+ statusCode: getStatusCodeForAppError(this)
7327
+ });
7328
+ }
7329
+ toGqlError({ correlationId }) {
7330
+ return toUserFacingGraphQLError({
7331
+ error: this,
7332
+ correlationId
7333
+ });
7334
+ }
7335
+ };
7336
+ function toAppError(error) {
7337
+ return error instanceof AppError ? error : new AppError(error);
7338
+ }
7339
+ function getStatusCodeForAppError(error) {
7340
+ const appError = toAppError(error);
7341
+ return getStatusCodeForAppErrorFromAppError(appError);
7342
+ }
7343
+ function toUserFacingApiError({ error, correlationId, statusCode }) {
7344
+ const appError = toAppError(error);
7345
+ return toUserFacingApiErrorFromAppError({
7346
+ appError,
7347
+ correlationId,
7348
+ statusCode
7349
+ });
7350
+ }
7351
+ function toUserFacingGraphQLError({ error, correlationId }) {
7352
+ const appError = toAppError(error);
7353
+ return toUserFacingGraphQLErrorFromAppError({
7354
+ appError,
7355
+ correlationId
7356
+ });
7357
+ }
7358
+
7359
+ // ../common/dist/src/stdlib/result.util.js
7360
+ var Result;
7361
+ (function(Result2) {
7362
+ function partition(responses) {
7363
+ const oks = responses.filter((resp) => resp._tag === "Ok").map((resp) => resp.value);
7364
+ const errs = responses.filter((resp) => resp._tag === "Err").map((resp) => resp.error);
7365
+ return [oks, errs];
7366
+ }
7367
+ Result2.partition = partition;
7368
+ async function promiseAllAndPartition(promises) {
7369
+ const results = await Promise.all(promises);
7370
+ return partition(results);
7371
+ }
7372
+ Result2.promiseAllAndPartition = promiseAllAndPartition;
7373
+ function unwrapOrThrow(result) {
7374
+ if (isErr(result)) {
7375
+ throw result.error;
7376
+ }
7377
+ return result.value;
7378
+ }
7379
+ Result2.unwrapOrThrow = unwrapOrThrow;
7380
+ async function all(promises) {
7381
+ const results = await fromThrowable(async () => Promise.all(promises.map(async (promise) => {
7382
+ const result = await promise;
7383
+ if (isErr(result)) {
7384
+ throw result.error;
8080
7385
  }
8081
- return parsedResponse.data.organizations.map((organization) => ({
8082
- id: organization.id,
8083
- name: organization.name,
8084
- primaryDomain: organization.primaryDomain ?? null
8085
- }));
8086
- },
8087
- async fetchUser({
8088
- accessToken,
8089
- userId
8090
- }) {
8091
- const parsedResponse = workosUserSchema.safeParse(
8092
- await fetchJson({
8093
- accessToken,
8094
- path: `/workos/user/${userId}`
8095
- })
8096
- );
8097
- if (!parsedResponse.success) {
8098
- throw new CliError("User payload was invalid.");
7386
+ return result;
7387
+ })), "unknown-error");
7388
+ if (isErr(results)) {
7389
+ return ErrFromThrowable(results.error.cause);
7390
+ }
7391
+ return Ok(results.value.map((r) => r.value));
7392
+ }
7393
+ Result2.all = all;
7394
+ function andThenSync(fnFirst, ...fns) {
7395
+ let result = fnFirst();
7396
+ const values = [];
7397
+ for (const fn of fns) {
7398
+ if (isErr(result)) {
7399
+ return result;
8099
7400
  }
8100
- return parsedResponse.data;
7401
+ values.unshift(result.value);
7402
+ result = fn(...values);
8101
7403
  }
8102
- };
8103
- }
8104
-
8105
- // src/config.ts
8106
- import os from "os";
8107
- import path from "path";
8108
- var DEFAULT_MAGICAL_API_URL = "https://api-agt.getmagical.io";
8109
- var DEFAULT_WORKOS_API_URL = "https://api.workos.com";
8110
- var DEFAULT_WORKOS_CLIENT_ID = "client_01JJZ6XJ1RF248P20WF63M4VAM";
8111
- var DEFAULT_STAGING_WORKOS_CLIENT_ID = "client_01JJZ6X26BGFBT8AC303XPQ9EQ";
8112
- var DEFAULT_KEYCHAIN_SERVICE_NAME = "@getmagical/mcp-cli";
8113
- var DEFAULT_CLI_DIST_TAG = "latest";
8114
- var DEFAULT_CLI_NPM_REGISTRY_URL = "https://registry.npmjs.org/";
8115
- var CLI_CONFIG_DIRECTORY_NAME = "magical-mcp-cli";
8116
- var CLI_ACCESS_TOKEN_FILE_NAME = "access-token.txt";
8117
- var CLI_STATE_FILE_NAME = "state.json";
8118
- var CLI_SETTINGS_FILE_NAME = "settings.json";
8119
- var CLI_REFRESH_TOKEN_FILE_NAME = "refresh-tokens.json";
8120
- function resolvePlatformConfigDirectory() {
8121
- const customConfigDirectory = process.env["MAGICAL_CLI_CONFIG_DIR"];
8122
- if (customConfigDirectory) {
8123
- return customConfigDirectory;
7404
+ return result;
8124
7405
  }
8125
- if (process.platform === "darwin") {
8126
- return path.join(os.homedir(), "Library", "Application Support");
7406
+ Result2.andThenSync = andThenSync;
7407
+ async function andThen(fnFirst, ...fns) {
7408
+ let result = await fnFirst();
7409
+ const values = [];
7410
+ for (const fn of fns) {
7411
+ if (isErr(result)) {
7412
+ return result;
7413
+ }
7414
+ values.unshift(result.value);
7415
+ result = await fn(...values);
7416
+ }
7417
+ return result;
8127
7418
  }
8128
- if (process.platform === "win32") {
8129
- const appDataDirectory = process.env["APPDATA"];
8130
- return appDataDirectory ?? path.join(os.homedir(), "AppData", "Roaming");
7419
+ Result2.andThen = andThen;
7420
+ })(Result || (Result = {}));
7421
+ function Ok(value) {
7422
+ if (arguments.length === 0) {
7423
+ return {
7424
+ _tag: "Ok",
7425
+ value: void 0
7426
+ };
8131
7427
  }
8132
- return process.env["XDG_CONFIG_HOME"] ?? path.join(os.homedir(), ".config");
7428
+ return {
7429
+ _tag: "Ok",
7430
+ value
7431
+ };
8133
7432
  }
8134
- function resolveRefreshTokenStoreKind() {
8135
- return process.env["MAGICAL_CLI_REFRESH_TOKEN_STORE"] === "file" ? "file" : "keytar";
7433
+ function Err(error) {
7434
+ return {
7435
+ _tag: "Err",
7436
+ error: new AppError(error)
7437
+ };
8136
7438
  }
8137
- function getRuntimeConfig() {
8138
- const configDirectory = path.join(
8139
- resolvePlatformConfigDirectory(),
8140
- CLI_CONFIG_DIRECTORY_NAME
8141
- );
7439
+ function ErrFromThrowable(error) {
8142
7440
  return {
8143
- accessTokenFilePath: path.join(configDirectory, CLI_ACCESS_TOKEN_FILE_NAME),
8144
- cliDistTag: process.env["MAGICAL_CLI_DIST_TAG"] ?? DEFAULT_CLI_DIST_TAG,
8145
- magicalApiUrl: DEFAULT_MAGICAL_API_URL,
8146
- npmRegistryUrl: process.env["MAGICAL_CLI_NPM_REGISTRY_URL"] ?? DEFAULT_CLI_NPM_REGISTRY_URL,
8147
- refreshTokenFilePath: path.join(
8148
- configDirectory,
8149
- CLI_REFRESH_TOKEN_FILE_NAME
8150
- ),
8151
- refreshTokenStoreKind: resolveRefreshTokenStoreKind(),
8152
- stateFilePath: path.join(configDirectory, CLI_STATE_FILE_NAME),
8153
- workosApiUrl: DEFAULT_WORKOS_API_URL,
8154
- workosClientId: DEFAULT_WORKOS_CLIENT_ID,
8155
- keychainServiceName: DEFAULT_KEYCHAIN_SERVICE_NAME
7441
+ _tag: "Err",
7442
+ error
8156
7443
  };
8157
7444
  }
8158
- function requireWorkosClientId(config) {
8159
- return config.workosClientId;
7445
+ function isErr(result) {
7446
+ return result._tag === "Err";
7447
+ }
7448
+ function fromThrowable(fn, errorType, errorInfo) {
7449
+ try {
7450
+ const result = fn();
7451
+ if (result && typeof result.then === "function") {
7452
+ return result.then((value) => Ok(value)).catch((err) => Err({
7453
+ ...errorInfo,
7454
+ type: errorType,
7455
+ cause: err
7456
+ }));
7457
+ }
7458
+ return Ok(result);
7459
+ } catch (err) {
7460
+ return Err({
7461
+ ...errorInfo,
7462
+ type: errorType,
7463
+ cause: err
7464
+ });
7465
+ }
8160
7466
  }
8161
-
8162
- // src/settings.ts
8163
- import { mkdir, readFile, rm, writeFile } from "fs/promises";
8164
- import path2 from "path";
8165
7467
 
8166
7468
  // ../common/dist/src/stdlib/json.util.js
8167
- var import_ts_essentials = __toESM(require_dist(), 1);
8168
-
8169
- // ../common/dist/src/stdlib/result.util.js
8170
- import { z as z3 } from "zod";
8171
-
8172
- // ../common/dist/src/stdlib/error-user-facing.js
8173
- var USER_FACING_STATUS_MESSAGES = /* @__PURE__ */ new Map([
8174
- [400, "Bad Request"],
8175
- [401, "Unauthorized"],
8176
- [403, "Forbidden"],
8177
- [404, "Not Found"],
8178
- [500, "Internal Server Error"],
8179
- [503, "Service Unavailable"]
8180
- ]);
8181
- var USER_FACING_DEFAULT_ACTIONS = /* @__PURE__ */ new Map([
8182
- [400, "Review the request payload and retry."],
8183
- [401, "Authenticate and retry the request."],
8184
- [403, "Verify your permissions and retry the request."],
8185
- [404, "Verify the requested resource exists and retry."],
8186
- [
8187
- 500,
8188
- "Retry the request. If this keeps happening, contact support and share the correlation ID."
8189
- ],
8190
- [
8191
- 503,
8192
- "Retry the request after a brief delay. If this keeps happening, contact support and share the correlation ID."
8193
- ]
8194
- ]);
8195
- var USER_FACING_FALLBACK_CODES = /* @__PURE__ */ new Map([
8196
- [400, "BAD_REQUEST"],
8197
- [401, "UNAUTHORIZED"],
8198
- [403, "FORBIDDEN"],
8199
- [404, "NOT_FOUND"],
8200
- [500, "INTERNAL_SERVER_ERROR"],
8201
- [503, "SERVICE_UNAVAILABLE"]
8202
- ]);
8203
- function isCustomerUsageError(appError) {
8204
- return appError.categories.includes("customer_usage");
8205
- }
8206
- function getStatusCodeFromAppErrorCode(code) {
8207
- if (typeof code !== "number" || !Number.isInteger(code)) {
8208
- return void 0;
8209
- }
8210
- if (code >= 400 && code <= 599) {
8211
- return code;
7469
+ function safeJsonParse(json) {
7470
+ try {
7471
+ return Ok(JSON.parse(json));
7472
+ } catch (error) {
7473
+ console.warn("Failed to parse JSON", { error, json });
7474
+ return Err({ type: "invalid-json", cause: error, json });
8212
7475
  }
8213
- return void 0;
8214
7476
  }
8215
- function getStatusFamilyFallbackCode(statusCode) {
8216
- if (statusCode >= 400 && statusCode <= 499) {
8217
- return 400;
8218
- }
8219
- return 500;
7477
+
7478
+ // ../mcp-registry/src/operation-specs.ts
7479
+ import { z as z2 } from "zod";
7480
+
7481
+ // ../mcp-registry/src/operation-spec.ts
7482
+ function stripLeadingGraphqlComments(document) {
7483
+ return document.replace(/^(?:\s*#.*\n)+/u, "").trimStart();
8220
7484
  }
8221
- function getStatusMessage(statusCode) {
8222
- const directMessage = USER_FACING_STATUS_MESSAGES.get(statusCode);
8223
- if (directMessage !== void 0) {
8224
- return directMessage;
7485
+ function assertDocumentMatchesOperation({
7486
+ document,
7487
+ kind,
7488
+ operationName
7489
+ }) {
7490
+ const normalizedDocument = stripLeadingGraphqlComments(document);
7491
+ const match = /^(?<actualKind>query|mutation)\s+(?<actualOperationName>[_A-Za-z][_0-9A-Za-z]*)/u.exec(
7492
+ normalizedDocument
7493
+ );
7494
+ const actualKind = match?.groups?.["actualKind"];
7495
+ const actualOperationName = match?.groups?.["actualOperationName"];
7496
+ if (!actualKind || !actualOperationName) {
7497
+ throw new Error(
7498
+ `Operation "${operationName}" is missing a top-level GraphQL ${kind} definition.`
7499
+ );
8225
7500
  }
8226
- return getStatusFamilyFallbackCode(statusCode) === 400 ? "Bad Request" : "Internal Server Error";
8227
- }
8228
- function getDefaultSuggestedAction(statusCode) {
8229
- const directAction = USER_FACING_DEFAULT_ACTIONS.get(statusCode);
8230
- if (directAction !== void 0) {
8231
- return directAction;
7501
+ if (actualKind !== kind || actualOperationName !== operationName) {
7502
+ throw new Error(
7503
+ `Operation "${operationName}" does not match its GraphQL document (${actualKind} ${actualOperationName}).`
7504
+ );
8232
7505
  }
8233
- return getStatusFamilyFallbackCode(statusCode) === 400 ? "Review the request payload and retry." : "Retry the request. If this keeps happening, contact support and share the correlation ID.";
8234
7506
  }
8235
- function getFallbackErrorCode(statusCode) {
8236
- const directCode = USER_FACING_FALLBACK_CODES.get(statusCode);
8237
- if (directCode !== void 0) {
8238
- return directCode;
8239
- }
8240
- return getStatusFamilyFallbackCode(statusCode) === 400 ? "BAD_REQUEST" : "INTERNAL_SERVER_ERROR";
7507
+ function createOperationSpec(spec) {
7508
+ assertDocumentMatchesOperation(spec);
7509
+ return spec;
8241
7510
  }
8242
- function shouldExposeMessage({ appError, statusCode }) {
8243
- if (statusCode >= 500) {
8244
- return false;
8245
- }
8246
- return isCustomerUsageError(appError);
7511
+
7512
+ // ../mcp-registry/src/operation-specs.ts
7513
+ function stringOption({
7514
+ description,
7515
+ flagName,
7516
+ inputKey,
7517
+ required = false
7518
+ }) {
7519
+ return {
7520
+ description,
7521
+ flagName,
7522
+ inputKey,
7523
+ required,
7524
+ valueType: "string"
7525
+ };
8247
7526
  }
8248
- function resolveApiMessage({ appError, statusCode }) {
8249
- if (!shouldExposeMessage({ appError, statusCode })) {
8250
- return getStatusMessage(statusCode);
8251
- }
8252
- const trimmedMessage = appError.message.trim();
8253
- if (trimmedMessage.length > 0) {
8254
- return trimmedMessage;
8255
- }
8256
- return getStatusMessage(statusCode);
7527
+ function numberOption({
7528
+ description,
7529
+ flagName,
7530
+ inputKey,
7531
+ required = false
7532
+ }) {
7533
+ return {
7534
+ description,
7535
+ flagName,
7536
+ inputKey,
7537
+ required,
7538
+ valueType: "number"
7539
+ };
8257
7540
  }
8258
- function resolveApiErrorCode({ appError, statusCode }) {
8259
- if (!shouldExposeMessage({ appError, statusCode })) {
8260
- return getFallbackErrorCode(statusCode);
8261
- }
8262
- return normalizeUserFacingErrorCode({
8263
- type: appError.type,
8264
- fallbackCode: getFallbackErrorCode(statusCode)
8265
- });
7541
+ function booleanOption({
7542
+ description,
7543
+ flagName,
7544
+ inputKey
7545
+ }) {
7546
+ return {
7547
+ description,
7548
+ flagName,
7549
+ inputKey,
7550
+ valueType: "boolean"
7551
+ };
8266
7552
  }
8267
- function resolveSuggestedAction({ appError, statusCode }) {
8268
- const trimmedSuggestedAction = appError.suggestedAction?.trim();
8269
- if (shouldExposeMessage({ appError, statusCode }) && trimmedSuggestedAction) {
8270
- return trimmedSuggestedAction;
8271
- }
8272
- return getDefaultSuggestedAction(statusCode);
7553
+ function stringArrayOption({
7554
+ description,
7555
+ flagName,
7556
+ inputKey,
7557
+ required = false
7558
+ }) {
7559
+ return {
7560
+ description,
7561
+ flagName,
7562
+ inputKey,
7563
+ required,
7564
+ valueHint: "comma-separated",
7565
+ valueType: "string-array"
7566
+ };
8273
7567
  }
8274
- function getZodIssuesFromCause(cause, maxDepth = 10) {
8275
- if (maxDepth < 0 || typeof cause !== "object" || cause === null) {
8276
- return void 0;
8277
- }
8278
- if ("issues" in cause && Array.isArray(cause.issues)) {
8279
- return cause.issues;
8280
- }
8281
- if ("cause" in cause) {
8282
- return getZodIssuesFromCause(cause.cause, maxDepth - 1);
8283
- }
8284
- return void 0;
7568
+ function jsonOption({
7569
+ description,
7570
+ flagName,
7571
+ inputKey,
7572
+ required = false
7573
+ }) {
7574
+ return {
7575
+ description,
7576
+ flagName,
7577
+ inputKey,
7578
+ required,
7579
+ valueHint: "JSON",
7580
+ valueType: "json"
7581
+ };
8285
7582
  }
8286
- function toUserFacingDetailsValue(value, depth) {
8287
- if (depth < 0) {
8288
- return void 0;
8289
- }
8290
- if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
8291
- return value;
8292
- }
8293
- if (Array.isArray(value)) {
8294
- const serializedValues = value.map((item) => toUserFacingDetailsValue(item, depth - 1)).filter((item) => item !== void 0);
8295
- return serializedValues;
8296
- }
8297
- if (value && typeof value === "object") {
8298
- const serializedObject = {};
8299
- for (const [key, itemValue] of Object.entries(value)) {
8300
- const serializedItemValue = toUserFacingDetailsValue(itemValue, depth - 1);
8301
- if (serializedItemValue !== void 0) {
8302
- serializedObject[key] = serializedItemValue;
8303
- }
7583
+ var jsonObjectSchema = z2.record(z2.string(), z2.unknown());
7584
+ var agentBrowserProviderOptionsSelection = ` browserbase {
7585
+ advancedStealth
7586
+ contextId
7587
+ extensionId
7588
+ instanceSize
7589
+ blockAds
7590
+ solveCaptchas
7591
+ viewport {
7592
+ width
7593
+ height
7594
+ }
7595
+ }
7596
+ agentCore {
7597
+ viewport {
7598
+ width
7599
+ height
7600
+ }
7601
+ enableWebBotAuth
7602
+ }
7603
+ local {
7604
+ viewport {
7605
+ width
7606
+ height
7607
+ }
7608
+ }
7609
+ hyperbrowser {
7610
+ viewport {
7611
+ width
7612
+ height
7613
+ }
7614
+ }
7615
+ steel {
7616
+ extensionIds
7617
+ region
7618
+ solveCaptcha
7619
+ viewport {
7620
+ width
7621
+ height
7622
+ }
7623
+ }`;
7624
+ var agentEnvironmentOptionsSelection = ` environmentOptions {
7625
+ __typename
7626
+ ... on AgentConfig_environmentOptions_Browser {
7627
+ environment
7628
+ maxMediaToIncludeInMemory
7629
+ saveAuthCookiesAfterRun
7630
+ startingUrl
7631
+ browserProvider
7632
+ browserProviderOptions {
7633
+ ${agentBrowserProviderOptionsSelection}
7634
+ }
7635
+ }
7636
+ ... on AgentConfig_environmentOptions_Browsercoordinates {
7637
+ environment
7638
+ maxMediaToIncludeInMemory
7639
+ saveAuthCookiesAfterRun
7640
+ startingUrl
7641
+ browserProvider
7642
+ browserProviderOptions {
7643
+ ${agentBrowserProviderOptionsSelection}
7644
+ }
7645
+ }
7646
+ ... on AgentConfig_environmentOptions_Desktop {
7647
+ environment
7648
+ browserProvider
7649
+ browserProviderOptions {
7650
+ ${agentBrowserProviderOptionsSelection}
7651
+ }
7652
+ maxMediaToIncludeInMemory
7653
+ startingUrl
7654
+ useCopyPasteForTyping
7655
+ }
7656
+ ... on AgentConfig_environmentOptions_Desktopapp {
7657
+ environment
7658
+ maxMediaToIncludeInMemory
7659
+ }
7660
+ ... on AgentConfig_environmentOptions_Minimal {
7661
+ environment
7662
+ }
7663
+ }`;
7664
+ var agentLimitationsSelection = ` limitations {
7665
+ maxDurationSeconds
7666
+ maxToolCalls
7667
+ allowedUrlRegexes
7668
+ }`;
7669
+ var operationSpecs = [
7670
+ createOperationSpec({
7671
+ operationName: "GetAgents",
7672
+ kind: "query",
7673
+ inputSchema: z2.object({
7674
+ ids: z2.array(z2.string().min(1)).min(1)
7675
+ }),
7676
+ cli: {
7677
+ name: "get-agents",
7678
+ path: ["agents", "get"],
7679
+ description: "Fetch one or more agents with config and schema fields.",
7680
+ resultKey: "agents",
7681
+ options: [
7682
+ stringArrayOption({
7683
+ inputKey: "ids",
7684
+ flagName: "ids",
7685
+ description: "Agent IDs.",
7686
+ required: true
7687
+ })
7688
+ ]
7689
+ },
7690
+ mcp: { fileName: "agents.graphql" },
7691
+ document: `# Query to fetch multiple agents with all fields
7692
+ # Includes nested environment and limitation config fields
7693
+ query GetAgents($ids: [ID!]!) {
7694
+ agents(ids: $ids) {
7695
+ id
7696
+ name
7697
+ description
7698
+ instructions
7699
+ organizationId
7700
+ createdAt
7701
+ updatedAt
7702
+ sourceAgentId
7703
+ inputSchema
7704
+ outputSchema
7705
+ config {
7706
+ type
7707
+ language
7708
+ model
7709
+ tools
7710
+ maxSessionMessages
7711
+ ${agentEnvironmentOptionsSelection}
7712
+ ${agentLimitationsSelection}
7713
+ commonParametersSchema
7714
+ taskQueue
7715
+ waitUponQueueing
7716
+ queueableAgentIds
7717
+ additionalSystemPrompt
7718
+ ignoreUnstableSessionState
8304
7719
  }
8305
- if (Object.keys(serializedObject).length === 0) {
8306
- return void 0;
7720
+ childAgentIds
8307
7721
  }
8308
- return serializedObject;
8309
- }
8310
- return void 0;
8311
- }
8312
- function resolveApiDetails({ appError, statusCode }) {
8313
- if (!shouldExposeMessage({ appError, statusCode })) {
8314
- return void 0;
8315
- }
8316
- const zodIssues = getZodIssuesFromCause(appError.cause);
8317
- if (zodIssues && zodIssues.length > 0) {
8318
- return {
8319
- validationErrors: zodIssues.map((issue) => ({
8320
- path: Array.isArray(issue.path) ? issue.path.map(String).join(".") : "",
8321
- message: typeof issue.message === "string" ? issue.message : "Invalid value",
8322
- ...typeof issue.code === "string" ? { code: issue.code } : {}
8323
- }))
8324
- };
8325
- }
8326
- const rawDetails = toUserFacingDetailsValue(appError.details, 4);
8327
- if (rawDetails && typeof rawDetails === "object" && !Array.isArray(rawDetails) && Object.keys(rawDetails).length > 0) {
8328
- return rawDetails;
8329
- }
8330
- return void 0;
8331
- }
8332
- function getGraphQLErrorCodeFromAppErrorCode(code) {
8333
- if (code === 400) {
8334
- return "BAD_USER_INPUT";
8335
- }
8336
- if (code === 401) {
8337
- return "UNAUTHORIZED";
8338
- }
8339
- if (code === 403) {
8340
- return "FORBIDDEN";
8341
- }
8342
- if (code === 404) {
8343
- return "NOT_FOUND";
8344
- }
8345
- if (code === 500) {
8346
- return "INTERNAL_SERVER_ERROR";
8347
- }
8348
- return void 0;
8349
- }
8350
- function resolveGraphQLErrorCode(appError) {
8351
- const codeFromAppErrorCode = getGraphQLErrorCodeFromAppErrorCode(appError.statusCode);
8352
- if (codeFromAppErrorCode !== void 0) {
8353
- return codeFromAppErrorCode;
8354
- }
8355
- const normalizedErrorType = appError.type.toLowerCase();
8356
- if (normalizedErrorType.includes("unauthorized")) {
8357
- return "UNAUTHORIZED";
8358
- }
8359
- if (normalizedErrorType.includes("forbidden")) {
8360
- return "FORBIDDEN";
8361
- }
8362
- if (normalizedErrorType.includes("not-found")) {
8363
- return "NOT_FOUND";
7722
+ }`
7723
+ }),
7724
+ createOperationSpec({
7725
+ operationName: "GetAgentVersion",
7726
+ kind: "query",
7727
+ inputSchema: z2.object({
7728
+ agentId: z2.string().min(1),
7729
+ versionId: z2.string().min(1)
7730
+ }),
7731
+ cli: {
7732
+ name: "get-agent-version",
7733
+ path: ["agents", "versions", "get"],
7734
+ description: "Fetch one saved version for an agent.",
7735
+ resultKey: "agentVersion",
7736
+ options: [
7737
+ stringOption({
7738
+ inputKey: "agentId",
7739
+ flagName: "agent-id",
7740
+ description: "Agent ID.",
7741
+ required: true
7742
+ }),
7743
+ stringOption({
7744
+ inputKey: "versionId",
7745
+ flagName: "version-id",
7746
+ description: "Agent version ID.",
7747
+ required: true
7748
+ })
7749
+ ]
7750
+ },
7751
+ mcp: { fileName: "agentVersion.graphql" },
7752
+ document: `# Query to fetch a specific saved version for an agent
7753
+ query GetAgentVersion($agentId: ID!, $versionId: ID!) {
7754
+ agentVersion(agentId: $agentId, versionId: $versionId) {
7755
+ id
7756
+ agentId
7757
+ sequence
7758
+ name
7759
+ description
7760
+ instructions
7761
+ instructionsMode
7762
+ instructionsDoc
7763
+ updaterUserId
7764
+ createdAt
7765
+ updatedAt
7766
+ inputSchema
7767
+ outputSchema
7768
+ config {
7769
+ type
7770
+ language
7771
+ model
7772
+ tools
7773
+ maxSessionMessages
7774
+ ${agentEnvironmentOptionsSelection}
7775
+ ${agentLimitationsSelection}
7776
+ commonParametersSchema
7777
+ taskQueue
7778
+ waitUponQueueing
7779
+ queueableAgentIds
7780
+ additionalSystemPrompt
7781
+ ignoreUnstableSessionState
7782
+ }
7783
+ isCurrent
8364
7784
  }
8365
- if (isCustomerUsageError(appError)) {
8366
- return "BAD_USER_INPUT";
7785
+ }`
7786
+ }),
7787
+ createOperationSpec({
7788
+ operationName: "GetAgentVersions",
7789
+ kind: "query",
7790
+ inputSchema: z2.object({
7791
+ agentId: z2.string().min(1)
7792
+ }),
7793
+ cli: {
7794
+ name: "get-agent-versions",
7795
+ path: ["agents", "versions", "list"],
7796
+ description: "Fetch version history for an agent.",
7797
+ resultKey: "agentVersions",
7798
+ options: [
7799
+ stringOption({
7800
+ inputKey: "agentId",
7801
+ flagName: "agent-id",
7802
+ description: "Agent ID.",
7803
+ required: true
7804
+ })
7805
+ ]
7806
+ },
7807
+ mcp: { fileName: "agentVersions.graphql" },
7808
+ document: `# Query to fetch version history metadata for an agent
7809
+ query GetAgentVersions($agentId: ID!) {
7810
+ agentVersions(agentId: $agentId) {
7811
+ id
7812
+ sequence
7813
+ name
7814
+ description
7815
+ updaterUserId
7816
+ createdAt
7817
+ updatedAt
7818
+ isCurrent
8367
7819
  }
8368
- return "INTERNAL_SERVER_ERROR";
8369
- }
8370
- function getStatusCodeFromGraphQLErrorCode(code) {
8371
- switch (code) {
8372
- case "BAD_USER_INPUT": {
8373
- return 400;
8374
- }
8375
- case "UNAUTHORIZED": {
8376
- return 401;
8377
- }
8378
- case "FORBIDDEN": {
8379
- return 403;
8380
- }
8381
- case "NOT_FOUND": {
8382
- return 404;
8383
- }
8384
- case "INTERNAL_SERVER_ERROR": {
8385
- return 500;
7820
+ }`
7821
+ }),
7822
+ createOperationSpec({
7823
+ operationName: "DiffAgentVersion",
7824
+ kind: "query",
7825
+ inputSchema: z2.object({
7826
+ agentId: z2.string().min(1),
7827
+ versionId: z2.string().min(1),
7828
+ compareVersionId: z2.string().min(1).optional()
7829
+ }),
7830
+ cli: {
7831
+ name: "diff-agent-version",
7832
+ path: ["agents", "versions", "diff"],
7833
+ description: "Diff one agent version against another version or the current latest version.",
7834
+ resultKey: "agentVersionDiff",
7835
+ options: [
7836
+ stringOption({
7837
+ inputKey: "agentId",
7838
+ flagName: "agent-id",
7839
+ description: "Agent ID.",
7840
+ required: true
7841
+ }),
7842
+ stringOption({
7843
+ inputKey: "versionId",
7844
+ flagName: "version-id",
7845
+ description: "Source agent version ID.",
7846
+ required: true
7847
+ }),
7848
+ stringOption({
7849
+ inputKey: "compareVersionId",
7850
+ flagName: "compare-version-id",
7851
+ description: "Optional target version ID. Defaults to the current latest version."
7852
+ })
7853
+ ]
7854
+ },
7855
+ mcp: { fileName: "agentVersionDiff.graphql" },
7856
+ document: `# Query to diff one agent version against another or the current latest version
7857
+ query DiffAgentVersion(
7858
+ $agentId: ID!
7859
+ $versionId: ID!
7860
+ $compareVersionId: ID
7861
+ ) {
7862
+ agentVersionDiff(
7863
+ agentId: $agentId
7864
+ versionId: $versionId
7865
+ compareVersionId: $compareVersionId
7866
+ ) {
7867
+ agentId
7868
+ fromVersionId
7869
+ toVersionId
7870
+ hasChanges
7871
+ changes {
7872
+ field
7873
+ oldValue
7874
+ newValue
8386
7875
  }
8387
7876
  }
8388
- }
8389
- function getGraphQLErrorMessage({ code, apiMessage }) {
8390
- switch (code) {
8391
- case "BAD_USER_INPUT":
8392
- case "NOT_FOUND":
8393
- case "INTERNAL_SERVER_ERROR": {
8394
- return apiMessage;
8395
- }
8396
- case "UNAUTHORIZED": {
8397
- return "Unauthorized";
8398
- }
8399
- case "FORBIDDEN": {
8400
- return "Forbidden";
7877
+ }`
7878
+ }),
7879
+ createOperationSpec({
7880
+ operationName: "GetAgentRun",
7881
+ kind: "query",
7882
+ inputSchema: z2.object({
7883
+ id: z2.string().min(1)
7884
+ }),
7885
+ cli: {
7886
+ name: "get-agent-run",
7887
+ path: ["agent-runs", "get"],
7888
+ description: "Fetch a single agent run.",
7889
+ resultKey: "agentRun",
7890
+ options: [
7891
+ stringOption({
7892
+ inputKey: "id",
7893
+ flagName: "id",
7894
+ description: "Agent run ID.",
7895
+ required: true
7896
+ })
7897
+ ]
7898
+ },
7899
+ mcp: { fileName: "agentRun.graphql" },
7900
+ document: `# Query a single agent run
7901
+ query GetAgentRun($id: ID!) {
7902
+ agentRun(id: $id) {
7903
+ id
7904
+ agentVersionId
7905
+ agentName
7906
+ status
7907
+ statusDetail
7908
+ isChildAgent
7909
+ input
7910
+ startedAt
7911
+ finishedAt
7912
+ parentAgentRunId
7913
+ }
7914
+ }`
7915
+ }),
7916
+ createOperationSpec({
7917
+ operationName: "GetAutomationAgents",
7918
+ kind: "query",
7919
+ inputSchema: z2.object({
7920
+ ids: z2.array(z2.string().min(1)).min(1)
7921
+ }),
7922
+ cli: {
7923
+ name: "get-automation-agents",
7924
+ path: ["automations", "agents"],
7925
+ description: "Fetch the agents attached to one or more automations.",
7926
+ resultKey: "automationAgents",
7927
+ options: [
7928
+ stringArrayOption({
7929
+ inputKey: "ids",
7930
+ flagName: "ids",
7931
+ description: "Automation IDs.",
7932
+ required: true
7933
+ })
7934
+ ]
7935
+ },
7936
+ mcp: { fileName: "automationAgents.graphql" },
7937
+ document: `# Query automation agent relationships with flat agent fields only
7938
+ # Excludes nested agent config and schemas for MCP tool simplicity
7939
+ query GetAutomationAgents($ids: [ID!]!) {
7940
+ automationAgents(ids: $ids) {
7941
+ automationId
7942
+ agentId
7943
+ isTrigger
7944
+ agent {
7945
+ id
7946
+ name
7947
+ description
7948
+ instructions
7949
+ organizationId
7950
+ createdAt
7951
+ updatedAt
7952
+ sourceAgentId
7953
+ childAgentIds
8401
7954
  }
8402
7955
  }
8403
- }
8404
- function getGraphQLAppErrorCode({ code, apiCode }) {
8405
- if (code === "INTERNAL_SERVER_ERROR" || code === "UNAUTHORIZED" || code === "FORBIDDEN") {
8406
- return code;
8407
- }
8408
- return apiCode;
8409
- }
8410
- function normalizeErrorCodeSegment(value) {
8411
- return value.trim().toUpperCase().replaceAll(/[^\dA-Z]+/gu, "_").replaceAll(/^_+/gu, "").replaceAll(/_+$/gu, "");
8412
- }
8413
- function getStatusCodeForAppErrorFromAppError(appError) {
8414
- const statusCodeFromCode = getStatusCodeFromAppErrorCode(appError.statusCode);
8415
- if (statusCodeFromCode !== void 0) {
8416
- return statusCodeFromCode;
8417
- }
8418
- if (isCustomerUsageError(appError)) {
8419
- return 400;
8420
- }
8421
- return 500;
8422
- }
8423
- function normalizeUserFacingErrorCode({ type, fallbackCode, prefix }) {
8424
- if (!type) {
8425
- return fallbackCode;
8426
- }
8427
- const normalized = normalizeErrorCodeSegment(type);
8428
- if (normalized.length === 0) {
8429
- return fallbackCode;
7956
+ }`
7957
+ }),
7958
+ createOperationSpec({
7959
+ operationName: "GetAutomationRun",
7960
+ kind: "query",
7961
+ inputSchema: z2.object({
7962
+ id: z2.string().min(1)
7963
+ }),
7964
+ cli: {
7965
+ name: "get-automation-run",
7966
+ path: ["automation-runs", "get"],
7967
+ description: "Fetch a single automation run.",
7968
+ resultKey: "automationRun",
7969
+ options: [
7970
+ stringOption({
7971
+ inputKey: "id",
7972
+ flagName: "id",
7973
+ description: "Automation run ID.",
7974
+ required: true
7975
+ })
7976
+ ]
7977
+ },
7978
+ mcp: { fileName: "automationRun.graphql" },
7979
+ document: `# Query a full automation run details payload
7980
+ query GetAutomationRun($id: ID!) {
7981
+ automationRun(id: $id) {
7982
+ id
7983
+ automationId
7984
+ parentAutomationRunId
7985
+ status
7986
+ statusDetail
7987
+ summary
7988
+ invocationType
7989
+ input
7990
+ additionalPrompt
7991
+ debugUrl
7992
+ createdAt
7993
+ startedAt
7994
+ pausedAt
7995
+ finishedAt
8430
7996
  }
8431
- const normalizedPrefix = prefix ? normalizeErrorCodeSegment(prefix) : void 0;
8432
- if (!normalizedPrefix) {
8433
- return normalized;
7997
+ }`
7998
+ }),
7999
+ createOperationSpec({
8000
+ operationName: "GetAutomationRunAgentRuns",
8001
+ kind: "query",
8002
+ inputSchema: z2.object({
8003
+ automationRunId: z2.string().min(1)
8004
+ }),
8005
+ cli: {
8006
+ name: "get-automation-run-agent-runs",
8007
+ path: ["automation-runs", "agent-runs"],
8008
+ description: "Fetch ordered agent runs for an automation run.",
8009
+ resultKey: "automationRunAgentRuns",
8010
+ options: [
8011
+ stringOption({
8012
+ inputKey: "automationRunId",
8013
+ flagName: "automation-run-id",
8014
+ description: "Automation run ID.",
8015
+ required: true
8016
+ })
8017
+ ]
8018
+ },
8019
+ mcp: { fileName: "automationRunAgentRuns.graphql" },
8020
+ document: `# Query ordered agent runs for an automation run
8021
+ query GetAutomationRunAgentRuns($automationRunId: ID!) {
8022
+ automationRunAgentRuns(automationRunId: $automationRunId) {
8023
+ id
8024
+ agentVersionId
8025
+ agentName
8026
+ status
8027
+ statusDetail
8028
+ isChildAgent
8029
+ input
8030
+ startedAt
8031
+ finishedAt
8032
+ parentAgentRunId
8434
8033
  }
8435
- if (normalized.startsWith(`${normalizedPrefix}_`)) {
8436
- return normalized;
8034
+ }`
8035
+ }),
8036
+ createOperationSpec({
8037
+ operationName: "GetAutomationRunIterations",
8038
+ kind: "query",
8039
+ inputSchema: z2.object({
8040
+ automationRunId: z2.string().min(1),
8041
+ agentRunId: z2.string().min(1).optional(),
8042
+ limit: z2.number().int().positive().optional(),
8043
+ reverse: z2.boolean().optional()
8044
+ }),
8045
+ cli: {
8046
+ name: "get-automation-run-iterations",
8047
+ path: ["automation-runs", "iterations"],
8048
+ description: "Fetch ordered iterations for an automation run.",
8049
+ resultKey: "automationRunIterations",
8050
+ options: [
8051
+ stringOption({
8052
+ inputKey: "automationRunId",
8053
+ flagName: "automation-run-id",
8054
+ description: "Automation run ID.",
8055
+ required: true
8056
+ }),
8057
+ stringOption({
8058
+ inputKey: "agentRunId",
8059
+ flagName: "agent-run-id",
8060
+ description: "Optional agent run ID to filter by."
8061
+ }),
8062
+ numberOption({
8063
+ inputKey: "limit",
8064
+ flagName: "limit",
8065
+ description: "Maximum number of iterations to return."
8066
+ }),
8067
+ booleanOption({
8068
+ inputKey: "reverse",
8069
+ flagName: "reverse",
8070
+ description: "Return newest iterations first."
8071
+ })
8072
+ ]
8073
+ },
8074
+ mcp: { fileName: "automationRunIterations.graphql" },
8075
+ document: `# Query iterations for an automation run with optional filtering by agent run
8076
+ query GetAutomationRunIterations(
8077
+ $automationRunId: ID!
8078
+ $agentRunId: ID
8079
+ $limit: Int
8080
+ $reverse: Boolean
8081
+ ) {
8082
+ automationRunIterations(
8083
+ automationRunId: $automationRunId
8084
+ agentRunId: $agentRunId
8085
+ limit: $limit
8086
+ reverse: $reverse
8087
+ ) {
8088
+ id
8089
+ sequence
8090
+ agentRunId
8091
+ metadata
8092
+ startedAt
8093
+ finishedAt
8094
+ totalDurationMs
8095
+ llmResponseDurationMs
8096
+ withMarksScreenshotUrl
8097
+ withMarksMimeType
8098
+ memories {
8099
+ id
8100
+ type
8101
+ value
8102
+ sequence
8103
+ screenshotUrl
8104
+ screenshotMimeType
8105
+ }
8437
8106
  }
8438
- return `${normalizedPrefix}_${normalized}`;
8439
- }
8440
- function toUserFacingApiErrorFromAppError({ appError, correlationId, statusCode }) {
8441
- const resolvedStatusCode = statusCode ?? getStatusCodeForAppErrorFromAppError(appError);
8442
- const message = resolveApiMessage({
8443
- appError,
8444
- statusCode: resolvedStatusCode
8445
- });
8446
- const suggestedAction = resolveSuggestedAction({
8447
- appError,
8448
- statusCode: resolvedStatusCode
8449
- });
8450
- const details = resolveApiDetails({
8451
- appError,
8452
- statusCode: resolvedStatusCode
8453
- });
8454
- return {
8455
- code: resolveApiErrorCode({
8456
- appError,
8457
- statusCode: resolvedStatusCode
8107
+ }`
8108
+ }),
8109
+ createOperationSpec({
8110
+ operationName: "GetAutomationRuns",
8111
+ kind: "query",
8112
+ inputSchema: z2.object({
8113
+ automationId: z2.string().min(1),
8114
+ status: z2.array(z2.string().min(1)).optional(),
8115
+ invocationType: z2.array(z2.string().min(1)).optional(),
8116
+ limit: z2.number().int().positive().optional(),
8117
+ page: z2.number().int().positive().optional()
8118
+ }),
8119
+ cli: {
8120
+ name: "get-automation-runs",
8121
+ path: ["automation-runs", "list"],
8122
+ description: "Fetch automation run history.",
8123
+ resultKey: "automationRuns",
8124
+ options: [
8125
+ stringOption({
8126
+ inputKey: "automationId",
8127
+ flagName: "automation-id",
8128
+ description: "Automation ID.",
8129
+ required: true
8130
+ }),
8131
+ stringArrayOption({
8132
+ inputKey: "status",
8133
+ flagName: "status",
8134
+ description: "Optional run statuses."
8135
+ }),
8136
+ stringArrayOption({
8137
+ inputKey: "invocationType",
8138
+ flagName: "invocation-type",
8139
+ description: "Optional invocation types."
8140
+ }),
8141
+ numberOption({
8142
+ inputKey: "limit",
8143
+ flagName: "limit",
8144
+ description: "Maximum number of runs to return."
8145
+ }),
8146
+ numberOption({
8147
+ inputKey: "page",
8148
+ flagName: "page",
8149
+ description: "Page number."
8150
+ })
8151
+ ]
8152
+ },
8153
+ mcp: { fileName: "automationRuns.graphql" },
8154
+ document: `# Query automation run history for a specific automation with optional filters
8155
+ query GetAutomationRuns(
8156
+ $automationId: ID!
8157
+ $status: [RunStatus!]
8158
+ $invocationType: [InvocationType!]
8159
+ $limit: Int
8160
+ $page: Int
8161
+ ) {
8162
+ automationRuns(
8163
+ automationId: $automationId
8164
+ status: $status
8165
+ invocationType: $invocationType
8166
+ limit: $limit
8167
+ page: $page
8168
+ ) {
8169
+ id
8170
+ automationId
8171
+ parentAutomationRunId
8172
+ status
8173
+ statusDetail
8174
+ invocationType
8175
+ summary
8176
+ createdAt
8177
+ startedAt
8178
+ pausedAt
8179
+ finishedAt
8180
+ }
8181
+ }`
8182
+ }),
8183
+ createOperationSpec({
8184
+ operationName: "ListAutomations",
8185
+ kind: "query",
8186
+ inputSchema: z2.object({
8187
+ limit: z2.number().positive().optional(),
8188
+ order: jsonObjectSchema.optional(),
8189
+ where: jsonObjectSchema.optional()
8458
8190
  }),
8459
- message,
8460
- correlationId,
8461
- suggestedAction,
8462
- ...details ? { details } : {}
8463
- };
8464
- }
8465
- function toUserFacingGraphQLErrorFromAppError({ appError, correlationId }) {
8466
- const code = resolveGraphQLErrorCode(appError);
8467
- const statusCode = getStatusCodeFromGraphQLErrorCode(code);
8468
- const apiError = toUserFacingApiErrorFromAppError({
8469
- appError,
8470
- correlationId,
8471
- statusCode
8472
- });
8473
- return {
8474
- code,
8475
- errorCode: getGraphQLAppErrorCode({ code, apiCode: apiError.code }),
8476
- message: getGraphQLErrorMessage({ code, apiMessage: apiError.message }),
8477
- correlationId
8478
- };
8479
- }
8480
-
8481
- // ../common/dist/src/stdlib/error.js
8482
- var INTERNAL_STACK_PATHS = [
8483
- "/src/stdlib/result.util.ts",
8484
- "/src/stdlib/error.ts"
8485
- ];
8486
- function stripInternalFrames(stack, internalFrames) {
8487
- const lines = stack.split("\n");
8488
- return lines.filter((line) => !internalFrames.some((internalFrame) => line.includes(internalFrame)));
8489
- }
8490
- var ORDERED_APP_ERROR_CATEGORIES = [
8491
- "internal_platform",
8492
- "customer_usage",
8493
- "third_party"
8494
- ];
8495
- function isAppErrorCategory(category) {
8496
- return typeof category === "string" && // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
8497
- ORDERED_APP_ERROR_CATEGORIES.includes(category);
8498
- }
8499
- function isNonEmptyAppErrorCategoryArray(categories) {
8500
- return Array.isArray(categories) && categories.length > 0 && categories.every(isAppErrorCategory);
8501
- }
8502
- var APP_ERROR_SEVERITIES = ["warn", "error", "fatal"];
8503
- function isAppErrorCode(code) {
8504
- return typeof code === "number" && Number.isInteger(code) && code >= 400 && code <= 599;
8505
- }
8506
- function isAppErrorSeverity(severity) {
8507
- return typeof severity === "string" && // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
8508
- APP_ERROR_SEVERITIES.includes(severity);
8509
- }
8510
- var AppError = class _AppError extends Error {
8511
- type;
8512
- categories;
8513
- severity;
8514
- statusCode;
8515
- suggestedAction;
8516
- nonRetryable;
8517
- details;
8518
- constructor({ type, categories, severity, statusCode, code, message, suggestedAction, cause, nonRetryable, stack, internalFrames, ...details }) {
8519
- super(_AppError.resolveMessage(message, cause, type), { cause });
8520
- this.type = type;
8521
- this.name = type;
8522
- this.details = details;
8523
- this.categories = categories ?? _AppError.extractCategoriesFromCause(cause);
8524
- this.severity = severity ?? _AppError.extractSeverityFromCause(cause);
8525
- this.statusCode = statusCode ?? code ?? _AppError.extractStatusCodeFromCause(cause);
8526
- this.suggestedAction = suggestedAction ?? _AppError.extractSuggestedActionFromCause(cause);
8527
- this.nonRetryable = nonRetryable ?? false;
8528
- _AppError.applyStack(this, stack, internalFrames);
8191
+ cli: {
8192
+ name: "list-automations",
8193
+ path: ["automations", "list"],
8194
+ description: "List automations with optional filters.",
8195
+ resultKey: "automations",
8196
+ options: [
8197
+ numberOption({
8198
+ inputKey: "limit",
8199
+ flagName: "limit",
8200
+ description: "Maximum number of automations to return."
8201
+ }),
8202
+ jsonOption({
8203
+ inputKey: "order",
8204
+ flagName: "order-json",
8205
+ description: "GraphQL order object."
8206
+ }),
8207
+ jsonOption({
8208
+ inputKey: "where",
8209
+ flagName: "where-json",
8210
+ description: "GraphQL filter object."
8211
+ })
8212
+ ]
8213
+ },
8214
+ mcp: { fileName: "listAutomations.graphql" },
8215
+ document: `# Query to list automations with flat fields only (no nested objects)
8216
+ # Excludes config and agents for MCP tool simplicity
8217
+ query ListAutomations(
8218
+ $limit: Float
8219
+ $order: AutomationsOrder
8220
+ $where: AutomationsWhereInput
8221
+ ) {
8222
+ automations(limit: $limit, order: $order, where: $where) {
8223
+ id
8224
+ name
8225
+ organizationId
8226
+ createdAt
8227
+ updatedAt
8228
+ environment
8229
+ lastSavedAt
8230
+ publishedVersionId
8231
+ draftVersionId
8529
8232
  }
8530
- static resolveMessage(message, cause, type) {
8531
- if (message) {
8532
- return message;
8533
- }
8534
- if (cause instanceof Error) {
8535
- return cause.message;
8536
- }
8537
- return type;
8233
+ }`
8234
+ }),
8235
+ createOperationSpec({
8236
+ operationName: "GetAutomations",
8237
+ kind: "query",
8238
+ inputSchema: z2.object({
8239
+ ids: z2.array(z2.string().min(1)).min(1)
8240
+ }),
8241
+ cli: {
8242
+ name: "get-automations",
8243
+ path: ["automations", "get"],
8244
+ description: "Fetch one or more automations by IDs.",
8245
+ resultKey: "automations",
8246
+ options: [
8247
+ stringArrayOption({
8248
+ inputKey: "ids",
8249
+ flagName: "ids",
8250
+ description: "Automation IDs.",
8251
+ required: true
8252
+ })
8253
+ ]
8254
+ },
8255
+ mcp: { fileName: "automations.graphql" },
8256
+ document: `# Query to fetch automations with flat fields only (no nested objects)
8257
+ # Excludes config and agents for MCP tool simplicity
8258
+ query GetAutomations($ids: [ID!]!) {
8259
+ automations(ids: $ids) {
8260
+ id
8261
+ name
8262
+ organizationId
8263
+ createdAt
8264
+ updatedAt
8265
+ environment
8266
+ lastSavedAt
8267
+ publishedVersionId
8268
+ draftVersionId
8538
8269
  }
8539
- static getInheritedCauseField(cause, extractor, seen = /* @__PURE__ */ new Set()) {
8540
- if (!cause || typeof cause !== "object" || seen.has(cause)) {
8541
- return void 0;
8542
- }
8543
- const causeRecord = cause;
8544
- const extractedValue = extractor(causeRecord);
8545
- if (extractedValue !== void 0) {
8546
- return extractedValue;
8547
- }
8548
- return _AppError.getInheritedCauseField(causeRecord["cause"], extractor, new Set(seen).add(cause));
8270
+ }`
8271
+ }),
8272
+ createOperationSpec({
8273
+ operationName: "GetAvailableCommands",
8274
+ kind: "query",
8275
+ inputSchema: z2.object({
8276
+ env: z2.string().min(1)
8277
+ }),
8278
+ cli: {
8279
+ name: "get-available-commands",
8280
+ path: ["catalog", "commands"],
8281
+ description: "Fetch available command definitions by environment.",
8282
+ resultKey: "availableCommands",
8283
+ options: [
8284
+ stringOption({
8285
+ inputKey: "env",
8286
+ flagName: "env",
8287
+ description: "Environment name.",
8288
+ required: true
8289
+ })
8290
+ ]
8291
+ },
8292
+ mcp: { fileName: "availableCommands.graphql" },
8293
+ document: `# Query to fetch available command definitions by environment
8294
+ query GetAvailableCommands($env: AvailableCommandsEnv!) {
8295
+ availableCommands(env: $env) {
8296
+ id
8297
+ description
8298
+ inputSchema
8549
8299
  }
8550
- static extractCategoriesFromCause(cause) {
8551
- return _AppError.getInheritedCauseField(cause, (causeRecord) => {
8552
- const { categories } = causeRecord;
8553
- if (isNonEmptyAppErrorCategoryArray(categories)) {
8554
- return categories;
8300
+ }`
8301
+ }),
8302
+ createOperationSpec({
8303
+ operationName: "GetAvailableModels",
8304
+ kind: "query",
8305
+ inputSchema: z2.object({
8306
+ agentId: z2.string().min(1)
8307
+ }),
8308
+ cli: {
8309
+ name: "get-available-models",
8310
+ path: ["catalog", "models"],
8311
+ description: "Fetch available model definitions for an agent.",
8312
+ resultKey: "availableModels",
8313
+ options: [
8314
+ stringOption({
8315
+ inputKey: "agentId",
8316
+ flagName: "agent-id",
8317
+ description: "Agent ID.",
8318
+ required: true
8319
+ })
8320
+ ]
8321
+ },
8322
+ mcp: { fileName: "availableModels.graphql" },
8323
+ document: `# Query to fetch available model definitions and pools for a specific agent
8324
+ query GetAvailableModels($agentId: String!) {
8325
+ availableModels(agentId: $agentId) {
8326
+ availableModelPools {
8327
+ name
8328
+ poolId
8329
+ models {
8330
+ id
8331
+ name
8332
+ description
8333
+ status
8334
+ provider
8555
8335
  }
8556
- return void 0;
8557
- }) ?? ["internal_platform"];
8336
+ }
8337
+ allAvailableModels {
8338
+ id
8339
+ name
8340
+ description
8341
+ status
8342
+ provider
8343
+ }
8558
8344
  }
8559
- static extractSeverityFromCause(cause) {
8560
- return _AppError.getInheritedCauseField(cause, (causeRecord) => {
8561
- const { severity } = causeRecord;
8562
- return isAppErrorSeverity(severity) ? severity : void 0;
8563
- }) ?? "error";
8345
+ }`
8346
+ }),
8347
+ createOperationSpec({
8348
+ operationName: "GetAvailableTools",
8349
+ kind: "query",
8350
+ inputSchema: z2.object({
8351
+ env: z2.string().min(1),
8352
+ automationId: z2.string().min(1).optional()
8353
+ }),
8354
+ cli: {
8355
+ name: "get-available-tools",
8356
+ path: ["catalog", "tools"],
8357
+ description: "Fetch available tool definitions by environment.",
8358
+ resultKey: "availableTools",
8359
+ options: [
8360
+ stringOption({
8361
+ inputKey: "env",
8362
+ flagName: "env",
8363
+ description: "Environment name.",
8364
+ required: true
8365
+ }),
8366
+ stringOption({
8367
+ inputKey: "automationId",
8368
+ flagName: "automation-id",
8369
+ description: "Optional automation ID."
8370
+ })
8371
+ ]
8372
+ },
8373
+ mcp: { fileName: "availableTools.graphql" },
8374
+ document: `# Query to fetch available tool definitions by environment
8375
+ query GetAvailableTools($env: AvailableCommandsEnv!, $automationId: String) {
8376
+ availableTools(env: $env, automationId: $automationId) {
8377
+ id
8378
+ description
8379
+ inputSchema
8564
8380
  }
8565
- static extractStatusCodeFromCause(cause) {
8566
- return _AppError.getInheritedCauseField(cause, (causeRecord) => {
8567
- const { statusCode } = causeRecord;
8568
- if (isAppErrorCode(statusCode)) {
8569
- return statusCode;
8570
- }
8571
- const { code: legacyCode } = causeRecord;
8572
- return isAppErrorCode(legacyCode) ? legacyCode : void 0;
8573
- });
8381
+ }`
8382
+ }),
8383
+ createOperationSpec({
8384
+ operationName: "CreateAutomation",
8385
+ kind: "mutation",
8386
+ inputSchema: z2.object({
8387
+ input: jsonObjectSchema
8388
+ }),
8389
+ cli: {
8390
+ name: "create-automation",
8391
+ path: ["automations", "create"],
8392
+ description: "Create a draft automation.",
8393
+ resultKey: "createAutomation",
8394
+ options: [
8395
+ jsonOption({
8396
+ inputKey: "input",
8397
+ flagName: "input-json",
8398
+ description: "CreateAutomationInput payload.",
8399
+ required: true
8400
+ })
8401
+ ]
8402
+ },
8403
+ mcp: { fileName: "createAutomation.graphql" },
8404
+ document: `# Mutation to create a draft automation with optional initial values
8405
+ # Returns flat fields only for MCP tool simplicity
8406
+ mutation CreateAutomation($input: CreateAutomationInput!) {
8407
+ createAutomation(input: $input) {
8408
+ id
8409
+ name
8410
+ organizationId
8411
+ createdAt
8412
+ updatedAt
8413
+ environment
8414
+ lastSavedAt
8415
+ publishedVersionId
8416
+ draftVersionId
8574
8417
  }
8575
- /** @deprecated Use statusCode instead. */
8576
- get code() {
8577
- return this.statusCode;
8418
+ }`
8419
+ }),
8420
+ createOperationSpec({
8421
+ operationName: "GetGraphqlSchema",
8422
+ kind: "query",
8423
+ inputSchema: z2.object({}),
8424
+ cli: {
8425
+ name: "get-graphql-schema",
8426
+ path: ["graphql", "schema"],
8427
+ description: "Fetch GraphQL schema metadata.",
8428
+ resultKey: "graphqlSchema",
8429
+ options: []
8430
+ },
8431
+ mcp: { fileName: "graphqlSchema.graphql" },
8432
+ document: `# Query to fetch full GraphQL schema metadata.
8433
+ # Uses the first-class graphqlSchema query field to avoid __schema validation
8434
+ # issues in MCP tool-load paths while still returning introspection JSON.
8435
+ # Response can be large: call sparingly (typically once per task/session) and
8436
+ # reuse cached results.
8437
+ query GetGraphqlSchema {
8438
+ graphqlSchema
8439
+ }`
8440
+ }),
8441
+ createOperationSpec({
8442
+ operationName: "PauseAutomationRun",
8443
+ kind: "mutation",
8444
+ inputSchema: z2.object({
8445
+ automationRunId: z2.string().min(1)
8446
+ }),
8447
+ cli: {
8448
+ name: "pause-automation-run",
8449
+ path: ["automation-runs", "pause"],
8450
+ description: "Pause an automation run.",
8451
+ resultKey: "pauseAutomationRun",
8452
+ options: [
8453
+ stringOption({
8454
+ inputKey: "automationRunId",
8455
+ flagName: "automation-run-id",
8456
+ description: "Automation run ID.",
8457
+ required: true
8458
+ })
8459
+ ]
8460
+ },
8461
+ mcp: { fileName: "pauseAutomationRun.graphql" },
8462
+ document: `# Mutation to pause an automation run
8463
+ mutation PauseAutomationRun($automationRunId: ID!) {
8464
+ pauseAutomationRun(automationRunId: $automationRunId)
8465
+ }`
8466
+ }),
8467
+ createOperationSpec({
8468
+ operationName: "RerunAutomation",
8469
+ kind: "mutation",
8470
+ inputSchema: z2.object({
8471
+ automationRunId: z2.string().min(1),
8472
+ additionalPrompt: z2.string().min(1).optional(),
8473
+ idempotencyKey: z2.string().min(1)
8474
+ }),
8475
+ cli: {
8476
+ name: "rerun-automation",
8477
+ path: ["automation-runs", "rerun"],
8478
+ description: "Rerun an existing automation run.",
8479
+ resultKey: "rerunAutomation",
8480
+ options: [
8481
+ stringOption({
8482
+ inputKey: "automationRunId",
8483
+ flagName: "automation-run-id",
8484
+ description: "Automation run ID.",
8485
+ required: true
8486
+ }),
8487
+ stringOption({
8488
+ inputKey: "additionalPrompt",
8489
+ flagName: "additional-prompt",
8490
+ description: "Optional prompt appended to the rerun."
8491
+ }),
8492
+ stringOption({
8493
+ inputKey: "idempotencyKey",
8494
+ flagName: "idempotency-key",
8495
+ description: "Idempotency key for the rerun request.",
8496
+ required: true
8497
+ })
8498
+ ]
8499
+ },
8500
+ mcp: { fileName: "rerunAutomation.graphql" },
8501
+ document: `# Mutation to rerun an existing automation run
8502
+ mutation RerunAutomation(
8503
+ $automationRunId: ID!
8504
+ $additionalPrompt: String
8505
+ $idempotencyKey: String!
8506
+ ) {
8507
+ rerunAutomation(
8508
+ automationRunId: $automationRunId
8509
+ additionalPrompt: $additionalPrompt
8510
+ idempotencyKey: $idempotencyKey
8511
+ ) {
8512
+ automationRunId
8513
+ workflowId
8514
+ workflowRunId
8515
+ }
8516
+ }`
8517
+ }),
8518
+ createOperationSpec({
8519
+ operationName: "ResumeAutomationRun",
8520
+ kind: "mutation",
8521
+ inputSchema: z2.object({
8522
+ automationRunId: z2.string().min(1),
8523
+ message: z2.string().min(1).optional()
8524
+ }),
8525
+ cli: {
8526
+ name: "resume-automation-run",
8527
+ path: ["automation-runs", "resume"],
8528
+ description: "Resume a paused automation run.",
8529
+ resultKey: "resumeAutomationRun",
8530
+ options: [
8531
+ stringOption({
8532
+ inputKey: "automationRunId",
8533
+ flagName: "automation-run-id",
8534
+ description: "Automation run ID.",
8535
+ required: true
8536
+ }),
8537
+ stringOption({
8538
+ inputKey: "message",
8539
+ flagName: "message",
8540
+ description: "Optional resume message."
8541
+ })
8542
+ ]
8543
+ },
8544
+ mcp: { fileName: "resumeAutomationRun.graphql" },
8545
+ document: `# Mutation to resume an automation run
8546
+ mutation ResumeAutomationRun($automationRunId: ID!, $message: String) {
8547
+ resumeAutomationRun(automationRunId: $automationRunId, message: $message)
8548
+ }`
8549
+ }),
8550
+ createOperationSpec({
8551
+ operationName: "RunDraftAutomation",
8552
+ kind: "mutation",
8553
+ inputSchema: z2.object({
8554
+ draftAutomationId: z2.string().min(1),
8555
+ agentId: z2.string().min(1),
8556
+ idempotencyKey: z2.string().min(1),
8557
+ input: z2.unknown().optional(),
8558
+ additionalPrompt: z2.string().min(1).optional()
8559
+ }),
8560
+ cli: {
8561
+ name: "run-draft-automation",
8562
+ path: ["automations", "run-draft"],
8563
+ description: "Run a draft automation with an explicit trigger agent.",
8564
+ resultKey: "runDraftAutomation",
8565
+ options: [
8566
+ stringOption({
8567
+ inputKey: "draftAutomationId",
8568
+ flagName: "draft-automation-id",
8569
+ description: "Draft automation ID.",
8570
+ required: true
8571
+ }),
8572
+ stringOption({
8573
+ inputKey: "agentId",
8574
+ flagName: "agent-id",
8575
+ description: "Trigger agent ID.",
8576
+ required: true
8577
+ }),
8578
+ stringOption({
8579
+ inputKey: "idempotencyKey",
8580
+ flagName: "idempotency-key",
8581
+ description: "Idempotency key for the run request.",
8582
+ required: true
8583
+ }),
8584
+ jsonOption({
8585
+ inputKey: "input",
8586
+ flagName: "input-json",
8587
+ description: "Optional JSON input payload."
8588
+ }),
8589
+ stringOption({
8590
+ inputKey: "additionalPrompt",
8591
+ flagName: "additional-prompt",
8592
+ description: "Optional prompt appended to the run."
8593
+ })
8594
+ ]
8595
+ },
8596
+ mcp: { fileName: "runDraftAutomation.graphql" },
8597
+ document: `# Mutation to run a draft automation with an explicit agent.
8598
+ # \`draftAutomationId\` is the draft automation entity ID (\`Automation.id\`), not \`draftVersionId\`.
8599
+ mutation RunDraftAutomation(
8600
+ $draftAutomationId: ID!
8601
+ $agentId: ID!
8602
+ $idempotencyKey: String!
8603
+ $input: JSON
8604
+ $additionalPrompt: String
8605
+ ) {
8606
+ runDraftAutomation(
8607
+ draftAutomationId: $draftAutomationId
8608
+ agentId: $agentId
8609
+ idempotencyKey: $idempotencyKey
8610
+ input: $input
8611
+ additionalPrompt: $additionalPrompt
8612
+ ) {
8613
+ automationRunId
8614
+ workflowId
8615
+ workflowRunId
8578
8616
  }
8579
- static extractSuggestedActionFromCause(cause) {
8580
- return _AppError.getInheritedCauseField(cause, (causeRecord) => {
8581
- const { suggestedAction } = causeRecord;
8582
- if (typeof suggestedAction !== "string") {
8583
- return void 0;
8584
- }
8585
- const trimmedSuggestedAction = suggestedAction.trim();
8586
- return trimmedSuggestedAction.length > 0 ? trimmedSuggestedAction : void 0;
8587
- });
8617
+ }`
8618
+ }),
8619
+ createOperationSpec({
8620
+ operationName: "StopAutomationRun",
8621
+ kind: "mutation",
8622
+ inputSchema: z2.object({
8623
+ automationRunId: z2.string().min(1)
8624
+ }),
8625
+ cli: {
8626
+ name: "stop-automation-run",
8627
+ path: ["automation-runs", "stop"],
8628
+ description: "Stop an automation run.",
8629
+ resultKey: "stopAutomationRun",
8630
+ options: [
8631
+ stringOption({
8632
+ inputKey: "automationRunId",
8633
+ flagName: "automation-run-id",
8634
+ description: "Automation run ID.",
8635
+ required: true
8636
+ })
8637
+ ]
8638
+ },
8639
+ mcp: { fileName: "stopAutomationRun.graphql" },
8640
+ document: `# Mutation to stop an automation run
8641
+ mutation StopAutomationRun($automationRunId: ID!) {
8642
+ stopAutomationRun(automationRunId: $automationRunId)
8643
+ }`
8644
+ }),
8645
+ createOperationSpec({
8646
+ operationName: "UpdateAutomationById",
8647
+ kind: "mutation",
8648
+ inputSchema: z2.object({
8649
+ id: z2.string().min(1),
8650
+ input: jsonObjectSchema
8651
+ }),
8652
+ cli: {
8653
+ name: "update-automation-by-id",
8654
+ path: ["automations", "update"],
8655
+ description: "Update an automation.",
8656
+ resultKey: "updateAutomation",
8657
+ options: [
8658
+ stringOption({
8659
+ inputKey: "id",
8660
+ flagName: "id",
8661
+ description: "Automation ID.",
8662
+ required: true
8663
+ }),
8664
+ jsonOption({
8665
+ inputKey: "input",
8666
+ flagName: "input-json",
8667
+ description: "UpdateAutomationInput payload.",
8668
+ required: true
8669
+ })
8670
+ ]
8671
+ },
8672
+ mcp: { fileName: "updateAutomation.graphql" },
8673
+ document: `# Mutation to update an automation
8674
+ # Returns only id and lastSavedAt for MCP tool simplicity
8675
+ mutation UpdateAutomationById($id: ID!, $input: UpdateAutomationInput!) {
8676
+ updateAutomation(id: $id, input: $input) {
8677
+ id
8678
+ lastSavedAt
8588
8679
  }
8589
- static applyStack(error, stack, internalFrames) {
8590
- if (stack) {
8591
- error.stack = stack;
8592
- }
8593
- error.stack &&= stripInternalFrames(error.stack, [
8594
- ...INTERNAL_STACK_PATHS,
8595
- ...internalFrames ?? []
8596
- ]).join("\n");
8680
+ }`
8681
+ })
8682
+ ];
8683
+
8684
+ // src/program.ts
8685
+ import { Command as Command2, InvalidArgumentError as InvalidArgumentError2, Option as Option2 } from "commander";
8686
+
8687
+ // src/api.ts
8688
+ import { z as z3 } from "zod";
8689
+ var workosOrganizationsResponseSchema = z3.object({
8690
+ organizations: z3.array(
8691
+ z3.object({
8692
+ id: z3.string().min(1),
8693
+ name: z3.string().min(1),
8694
+ primaryDomain: z3.string().nullable().optional()
8695
+ })
8696
+ ),
8697
+ success: z3.boolean()
8698
+ });
8699
+ var workosUserSchema = z3.object({
8700
+ email: z3.string().nullable(),
8701
+ id: z3.string().min(1)
8702
+ });
8703
+ var nangoIntegrationWireSchema = z3.object({
8704
+ // eslint-disable-next-line @typescript-eslint/naming-convention -- mirrors Nango REST payload
8705
+ unique_key: z3.string().min(1)
8706
+ }).passthrough().transform((data) => ({
8707
+ ...data,
8708
+ uniqueKey: data.unique_key
8709
+ }));
8710
+ var nangoIntegrationsResponseSchema = z3.array(nangoIntegrationWireSchema);
8711
+ var organizationAuthenticationSchema = z3.object({
8712
+ id: z3.string().min(1),
8713
+ type: z3.string().min(1),
8714
+ connectionId: z3.string().nullable().optional(),
8715
+ providerConfigKey: z3.string().nullable().optional(),
8716
+ description: z3.string().nullable().optional(),
8717
+ hostname: z3.string().nullable().optional()
8718
+ }).passthrough();
8719
+ var organizationAuthenticationsResponseSchema = z3.object({
8720
+ authentications: z3.array(organizationAuthenticationSchema),
8721
+ success: z3.boolean()
8722
+ });
8723
+ var graphQlResponseSchema = z3.object({
8724
+ data: z3.record(z3.string(), z3.unknown()).optional(),
8725
+ errors: z3.array(
8726
+ z3.object({
8727
+ message: z3.string().min(1)
8728
+ })
8729
+ ).optional()
8730
+ });
8731
+ var apiErrorResponseSchema = z3.object({
8732
+ errors: z3.array(
8733
+ z3.object({
8734
+ message: z3.string().min(1)
8735
+ })
8736
+ ).optional(),
8737
+ message: z3.string().min(1).optional()
8738
+ });
8739
+ function getApiErrorDetail(responseBody) {
8740
+ const parsedResponse = apiErrorResponseSchema.safeParse(responseBody);
8741
+ if (!parsedResponse.success) {
8742
+ return null;
8597
8743
  }
8598
- toApiError({ correlationId }) {
8599
- return toUserFacingApiError({
8600
- error: this,
8601
- correlationId,
8602
- statusCode: getStatusCodeForAppError(this)
8603
- });
8744
+ if (parsedResponse.data.message) {
8745
+ return parsedResponse.data.message;
8604
8746
  }
8605
- toGqlError({ correlationId }) {
8606
- return toUserFacingGraphQLError({
8607
- error: this,
8608
- correlationId
8609
- });
8747
+ if (!parsedResponse.data.errors || parsedResponse.data.errors.length === 0) {
8748
+ return null;
8610
8749
  }
8611
- };
8612
- function toAppError(error) {
8613
- return error instanceof AppError ? error : new AppError(error);
8614
- }
8615
- function getStatusCodeForAppError(error) {
8616
- const appError = toAppError(error);
8617
- return getStatusCodeForAppErrorFromAppError(appError);
8618
- }
8619
- function toUserFacingApiError({ error, correlationId, statusCode }) {
8620
- const appError = toAppError(error);
8621
- return toUserFacingApiErrorFromAppError({
8622
- appError,
8623
- correlationId,
8624
- statusCode
8625
- });
8750
+ return parsedResponse.data.errors.map((error) => error.message).join("\n");
8626
8751
  }
8627
- function toUserFacingGraphQLError({ error, correlationId }) {
8628
- const appError = toAppError(error);
8629
- return toUserFacingGraphQLErrorFromAppError({
8630
- appError,
8631
- correlationId
8632
- });
8752
+ function trimTrailingSlash(value) {
8753
+ return value.replace(/\/+$/u, "");
8633
8754
  }
8634
-
8635
- // ../common/dist/src/stdlib/result.util.js
8636
- var Result;
8637
- (function(Result2) {
8638
- function partition(responses) {
8639
- const oks = responses.filter((resp) => resp._tag === "Ok").map((resp) => resp.value);
8640
- const errs = responses.filter((resp) => resp._tag === "Err").map((resp) => resp.error);
8641
- return [oks, errs];
8642
- }
8643
- Result2.partition = partition;
8644
- async function promiseAllAndPartition(promises) {
8645
- const results = await Promise.all(promises);
8646
- return partition(results);
8647
- }
8648
- Result2.promiseAllAndPartition = promiseAllAndPartition;
8649
- function unwrapOrThrow(result) {
8650
- if (isErr(result)) {
8651
- throw result.error;
8755
+ function createMagicalApiClient({
8756
+ apiBaseUrl,
8757
+ fetchFn = fetch
8758
+ }) {
8759
+ const resolveApiBaseUrl = typeof apiBaseUrl === "string" ? () => apiBaseUrl : apiBaseUrl;
8760
+ async function fetchJson({
8761
+ accessToken,
8762
+ path: path7,
8763
+ init
8764
+ }) {
8765
+ const url = `${trimTrailingSlash(await resolveApiBaseUrl())}${path7}`;
8766
+ const headers = new Headers(init?.headers);
8767
+ headers.set("authorization", `Bearer ${accessToken}`);
8768
+ const response = await fetchFn(url, {
8769
+ ...init,
8770
+ headers
8771
+ }).catch((error) => {
8772
+ throw new CliError(
8773
+ `Failed to reach Magical API at ${url}. Check your configured base URL and make sure service-main is running.`,
8774
+ { cause: error }
8775
+ );
8776
+ });
8777
+ const responseBody = await response.json().catch((error) => {
8778
+ if (!response.ok) {
8779
+ throw new CliError(
8780
+ `Magical API request to ${url} failed with status ${response.status}.`,
8781
+ {
8782
+ cause: error
8783
+ }
8784
+ );
8785
+ }
8786
+ throw new CliError(
8787
+ `Magical API returned a non-JSON response for ${url}.`,
8788
+ {
8789
+ cause: error
8790
+ }
8791
+ );
8792
+ });
8793
+ if (!response.ok) {
8794
+ const errorDetail = getApiErrorDetail(responseBody);
8795
+ throw new CliError(
8796
+ `Magical API request to ${url} failed with status ${response.status}${errorDetail ? `: ${errorDetail}` : "."}`
8797
+ );
8652
8798
  }
8653
- return result.value;
8799
+ return responseBody;
8654
8800
  }
8655
- Result2.unwrapOrThrow = unwrapOrThrow;
8656
- async function all(promises) {
8657
- const results = await fromThrowable(async () => Promise.all(promises.map(async (promise) => {
8658
- const result = await promise;
8659
- if (isErr(result)) {
8660
- throw result.error;
8801
+ return {
8802
+ async executeGraphQl({
8803
+ accessToken,
8804
+ query,
8805
+ resultKey,
8806
+ variables
8807
+ }) {
8808
+ const headers = new Headers();
8809
+ headers.set("content-type", "application/json");
8810
+ const parsedResponse = graphQlResponseSchema.safeParse(
8811
+ await fetchJson({
8812
+ accessToken,
8813
+ path: "/graphql",
8814
+ init: {
8815
+ method: "POST",
8816
+ headers,
8817
+ body: JSON.stringify({
8818
+ query,
8819
+ variables
8820
+ })
8821
+ }
8822
+ })
8823
+ );
8824
+ if (!parsedResponse.success) {
8825
+ throw new CliError("GraphQL response payload was invalid.");
8826
+ }
8827
+ if (parsedResponse.data.errors && parsedResponse.data.errors.length > 0) {
8828
+ throw new CliError(
8829
+ parsedResponse.data.errors.map((error) => error.message).join("\n")
8830
+ );
8831
+ }
8832
+ return parsedResponse.data.data?.[resultKey] ?? null;
8833
+ },
8834
+ async fetchOrganizations({ accessToken }) {
8835
+ const parsedResponse = workosOrganizationsResponseSchema.safeParse(
8836
+ await fetchJson({
8837
+ accessToken,
8838
+ path: "/workos/organizations"
8839
+ })
8840
+ );
8841
+ if (!parsedResponse.success) {
8842
+ throw new CliError("Organization list payload was invalid.");
8661
8843
  }
8662
- return result;
8663
- })), "unknown-error");
8664
- if (isErr(results)) {
8665
- return ErrFromThrowable(results.error.cause);
8666
- }
8667
- return Ok(results.value.map((r) => r.value));
8668
- }
8669
- Result2.all = all;
8670
- function andThenSync(fnFirst, ...fns) {
8671
- let result = fnFirst();
8672
- const values = [];
8673
- for (const fn of fns) {
8674
- if (isErr(result)) {
8675
- return result;
8844
+ return parsedResponse.data.organizations.map((organization) => ({
8845
+ id: organization.id,
8846
+ name: organization.name,
8847
+ primaryDomain: organization.primaryDomain ?? null
8848
+ }));
8849
+ },
8850
+ async fetchUser({
8851
+ accessToken,
8852
+ userId
8853
+ }) {
8854
+ const parsedResponse = workosUserSchema.safeParse(
8855
+ await fetchJson({
8856
+ accessToken,
8857
+ path: `/workos/user/${userId}`
8858
+ })
8859
+ );
8860
+ if (!parsedResponse.success) {
8861
+ throw new CliError("User payload was invalid.");
8676
8862
  }
8677
- values.unshift(result.value);
8678
- result = fn(...values);
8679
- }
8680
- return result;
8681
- }
8682
- Result2.andThenSync = andThenSync;
8683
- async function andThen(fnFirst, ...fns) {
8684
- let result = await fnFirst();
8685
- const values = [];
8686
- for (const fn of fns) {
8687
- if (isErr(result)) {
8688
- return result;
8863
+ return parsedResponse.data;
8864
+ },
8865
+ async listNangoIntegrations({
8866
+ accessToken
8867
+ }) {
8868
+ const parsedResponse = nangoIntegrationsResponseSchema.safeParse(
8869
+ await fetchJson({
8870
+ accessToken,
8871
+ path: "/nango/integrations"
8872
+ })
8873
+ );
8874
+ if (!parsedResponse.success) {
8875
+ throw new CliError("Nango integrations payload was invalid.");
8689
8876
  }
8690
- values.unshift(result.value);
8691
- result = await fn(...values);
8877
+ return parsedResponse.data;
8878
+ },
8879
+ async listNangoAuthentications({
8880
+ accessToken
8881
+ }) {
8882
+ const parsedResponse = organizationAuthenticationsResponseSchema.safeParse(
8883
+ await fetchJson({
8884
+ accessToken,
8885
+ path: "/authentications/organization?type=nangoConnection"
8886
+ })
8887
+ );
8888
+ if (!parsedResponse.success) {
8889
+ throw new CliError("Organization authentications payload was invalid.");
8890
+ }
8891
+ return parsedResponse.data.authentications;
8692
8892
  }
8693
- return result;
8893
+ };
8894
+ }
8895
+
8896
+ // src/config.ts
8897
+ import os from "os";
8898
+ import path from "path";
8899
+ var DEFAULT_MAGICAL_API_URL = "https://api-agt.getmagical.io";
8900
+ var DEFAULT_WORKOS_API_URL = "https://api.workos.com";
8901
+ var DEFAULT_WORKOS_CLIENT_ID = "client_01JJZ6XJ1RF248P20WF63M4VAM";
8902
+ var DEFAULT_STAGING_WORKOS_CLIENT_ID = "client_01JJZ6X26BGFBT8AC303XPQ9EQ";
8903
+ var DEFAULT_KEYCHAIN_SERVICE_NAME = "@getmagical/mcp-cli";
8904
+ var DEFAULT_CLI_DIST_TAG = "latest";
8905
+ var DEFAULT_CLI_NPM_REGISTRY_URL = "https://registry.npmjs.org/";
8906
+ var CLI_CONFIG_DIRECTORY_NAME = "magical-mcp-cli";
8907
+ var CLI_ACCESS_TOKEN_FILE_NAME = "access-token.txt";
8908
+ var CLI_STATE_FILE_NAME = "state.json";
8909
+ var CLI_SETTINGS_FILE_NAME = "settings.json";
8910
+ var CLI_REFRESH_TOKEN_FILE_NAME = "refresh-tokens.json";
8911
+ function resolvePlatformConfigDirectory() {
8912
+ const customConfigDirectory = process.env["MAGICAL_CLI_CONFIG_DIR"];
8913
+ if (customConfigDirectory) {
8914
+ return customConfigDirectory;
8694
8915
  }
8695
- Result2.andThen = andThen;
8696
- })(Result || (Result = {}));
8697
- function Ok(value) {
8698
- if (arguments.length === 0) {
8699
- return {
8700
- _tag: "Ok",
8701
- value: void 0
8702
- };
8916
+ if (process.platform === "darwin") {
8917
+ return path.join(os.homedir(), "Library", "Application Support");
8703
8918
  }
8704
- return {
8705
- _tag: "Ok",
8706
- value
8707
- };
8919
+ if (process.platform === "win32") {
8920
+ const appDataDirectory = process.env["APPDATA"];
8921
+ return appDataDirectory ?? path.join(os.homedir(), "AppData", "Roaming");
8922
+ }
8923
+ return process.env["XDG_CONFIG_HOME"] ?? path.join(os.homedir(), ".config");
8708
8924
  }
8709
- function Err(error) {
8710
- return {
8711
- _tag: "Err",
8712
- error: new AppError(error)
8713
- };
8925
+ function resolveRefreshTokenStoreKind() {
8926
+ return process.env["MAGICAL_CLI_REFRESH_TOKEN_STORE"] === "file" ? "file" : "keytar";
8714
8927
  }
8715
- function ErrFromThrowable(error) {
8928
+ function getRuntimeConfig() {
8929
+ const configDirectory = path.join(
8930
+ resolvePlatformConfigDirectory(),
8931
+ CLI_CONFIG_DIRECTORY_NAME
8932
+ );
8716
8933
  return {
8717
- _tag: "Err",
8718
- error
8934
+ accessTokenFilePath: path.join(configDirectory, CLI_ACCESS_TOKEN_FILE_NAME),
8935
+ cliDistTag: process.env["MAGICAL_CLI_DIST_TAG"] ?? DEFAULT_CLI_DIST_TAG,
8936
+ magicalApiUrl: DEFAULT_MAGICAL_API_URL,
8937
+ npmRegistryUrl: process.env["MAGICAL_CLI_NPM_REGISTRY_URL"] ?? DEFAULT_CLI_NPM_REGISTRY_URL,
8938
+ refreshTokenFilePath: path.join(
8939
+ configDirectory,
8940
+ CLI_REFRESH_TOKEN_FILE_NAME
8941
+ ),
8942
+ refreshTokenStoreKind: resolveRefreshTokenStoreKind(),
8943
+ stateFilePath: path.join(configDirectory, CLI_STATE_FILE_NAME),
8944
+ workosApiUrl: DEFAULT_WORKOS_API_URL,
8945
+ workosClientId: DEFAULT_WORKOS_CLIENT_ID,
8946
+ keychainServiceName: DEFAULT_KEYCHAIN_SERVICE_NAME
8719
8947
  };
8720
8948
  }
8721
- function isErr(result) {
8722
- return result._tag === "Err";
8723
- }
8724
- function fromThrowable(fn, errorType, errorInfo) {
8725
- try {
8726
- const result = fn();
8727
- if (result && typeof result.then === "function") {
8728
- return result.then((value) => Ok(value)).catch((err) => Err({
8729
- ...errorInfo,
8730
- type: errorType,
8731
- cause: err
8732
- }));
8733
- }
8734
- return Ok(result);
8735
- } catch (err) {
8736
- return Err({
8737
- ...errorInfo,
8738
- type: errorType,
8739
- cause: err
8740
- });
8741
- }
8742
- }
8743
-
8744
- // ../common/dist/src/stdlib/json.util.js
8745
- function safeJsonParse(json) {
8746
- try {
8747
- return Ok(JSON.parse(json));
8748
- } catch (error) {
8749
- console.warn("Failed to parse JSON", { error, json });
8750
- return Err({ type: "invalid-json", cause: error, json });
8751
- }
8949
+ function requireWorkosClientId(config) {
8950
+ return config.workosClientId;
8752
8951
  }
8753
8952
 
8754
8953
  // src/settings.ts
8954
+ import { mkdir, readFile, rm, writeFile } from "fs/promises";
8955
+ import path2 from "path";
8755
8956
  import { z as z4 } from "zod";
8756
8957
  var cliSettingsSchema = z4.object({
8757
8958
  env: z4.object({
@@ -9879,13 +10080,13 @@ function parseCommandOptionValue(rawValue, optionSpec) {
9879
10080
  return rawValue.split(",").map((value) => value.trim()).filter((value) => value.length > 0);
9880
10081
  }
9881
10082
  case "json": {
9882
- try {
9883
- return JSON.parse(rawValue);
9884
- } catch {
10083
+ const parsedJson = safeJsonParse(rawValue);
10084
+ if (isErr(parsedJson)) {
9885
10085
  throw new InvalidArgumentError2(
9886
10086
  `Expected valid JSON for --${optionSpec.flagName}.`
9887
10087
  );
9888
10088
  }
10089
+ return parsedJson.value;
9889
10090
  }
9890
10091
  case "boolean": {
9891
10092
  return rawValue;
@@ -9955,6 +10156,13 @@ function requireLoggedInState(state) {
9955
10156
  function writeJsonOutput3(io, value) {
9956
10157
  io.info(JSON.stringify(value, null, 2));
9957
10158
  }
10159
+ function requireApiClientMethod(apiClient, key) {
10160
+ const method = apiClient[key];
10161
+ if (!method) {
10162
+ throw new CliError(`CLI API client method "${key}" is not wired.`);
10163
+ }
10164
+ return method;
10165
+ }
9958
10166
  function collectOperationVariables(operationSpec, options) {
9959
10167
  const variables = Object.fromEntries(
9960
10168
  operationSpec.cli.options.flatMap((optionSpec) => {
@@ -10090,6 +10298,100 @@ async function handleOperationCommand(dependencies, operationSpec, commandOption
10090
10298
  }
10091
10299
  dependencies.io.info(formatHumanReadableOutput(result));
10092
10300
  }
10301
+ async function withSelectedOrganizationAndAccessToken({
10302
+ dependencies,
10303
+ options
10304
+ }) {
10305
+ const state = requireLoggedInState(await dependencies.stateStore.load());
10306
+ const organization = resolveSelectedOrganization({
10307
+ state,
10308
+ ...options.org ? { organizationSelector: options.org } : {}
10309
+ });
10310
+ const { accessToken } = await withOrgScopedAccessToken({
10311
+ dependencies,
10312
+ organizationId: organization.id,
10313
+ state
10314
+ });
10315
+ return { accessToken, organization, state };
10316
+ }
10317
+ function writeCommandOutput({
10318
+ dependencies,
10319
+ json,
10320
+ result
10321
+ }) {
10322
+ if (json) {
10323
+ writeJsonOutput3(dependencies.io, result);
10324
+ return;
10325
+ }
10326
+ dependencies.io.info(formatHumanReadableOutput(result));
10327
+ }
10328
+ async function handleNangoIntegrationsListCommand(dependencies, options) {
10329
+ const { accessToken, organization, state } = await withSelectedOrganizationAndAccessToken({ dependencies, options });
10330
+ const listNangoIntegrations = requireApiClientMethod(
10331
+ dependencies.apiClient,
10332
+ "listNangoIntegrations"
10333
+ );
10334
+ const integrations = await listNangoIntegrations({ accessToken });
10335
+ await saveLastUsedOrganization({
10336
+ dependencies,
10337
+ organizationId: organization.id,
10338
+ state
10339
+ });
10340
+ writeCommandOutput({
10341
+ dependencies,
10342
+ json: options.json,
10343
+ result: integrations
10344
+ });
10345
+ }
10346
+ function normalizeListedNangoAuthentication(authentication) {
10347
+ return {
10348
+ id: authentication.id,
10349
+ type: authentication.type,
10350
+ ...authentication.connectionId === void 0 ? {} : { connectionId: authentication.connectionId },
10351
+ ...authentication.providerConfigKey === void 0 ? {} : { providerConfigKey: authentication.providerConfigKey },
10352
+ ...authentication.description === void 0 ? {} : { description: authentication.description },
10353
+ ...authentication.hostname === void 0 ? {} : { hostname: authentication.hostname }
10354
+ };
10355
+ }
10356
+ async function handleNangoAuthsListCommand(dependencies, options) {
10357
+ const { accessToken, organization, state } = await withSelectedOrganizationAndAccessToken({ dependencies, options });
10358
+ const listNangoAuthentications = requireApiClientMethod(
10359
+ dependencies.apiClient,
10360
+ "listNangoAuthentications"
10361
+ );
10362
+ const organizationAuthentications = await listNangoAuthentications({
10363
+ accessToken
10364
+ });
10365
+ const authentications = organizationAuthentications.filter((authentication) => {
10366
+ if (options.integration && authentication.providerConfigKey !== options.integration) {
10367
+ return false;
10368
+ }
10369
+ if (options.connectionId && authentication.connectionId !== options.connectionId) {
10370
+ return false;
10371
+ }
10372
+ return true;
10373
+ }).map(normalizeListedNangoAuthentication);
10374
+ await saveLastUsedOrganization({
10375
+ dependencies,
10376
+ organizationId: organization.id,
10377
+ state
10378
+ });
10379
+ writeCommandOutput({
10380
+ dependencies,
10381
+ json: options.json,
10382
+ result: authentications
10383
+ });
10384
+ }
10385
+ async function saveLastUsedOrganization({
10386
+ dependencies,
10387
+ organizationId,
10388
+ state
10389
+ }) {
10390
+ await dependencies.stateStore.save({
10391
+ ...state,
10392
+ lastUsedOrgId: organizationId
10393
+ });
10394
+ }
10093
10395
  function addRegistryOperationCommand({
10094
10396
  program: program2,
10095
10397
  commandGroups,
@@ -10283,6 +10585,66 @@ ${formatExamples("Examples", [
10283
10585
  );
10284
10586
  });
10285
10587
  program2.addCommand(orgCommand);
10588
+ const nangoCommand = configureCommandPresentation(
10589
+ new Command2("nango").description(
10590
+ "Inspect Nango integrations and org-scoped authentications."
10591
+ )
10592
+ ).helpGroup("Workspace:").addHelpText(
10593
+ "after",
10594
+ `
10595
+ ${formatExamples("Examples", [
10596
+ "mgcl nango integrations list --json",
10597
+ "mgcl nango auths list --integration github --json"
10598
+ ])}`
10599
+ );
10600
+ const nangoIntegrationsCommand = configureCommandPresentation(
10601
+ new Command2("integrations").description("Work with Nango integrations.")
10602
+ );
10603
+ nangoIntegrationsCommand.command("list").description("List Nango integrations available in the current workspace.").addOption(
10604
+ new Option2(
10605
+ "--org <org>",
10606
+ "Organization ID or exact organization name to use."
10607
+ ).helpGroup("Shared options:")
10608
+ ).action(async function() {
10609
+ await handleNangoIntegrationsListCommand(
10610
+ dependencies,
10611
+ this.optsWithGlobals()
10612
+ );
10613
+ });
10614
+ nangoCommand.addCommand(nangoIntegrationsCommand);
10615
+ const nangoAuthsCommand = configureCommandPresentation(
10616
+ new Command2("auths").alias("authentications").description("Work with org-scoped Nango authentications.")
10617
+ );
10618
+ nangoAuthsCommand.command("list").description(
10619
+ "List org-scoped Nango authentications and their connection IDs."
10620
+ ).addOption(
10621
+ new Option2(
10622
+ "--org <org>",
10623
+ "Organization ID or exact organization name to use."
10624
+ ).helpGroup("Shared options:")
10625
+ ).addOption(
10626
+ new Option2(
10627
+ "--integration <integration>",
10628
+ "Optional integration key to filter Nango authentications."
10629
+ )
10630
+ ).addOption(
10631
+ new Option2(
10632
+ "--connection-id <connectionId>",
10633
+ "Optional connection ID to filter Nango authentications."
10634
+ )
10635
+ ).addHelpText(
10636
+ "after",
10637
+ `
10638
+ ${formatExamples("Examples", [
10639
+ "mgcl nango auths list --json",
10640
+ "mgcl nango auths list --integration github --json",
10641
+ "mgcl nango auths list --integration github --connection-id <id> --json"
10642
+ ])}`
10643
+ ).action(async function() {
10644
+ await handleNangoAuthsListCommand(dependencies, this.optsWithGlobals());
10645
+ });
10646
+ nangoCommand.addCommand(nangoAuthsCommand);
10647
+ program2.addCommand(nangoCommand);
10286
10648
  const updateCommand = configureCommandPresentation(
10287
10649
  new Command2("update").description(
10288
10650
  "Update mgcl to the latest published npm release."