@getmagical/cli 0.2.5 → 0.2.7
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/README.md +139 -0
- package/dist/index.js +2660 -340
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2056,13 +2056,13 @@ var require_ast = __commonJS({
|
|
|
2056
2056
|
helperExpression: function helperExpression(node) {
|
|
2057
2057
|
return node.type === "SubExpression" || (node.type === "MustacheStatement" || node.type === "BlockStatement") && !!(node.params && node.params.length || node.hash);
|
|
2058
2058
|
},
|
|
2059
|
-
scopedId: function scopedId(
|
|
2060
|
-
return /^\.|this\b/.test(
|
|
2059
|
+
scopedId: function scopedId(path9) {
|
|
2060
|
+
return /^\.|this\b/.test(path9.original);
|
|
2061
2061
|
},
|
|
2062
2062
|
// an ID is simple if it only has one part, and that part is not
|
|
2063
2063
|
// `..` or `this`.
|
|
2064
|
-
simpleId: function simpleId(
|
|
2065
|
-
return
|
|
2064
|
+
simpleId: function simpleId(path9) {
|
|
2065
|
+
return path9.parts.length === 1 && !AST.helpers.scopedId(path9) && !path9.depth;
|
|
2066
2066
|
}
|
|
2067
2067
|
}
|
|
2068
2068
|
};
|
|
@@ -3132,12 +3132,12 @@ var require_helpers2 = __commonJS({
|
|
|
3132
3132
|
loc
|
|
3133
3133
|
};
|
|
3134
3134
|
}
|
|
3135
|
-
function prepareMustache(
|
|
3135
|
+
function prepareMustache(path9, params, hash, open, strip, locInfo) {
|
|
3136
3136
|
var escapeFlag = open.charAt(3) || open.charAt(2), escaped = escapeFlag !== "{" && escapeFlag !== "&";
|
|
3137
3137
|
var decorator = /\*/.test(open);
|
|
3138
3138
|
return {
|
|
3139
3139
|
type: decorator ? "Decorator" : "MustacheStatement",
|
|
3140
|
-
path:
|
|
3140
|
+
path: path9,
|
|
3141
3141
|
params,
|
|
3142
3142
|
hash,
|
|
3143
3143
|
escaped,
|
|
@@ -3455,9 +3455,9 @@ var require_compiler = __commonJS({
|
|
|
3455
3455
|
},
|
|
3456
3456
|
DecoratorBlock: function DecoratorBlock(decorator) {
|
|
3457
3457
|
var program2 = decorator.program && this.compileProgram(decorator.program);
|
|
3458
|
-
var params = this.setupFullMustacheParams(decorator, program2, void 0),
|
|
3458
|
+
var params = this.setupFullMustacheParams(decorator, program2, void 0), path9 = decorator.path;
|
|
3459
3459
|
this.useDecorators = true;
|
|
3460
|
-
this.opcode("registerDecorator", params.length,
|
|
3460
|
+
this.opcode("registerDecorator", params.length, path9.original);
|
|
3461
3461
|
},
|
|
3462
3462
|
PartialStatement: function PartialStatement(partial) {
|
|
3463
3463
|
this.usePartial = true;
|
|
@@ -3521,46 +3521,46 @@ var require_compiler = __commonJS({
|
|
|
3521
3521
|
}
|
|
3522
3522
|
},
|
|
3523
3523
|
ambiguousSexpr: function ambiguousSexpr(sexpr, program2, inverse) {
|
|
3524
|
-
var
|
|
3525
|
-
this.opcode("getContext",
|
|
3524
|
+
var path9 = sexpr.path, name = path9.parts[0], isBlock = program2 != null || inverse != null;
|
|
3525
|
+
this.opcode("getContext", path9.depth);
|
|
3526
3526
|
this.opcode("pushProgram", program2);
|
|
3527
3527
|
this.opcode("pushProgram", inverse);
|
|
3528
|
-
|
|
3529
|
-
this.accept(
|
|
3528
|
+
path9.strict = true;
|
|
3529
|
+
this.accept(path9);
|
|
3530
3530
|
this.opcode("invokeAmbiguous", name, isBlock);
|
|
3531
3531
|
},
|
|
3532
3532
|
simpleSexpr: function simpleSexpr(sexpr) {
|
|
3533
|
-
var
|
|
3534
|
-
|
|
3535
|
-
this.accept(
|
|
3533
|
+
var path9 = sexpr.path;
|
|
3534
|
+
path9.strict = true;
|
|
3535
|
+
this.accept(path9);
|
|
3536
3536
|
this.opcode("resolvePossibleLambda");
|
|
3537
3537
|
},
|
|
3538
3538
|
helperSexpr: function helperSexpr(sexpr, program2, inverse) {
|
|
3539
|
-
var params = this.setupFullMustacheParams(sexpr, program2, inverse),
|
|
3539
|
+
var params = this.setupFullMustacheParams(sexpr, program2, inverse), path9 = sexpr.path, name = path9.parts[0];
|
|
3540
3540
|
if (this.options.knownHelpers[name]) {
|
|
3541
3541
|
this.opcode("invokeKnownHelper", params.length, name);
|
|
3542
3542
|
} else if (this.options.knownHelpersOnly) {
|
|
3543
3543
|
throw new _exception2["default"]("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
|
|
3544
3544
|
} else {
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
this.accept(
|
|
3548
|
-
this.opcode("invokeHelper", params.length,
|
|
3545
|
+
path9.strict = true;
|
|
3546
|
+
path9.falsy = true;
|
|
3547
|
+
this.accept(path9);
|
|
3548
|
+
this.opcode("invokeHelper", params.length, path9.original, _ast2["default"].helpers.simpleId(path9));
|
|
3549
3549
|
}
|
|
3550
3550
|
},
|
|
3551
|
-
PathExpression: function PathExpression(
|
|
3552
|
-
this.addDepth(
|
|
3553
|
-
this.opcode("getContext",
|
|
3554
|
-
var name =
|
|
3551
|
+
PathExpression: function PathExpression(path9) {
|
|
3552
|
+
this.addDepth(path9.depth);
|
|
3553
|
+
this.opcode("getContext", path9.depth);
|
|
3554
|
+
var name = path9.parts[0], scoped = _ast2["default"].helpers.scopedId(path9), blockParamId = !path9.depth && !scoped && this.blockParamIndex(name);
|
|
3555
3555
|
if (blockParamId) {
|
|
3556
|
-
this.opcode("lookupBlockParam", blockParamId,
|
|
3556
|
+
this.opcode("lookupBlockParam", blockParamId, path9.parts);
|
|
3557
3557
|
} else if (!name) {
|
|
3558
3558
|
this.opcode("pushContext");
|
|
3559
|
-
} else if (
|
|
3559
|
+
} else if (path9.data) {
|
|
3560
3560
|
this.options.data = true;
|
|
3561
|
-
this.opcode("lookupData",
|
|
3561
|
+
this.opcode("lookupData", path9.depth, path9.parts, path9.strict);
|
|
3562
3562
|
} else {
|
|
3563
|
-
this.opcode("lookupOnContext",
|
|
3563
|
+
this.opcode("lookupOnContext", path9.parts, path9.falsy, path9.strict, scoped);
|
|
3564
3564
|
}
|
|
3565
3565
|
},
|
|
3566
3566
|
StringLiteral: function StringLiteral(string) {
|
|
@@ -3910,16 +3910,16 @@ var require_util2 = __commonJS({
|
|
|
3910
3910
|
}
|
|
3911
3911
|
exports.urlGenerate = urlGenerate;
|
|
3912
3912
|
function normalize(aPath) {
|
|
3913
|
-
var
|
|
3913
|
+
var path9 = aPath;
|
|
3914
3914
|
var url = urlParse(aPath);
|
|
3915
3915
|
if (url) {
|
|
3916
3916
|
if (!url.path) {
|
|
3917
3917
|
return aPath;
|
|
3918
3918
|
}
|
|
3919
|
-
|
|
3919
|
+
path9 = url.path;
|
|
3920
3920
|
}
|
|
3921
|
-
var isAbsolute = exports.isAbsolute(
|
|
3922
|
-
var parts =
|
|
3921
|
+
var isAbsolute = exports.isAbsolute(path9);
|
|
3922
|
+
var parts = path9.split(/\/+/);
|
|
3923
3923
|
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
|
|
3924
3924
|
part = parts[i];
|
|
3925
3925
|
if (part === ".") {
|
|
@@ -3936,15 +3936,15 @@ var require_util2 = __commonJS({
|
|
|
3936
3936
|
}
|
|
3937
3937
|
}
|
|
3938
3938
|
}
|
|
3939
|
-
|
|
3940
|
-
if (
|
|
3941
|
-
|
|
3939
|
+
path9 = parts.join("/");
|
|
3940
|
+
if (path9 === "") {
|
|
3941
|
+
path9 = isAbsolute ? "/" : ".";
|
|
3942
3942
|
}
|
|
3943
3943
|
if (url) {
|
|
3944
|
-
url.path =
|
|
3944
|
+
url.path = path9;
|
|
3945
3945
|
return urlGenerate(url);
|
|
3946
3946
|
}
|
|
3947
|
-
return
|
|
3947
|
+
return path9;
|
|
3948
3948
|
}
|
|
3949
3949
|
exports.normalize = normalize;
|
|
3950
3950
|
function join(aRoot, aPath) {
|
|
@@ -6727,8 +6727,8 @@ var require_printer = __commonJS({
|
|
|
6727
6727
|
return this.accept(sexpr.path) + " " + params + hash;
|
|
6728
6728
|
};
|
|
6729
6729
|
PrintVisitor.prototype.PathExpression = function(id) {
|
|
6730
|
-
var
|
|
6731
|
-
return (id.data ? "@" : "") + "PATH:" +
|
|
6730
|
+
var path9 = id.parts.join("/");
|
|
6731
|
+
return (id.data ? "@" : "") + "PATH:" + path9;
|
|
6732
6732
|
};
|
|
6733
6733
|
PrintVisitor.prototype.StringLiteral = function(string) {
|
|
6734
6734
|
return '"' + string.value + '"';
|
|
@@ -7079,8 +7079,8 @@ function getErrorMessage(error) {
|
|
|
7079
7079
|
}
|
|
7080
7080
|
|
|
7081
7081
|
// src/program.ts
|
|
7082
|
-
import { readFile as
|
|
7083
|
-
import
|
|
7082
|
+
import { readFile as readFile6 } from "node:fs/promises";
|
|
7083
|
+
import path8 from "node:path";
|
|
7084
7084
|
|
|
7085
7085
|
// ../common/dist/src/stdlib/json.util.js
|
|
7086
7086
|
var import_ts_essentials = __toESM(require_dist(), 1);
|
|
@@ -11818,6 +11818,7 @@ var fieldMetadataSchema = z7.object({
|
|
|
11818
11818
|
description: z7.string().describe("A description of the input parameter.").nullable(),
|
|
11819
11819
|
typeOverride: z7.string().describe("The override for the input parameter.").nullable(),
|
|
11820
11820
|
enumLabels: z7.record(z7.string(), z7.string()).describe("Optional map of enum values to their display labels.").optional(),
|
|
11821
|
+
displayDefaultValue: z7.unknown().describe("Optional value to display when input is omitted without changing the parsed value.").optional(),
|
|
11821
11822
|
label: z7.string().describe("Optional label override for the field.").optional(),
|
|
11822
11823
|
allowLineBreaks: z7.boolean().describe("Whether the field should allow line breaks when supported by the input component.").optional(),
|
|
11823
11824
|
hideEmptyInCollapsed: z7.boolean().describe("Whether to hide this field in collapsed view when empty.").optional(),
|
|
@@ -11850,6 +11851,7 @@ var clickTypeEnumSchema = z7.enum([
|
|
|
11850
11851
|
"DOUBLE",
|
|
11851
11852
|
"TRIPLE"
|
|
11852
11853
|
]);
|
|
11854
|
+
var updateModeSchema = z7.enum(["append", "prepend", "replace"]);
|
|
11853
11855
|
var clickTypeSchema = withMetadata(clickTypeEnumSchema.optional(), {
|
|
11854
11856
|
description: "The type of click to perform",
|
|
11855
11857
|
typeOverride: null
|
|
@@ -11922,8 +11924,8 @@ var RENDER_TEMPLATE_ERROR_REASON_CATALOG = defineErrorReasonCatalog()([
|
|
|
11922
11924
|
]);
|
|
11923
11925
|
var storeReferencePathPattern = String.raw`store(?:\.[$A-Z_a-z][\w$]*)*`;
|
|
11924
11926
|
var storeReferenceMarkdownLinkTemplateRegex = new RegExp(String.raw`(?<open>\{\{\{?)\s*\[(?<path>${storeReferencePathPattern})\]\(\s*<?https?:\/\/\k<path>>?\s*\)\s*(?<close>\}\}\}?)`, "gu");
|
|
11925
|
-
function normalizeAutomationStoreTemplateLinkMatch([_match, open,
|
|
11926
|
-
return open === "{{{" ? `{{{${
|
|
11927
|
+
function normalizeAutomationStoreTemplateLinkMatch([_match, open, path9]) {
|
|
11928
|
+
return open === "{{{" ? `{{{${path9}}}}` : `{{${path9}}}`;
|
|
11927
11929
|
}
|
|
11928
11930
|
function normalizeAutomationStoreTemplateLinks(template) {
|
|
11929
11931
|
return template.replaceAll(storeReferenceMarkdownLinkTemplateRegex, (...args) => normalizeAutomationStoreTemplateLinkMatch(args));
|
|
@@ -12491,18 +12493,18 @@ var reportStopDataSchema = z11.object({
|
|
|
12491
12493
|
// ../common/dist/src/utils/automation-store-path.util.js
|
|
12492
12494
|
var AUTOMATION_STORE_ROOT_PATH = "store";
|
|
12493
12495
|
var relativeStorePathRegex = /^[$A-Z_a-z][\w$]*(?:\.[$A-Z_a-z][\w$]*)*$/u;
|
|
12494
|
-
function normalizeStoreMutationPath(
|
|
12495
|
-
const trimmedPath =
|
|
12496
|
+
function normalizeStoreMutationPath(path9) {
|
|
12497
|
+
const trimmedPath = path9.trim();
|
|
12496
12498
|
const rootPrefix = `${AUTOMATION_STORE_ROOT_PATH}.`;
|
|
12497
12499
|
const relativePath = trimmedPath.startsWith(rootPrefix) ? trimmedPath.slice(rootPrefix.length) : trimmedPath;
|
|
12498
12500
|
if (!relativeStorePathRegex.test(relativePath)) {
|
|
12499
12501
|
return Err({
|
|
12500
12502
|
type: "invalid-automation-store-path",
|
|
12501
|
-
path:
|
|
12503
|
+
path: path9,
|
|
12502
12504
|
categories: ["customer_usage"],
|
|
12503
12505
|
statusCode: 400,
|
|
12504
12506
|
nonRetryable: true,
|
|
12505
|
-
message: `Automation store path "${
|
|
12507
|
+
message: `Automation store path "${path9}" is invalid.`,
|
|
12506
12508
|
suggestedAction: "Use a dot path relative to the automation store, such as patient.name or provider.clinic."
|
|
12507
12509
|
});
|
|
12508
12510
|
}
|
|
@@ -12515,16 +12517,16 @@ function findAutomationStorePathOverlap(paths) {
|
|
|
12515
12517
|
...new Set(paths.map(getCanonicalAutomationStoreMutationPath))
|
|
12516
12518
|
].toSorted((left, right) => (left === AUTOMATION_STORE_ROOT_PATH ? 0 : left.split(".").length) - (right === AUTOMATION_STORE_ROOT_PATH ? 0 : right.split(".").length));
|
|
12517
12519
|
for (const [index, ancestorPath] of canonicalPaths.entries()) {
|
|
12518
|
-
const descendantPath = canonicalPaths.slice(index + 1).find((
|
|
12520
|
+
const descendantPath = canonicalPaths.slice(index + 1).find((path9) => ancestorPath === AUTOMATION_STORE_ROOT_PATH || path9.startsWith(`${ancestorPath}.`));
|
|
12519
12521
|
if (descendantPath !== void 0) {
|
|
12520
12522
|
return { ancestorPath, descendantPath };
|
|
12521
12523
|
}
|
|
12522
12524
|
}
|
|
12523
12525
|
return void 0;
|
|
12524
12526
|
}
|
|
12525
|
-
function getCanonicalAutomationStoreMutationPath(
|
|
12526
|
-
const normalizedPath = normalizeStoreMutationPath(
|
|
12527
|
-
return normalizedPath._tag === "Ok" ? normalizedPath.value :
|
|
12527
|
+
function getCanonicalAutomationStoreMutationPath(path9) {
|
|
12528
|
+
const normalizedPath = normalizeStoreMutationPath(path9);
|
|
12529
|
+
return normalizedPath._tag === "Ok" ? normalizedPath.value : path9.trim();
|
|
12528
12530
|
}
|
|
12529
12531
|
|
|
12530
12532
|
// ../common/dist/src/constants/tool-declarations.js
|
|
@@ -12748,9 +12750,9 @@ var baseToolDeclarations = {
|
|
|
12748
12750
|
path: []
|
|
12749
12751
|
});
|
|
12750
12752
|
}
|
|
12751
|
-
const canonicalUpdatePaths = updates.map(({ path:
|
|
12753
|
+
const canonicalUpdatePaths = updates.map(({ path: path9 }) => getCanonicalAutomationStoreMutationPath(path9));
|
|
12752
12754
|
const canonicalClearPathSet = new Set(clears.map(getCanonicalAutomationStoreMutationPath));
|
|
12753
|
-
const conflictedUpdatePath = canonicalUpdatePaths.find((
|
|
12755
|
+
const conflictedUpdatePath = canonicalUpdatePaths.find((path9) => canonicalClearPathSet.has(path9));
|
|
12754
12756
|
if (conflictedUpdatePath !== void 0) {
|
|
12755
12757
|
context.addIssue({
|
|
12756
12758
|
code: "custom",
|
|
@@ -12826,10 +12828,11 @@ var baseToolDeclarations = {
|
|
|
12826
12828
|
},
|
|
12827
12829
|
type: {
|
|
12828
12830
|
id: "type",
|
|
12829
|
-
description: "Type in the currently focused element
|
|
12831
|
+
description: "Type in the currently focused element. By default, this replaces the complete current value; updateMode can instead append or prepend the text.",
|
|
12830
12832
|
parameters: z12.object({
|
|
12831
12833
|
[COMMON_PARAMETERS_KEY]: DEFAULT_COMMON_PARAMETERS,
|
|
12832
|
-
text: z12.string().describe("The text to type")
|
|
12834
|
+
text: z12.string().describe("The text to type"),
|
|
12835
|
+
updateMode: updateModeSchema.optional().describe("How to combine the text with the current value. Defaults to replace.")
|
|
12833
12836
|
})
|
|
12834
12837
|
},
|
|
12835
12838
|
getNDCFromMedication: {
|
|
@@ -13429,9 +13432,9 @@ var specialCommands = {
|
|
|
13429
13432
|
};
|
|
13430
13433
|
|
|
13431
13434
|
// ../common/dist/src/utils/agent-knowledge-base-assets.util.js
|
|
13432
|
-
function getIsKnowledgeBaseAssetPathAllowed(
|
|
13433
|
-
const pathSegments =
|
|
13434
|
-
if (
|
|
13435
|
+
function getIsKnowledgeBaseAssetPathAllowed(path9) {
|
|
13436
|
+
const pathSegments = path9.split("/");
|
|
13437
|
+
if (path9.length === 0 || pathSegments.some((segment) => segment.length === 0)) {
|
|
13435
13438
|
return false;
|
|
13436
13439
|
}
|
|
13437
13440
|
const isTopLevelAssetPath = pathSegments[0] === "assets";
|
|
@@ -13473,46 +13476,46 @@ var API_FILE_TYPE_REGISTRY = {
|
|
|
13473
13476
|
var ApiAgentOutputModes = ["inline", "file"];
|
|
13474
13477
|
var API_EMBEDDED_FILE_PATH_PATTERN = /^(?:\[\*\]|[A-Za-z_$][\w$-]*)(?:\[\*\]|\.[A-Za-z_$][\w$-]*)*$/u;
|
|
13475
13478
|
var API_EMBEDDED_FILE_PATH_SEGMENT_PATTERN = /\[\*\]|[A-Za-z_$][\w$-]*/gu;
|
|
13476
|
-
function parseApiEmbeddedFilePath(
|
|
13477
|
-
if (!API_EMBEDDED_FILE_PATH_PATTERN.test(
|
|
13479
|
+
function parseApiEmbeddedFilePath(path9) {
|
|
13480
|
+
if (!API_EMBEDDED_FILE_PATH_PATTERN.test(path9)) {
|
|
13478
13481
|
return void 0;
|
|
13479
13482
|
}
|
|
13480
|
-
return [...
|
|
13483
|
+
return [...path9.matchAll(API_EMBEDDED_FILE_PATH_SEGMENT_PATTERN)].map(([segment]) => segment === "[*]" ? { type: "arrayWildcard" } : { key: segment, type: "property" });
|
|
13481
13484
|
}
|
|
13482
13485
|
var apiAgentEmbeddedFileSchema = z14.object({
|
|
13483
|
-
path: z14.string().trim().min(1, "Embedded file path is required.").refine((
|
|
13486
|
+
path: z14.string().trim().min(1, "Embedded file path is required.").refine((path9) => parseApiEmbeddedFilePath(path9) !== void 0, {
|
|
13484
13487
|
message: "Embedded file path must use object properties and [*] array wildcards."
|
|
13485
13488
|
}).describe("Path to a Base64 value relative to the projected API response. Supports object properties and [*] array wildcards."),
|
|
13486
13489
|
contentType: z14.enum(ApiFileContentTypes).describe("File type of the decoded Base64 value.")
|
|
13487
13490
|
}).strict();
|
|
13488
13491
|
var apiAgentEmbeddedFilesSchema = z14.array(apiAgentEmbeddedFileSchema).superRefine((embeddedFiles, context) => {
|
|
13489
13492
|
const paths = /* @__PURE__ */ new Set();
|
|
13490
|
-
for (const [index, { path:
|
|
13491
|
-
if (paths.has(
|
|
13493
|
+
for (const [index, { path: path9 }] of embeddedFiles.entries()) {
|
|
13494
|
+
if (paths.has(path9)) {
|
|
13492
13495
|
context.addIssue({
|
|
13493
13496
|
code: z14.ZodIssueCode.custom,
|
|
13494
|
-
message: `Embedded file path "${
|
|
13497
|
+
message: `Embedded file path "${path9}" can only be configured once.`,
|
|
13495
13498
|
path: [index, "path"]
|
|
13496
13499
|
});
|
|
13497
13500
|
}
|
|
13498
|
-
paths.add(
|
|
13501
|
+
paths.add(path9);
|
|
13499
13502
|
}
|
|
13500
13503
|
}).describe("Base64 values to decode, upload as permanent files, and replace with file references in the projected API response.");
|
|
13501
13504
|
|
|
13502
13505
|
// ../common/dist/src/zod-schemas/api-agent-request-file-encoding.schema.js
|
|
13503
13506
|
import { z as z15 } from "zod";
|
|
13504
13507
|
var API_REQUEST_FILE_PATH_PATTERN = /^[A-Za-z_$][\w$-]*(?:\.[A-Za-z_$][\w$-]*)*$/u;
|
|
13505
|
-
function parseApiRequestFilePath(
|
|
13506
|
-
if (!API_REQUEST_FILE_PATH_PATTERN.test(
|
|
13508
|
+
function parseApiRequestFilePath(path9) {
|
|
13509
|
+
if (!API_REQUEST_FILE_PATH_PATTERN.test(path9)) {
|
|
13507
13510
|
return void 0;
|
|
13508
13511
|
}
|
|
13509
|
-
return
|
|
13512
|
+
return path9.split(".");
|
|
13510
13513
|
}
|
|
13511
13514
|
var apiAgentRequestFileEncodingSchema = z15.object({
|
|
13512
|
-
sourceInput: z15.string().trim().min(1, "File input is required.").refine((
|
|
13515
|
+
sourceInput: z15.string().trim().min(1, "File input is required.").refine((path9) => parseApiRequestFilePath(path9) !== void 0, {
|
|
13513
13516
|
message: "File input must use an object property path."
|
|
13514
13517
|
}).describe("API Agent input containing the file reference to encode."),
|
|
13515
|
-
destinationPath: z15.string().trim().min(1, "Request field is required.").refine((
|
|
13518
|
+
destinationPath: z15.string().trim().min(1, "Request field is required.").refine((path9) => parseApiRequestFilePath(path9) !== void 0, {
|
|
13516
13519
|
message: "Request field must use an object property path."
|
|
13517
13520
|
}).describe("JSON request body path where the encoded value is inserted."),
|
|
13518
13521
|
encoding: z15.literal("base64").describe("Encoding applied to the source file before insertion.")
|
|
@@ -13863,25 +13866,32 @@ function hasControlCharacter(value) {
|
|
|
13863
13866
|
}
|
|
13864
13867
|
return false;
|
|
13865
13868
|
}
|
|
13866
|
-
function isNormalizedRepoPath(
|
|
13867
|
-
if (
|
|
13869
|
+
function isNormalizedRepoPath(path9) {
|
|
13870
|
+
if (path9 === "/") {
|
|
13868
13871
|
return true;
|
|
13869
13872
|
}
|
|
13870
|
-
if (
|
|
13873
|
+
if (path9.length === 0 || path9.startsWith("/") || path9.startsWith("\\") || path9.includes("\\") || hasControlCharacter(path9) || windowsAbsolutePathPattern.test(path9)) {
|
|
13871
13874
|
return false;
|
|
13872
13875
|
}
|
|
13873
|
-
return
|
|
13876
|
+
return path9.split("/").every((segment) => segment.length > 0 && segment !== "." && segment !== ".." && segment !== ".git");
|
|
13874
13877
|
}
|
|
13875
|
-
function normalizeRepoPath(
|
|
13876
|
-
if (
|
|
13877
|
-
return
|
|
13878
|
+
function normalizeRepoPath(path9) {
|
|
13879
|
+
if (path9 === "/") {
|
|
13880
|
+
return path9;
|
|
13878
13881
|
}
|
|
13879
|
-
return
|
|
13882
|
+
return path9.replaceAll(/\/+$/gu, "");
|
|
13880
13883
|
}
|
|
13881
13884
|
var skillPathPattern = /^(?:skills\/.+|automations\/[^/]+\/skills\/.+|automations\/[^/]+\/agents\/[^/]+\/skills\/.+)$/u;
|
|
13885
|
+
var skillRootPathPattern = /^(?:skills\/[^/]+|automations\/[^/]+\/skills\/[^/]+|automations\/[^/]+\/agents\/[^/]+\/skills\/[^/]+)$/u;
|
|
13882
13886
|
var repoPathSchema = z21.string().min(1).transform(normalizeRepoPath).refine(isNormalizedRepoPath, {
|
|
13883
13887
|
message: "Path must be a normalized repository-relative path."
|
|
13884
13888
|
});
|
|
13889
|
+
var registeredSkillPathSchema = repoPathSchema.refine((path9) => skillPathPattern.test(path9), {
|
|
13890
|
+
message: "Skill paths must be under root, automation, or automation-agent skills."
|
|
13891
|
+
});
|
|
13892
|
+
var registeredSkillRootPathSchema = registeredSkillPathSchema.refine((path9) => skillRootPathPattern.test(path9) && !path9.endsWith("/SKILL.md"), {
|
|
13893
|
+
message: "Registered skill paths must identify a skill root directory."
|
|
13894
|
+
});
|
|
13885
13895
|
var knowledgeBasePluginPermissionSchema = z21.object({
|
|
13886
13896
|
path: repoPathSchema.refine(getIsKnowledgeBaseAssetPathAllowed, {
|
|
13887
13897
|
message: "Knowledge Base paths must be under org, automation, or automation-agent assets."
|
|
@@ -13897,9 +13907,7 @@ var memoryConfigSchema = z21.object({
|
|
|
13897
13907
|
}).strict().describe("Configuration for the memory runtime plugin.");
|
|
13898
13908
|
var skillsConfigSchema = z21.object({
|
|
13899
13909
|
enabled: z21.boolean().default(false).describe("Explicit rollout switch for the skills runtime plugin."),
|
|
13900
|
-
registeredSkills: z21.array(
|
|
13901
|
-
message: "Skill paths must be under root, automation, or automation-agent skills."
|
|
13902
|
-
})).default(() => []).describe("Repository skill root paths available to the skills plugin."),
|
|
13910
|
+
registeredSkills: z21.array(registeredSkillPathSchema).default(() => []).describe("Repository skill root paths available to the skills plugin."),
|
|
13903
13911
|
canEdit: z21.boolean().default(false).describe("Allows the skills runtime plugin to edit repo skills under the root skills folder.")
|
|
13904
13912
|
}).describe("Configuration for the skills runtime plugin.");
|
|
13905
13913
|
var agentPluginsConfigSchema = z21.object({
|
|
@@ -13921,6 +13929,7 @@ var baseAgentConfigFieldsSchema = z21.object({
|
|
|
13921
13929
|
environmentOptions: environmentOptionsSchema.optional().default(DEFAULT_ENVIRONMENT_OPTION).describe("Environment configuration for the agent. Default is browser with SOM."),
|
|
13922
13930
|
runSettings: agentRunSettingsSchema.optional().describe("Run settings persisted on the agent and used when this agent is selected as the settings source for a run while the run-settings rollout is enabled. This is the canonical runtime source for resource pools during the migration. It intentionally mirrors a subset of agent config so settings survive topology changes and can be stored on any agent regardless of that agent's own execution environment. Writers may populate this before the rollout flag is enabled, but runtime snapshotting must keep using legacy fields while the flag is disabled."),
|
|
13923
13931
|
skipBrowserDebuggerPauses: z21.boolean().optional().describe("Legacy agent-local browser session startup setting. Used only when a run is in legacy config mode; canonical run settings mode reads runSettings.skipBrowserDebuggerPauses instead."),
|
|
13932
|
+
stepFollowingVerification: z21.enum(["default", "enabled", "disabled"]).optional().describe("Controls step-following verification for this agent. Default runs verification unless skills are enabled; enabled forces it on past the skills rule; disabled forces it off. Automation and system feature gates still take precedence."),
|
|
13924
13933
|
limitations: agentRunLimitationSchema.describe("Resource limits for this agent, including maximum duration and tool call limits."),
|
|
13925
13934
|
commonParametersSchema: z21.custom().optional().describe("Custom schema defining metadata the agent must provide with every tool call. By default, agents provide reasoning and step information. If specified, this schema replaces the default metadata schema entirely."),
|
|
13926
13935
|
idempotencySettings: z21.object({
|
|
@@ -14266,7 +14275,8 @@ var automationRunConfigBaseSchema = z24.object({
|
|
|
14266
14275
|
resolvedRunSettings: automationRunResolvedRunSettingsSchema.optional().describe("Canonical run settings snapshotted onto the automation run at creation time. Present only for runSettings mode; legacyConfig mode intentionally resolves runtime settings from each current agent config instead of storing a misleading snapshot."),
|
|
14267
14276
|
queueResourcePools: resourcePoolsSchema.optional().describe("Canonical deduped resource-pool requirements snapshotted for queue and slot assignment. Present on new runs so assignment does not recompute requirements from mutable agent config."),
|
|
14268
14277
|
credentialVariableResourcePools: resourcePoolsSchema.optional().describe("Additional resource pools selected through credential-valued automation variables. These are additive queue requirements and do not change whether the run uses runSettings or legacyConfig as its runtime settings source."),
|
|
14269
|
-
resolvedRunSettingsSource: z24.enum(["runSettings", "legacyConfig"]).optional().describe("Runtime mode decided at run creation. runSettings means resolvedRunSettings is canonical for browser/session/resource-pool behaviour; legacyConfig means runtime consumers must use current agent legacy config fields.")
|
|
14278
|
+
resolvedRunSettingsSource: z24.enum(["runSettings", "legacyConfig"]).optional().describe("Runtime mode decided at run creation. runSettings means resolvedRunSettings is canonical for browser/session/resource-pool behaviour; legacyConfig means runtime consumers must use current agent legacy config fields."),
|
|
14279
|
+
automationVersionPinned: z24.literal(true).optional().describe("Infrastructure-owned marker set when the run was explicitly pinned to an automation version (e.g. a branch head draft run). Draft-scoped prompt rendering must keep the pinned agent version instead of re-resolving the latest draft instructions.")
|
|
14270
14280
|
});
|
|
14271
14281
|
var automationRunConfigSchema = automationRunConfigBaseSchema.superRefine((config, ctx) => {
|
|
14272
14282
|
if (config.networkTrafficCaptureExplicitlyDisabled === true && config.networkTrafficCapture !== void 0) {
|
|
@@ -14279,6 +14289,7 @@ var automationRunConfigSchema = automationRunConfigBaseSchema.superRefine((confi
|
|
|
14279
14289
|
});
|
|
14280
14290
|
var automationRunStartConfigSchema = automationRunConfigBaseSchema.omit({
|
|
14281
14291
|
allowPointOfNoReturnOverride: true,
|
|
14292
|
+
automationVersionPinned: true,
|
|
14282
14293
|
credentialVariableResourcePools: true,
|
|
14283
14294
|
implicitNetworkTrafficRecordingDecision: true,
|
|
14284
14295
|
networkTrafficCapture: true,
|
|
@@ -14327,13 +14338,13 @@ function getMentionedStandardCommand(instructions) {
|
|
|
14327
14338
|
const normalizedInstructions = instructions.toLowerCase();
|
|
14328
14339
|
return STANDARD_COMMAND_NAMES.find((commandName) => normalizedInstructions.includes(commandName.toLowerCase())) ?? null;
|
|
14329
14340
|
}
|
|
14330
|
-
function assertCustomInstructionsCommand({ commands, path:
|
|
14331
|
-
const customCommands = commands.flatMap((command, commandIndex) => command["commandName"] === "custom" ? [{ command, path: `${
|
|
14341
|
+
function assertCustomInstructionsCommand({ commands, path: path9 }) {
|
|
14342
|
+
const customCommands = commands.flatMap((command, commandIndex) => command["commandName"] === "custom" ? [{ command, path: `${path9}[${commandIndex.toString()}]` }] : []);
|
|
14332
14343
|
if (customCommands.length === 0) {
|
|
14333
14344
|
return;
|
|
14334
14345
|
}
|
|
14335
14346
|
if (customCommands.length > MAX_CUSTOM_COMMAND_COUNT) {
|
|
14336
|
-
throw createInvalidValueError(`${
|
|
14347
|
+
throw createInvalidValueError(`${path9} contains ${customCommands.length.toString()} custom commands. Use at most one short custom command per agent. Split policy, decision, outreach, and multi-step work into catalog commands or child agents instead.`);
|
|
14337
14348
|
}
|
|
14338
14349
|
const [customCommand] = customCommands;
|
|
14339
14350
|
if (!customCommand) {
|
|
@@ -14387,27 +14398,35 @@ function createOperationSpec(spec) {
|
|
|
14387
14398
|
}
|
|
14388
14399
|
|
|
14389
14400
|
// ../mcp-registry/src/operation-specs.ts
|
|
14401
|
+
var AUTOMATION_BRANCH_NAME_PATTERN = /^[\da-z]+(?:-[\da-z]+)*$/u;
|
|
14402
|
+
var AUTOMATION_BRANCH_NAME_MESSAGE = 'Branch name must use lowercase letters or numbers separated by single dashes (for example, "release-2").';
|
|
14390
14403
|
function stringOption({
|
|
14404
|
+
clientOnly = false,
|
|
14391
14405
|
description,
|
|
14392
14406
|
flagName,
|
|
14393
14407
|
inputKey,
|
|
14394
|
-
required = false
|
|
14408
|
+
required = false,
|
|
14409
|
+
valueHint
|
|
14395
14410
|
}) {
|
|
14396
14411
|
return {
|
|
14412
|
+
...clientOnly ? { clientOnly: true } : {},
|
|
14397
14413
|
description,
|
|
14398
14414
|
flagName,
|
|
14399
14415
|
inputKey,
|
|
14400
14416
|
required,
|
|
14417
|
+
...valueHint ? { valueHint } : {},
|
|
14401
14418
|
valueType: "string"
|
|
14402
14419
|
};
|
|
14403
14420
|
}
|
|
14404
14421
|
function numberOption({
|
|
14422
|
+
clientOnly = false,
|
|
14405
14423
|
description,
|
|
14406
14424
|
flagName,
|
|
14407
14425
|
inputKey,
|
|
14408
14426
|
required = false
|
|
14409
14427
|
}) {
|
|
14410
14428
|
return {
|
|
14429
|
+
...clientOnly ? { clientOnly: true } : {},
|
|
14411
14430
|
description,
|
|
14412
14431
|
flagName,
|
|
14413
14432
|
inputKey,
|
|
@@ -14416,11 +14435,13 @@ function numberOption({
|
|
|
14416
14435
|
};
|
|
14417
14436
|
}
|
|
14418
14437
|
function booleanOption({
|
|
14438
|
+
clientOnly = false,
|
|
14419
14439
|
description,
|
|
14420
14440
|
flagName,
|
|
14421
14441
|
inputKey
|
|
14422
14442
|
}) {
|
|
14423
14443
|
return {
|
|
14444
|
+
...clientOnly ? { clientOnly: true } : {},
|
|
14424
14445
|
description,
|
|
14425
14446
|
flagName,
|
|
14426
14447
|
inputKey,
|
|
@@ -14458,13 +14479,79 @@ function jsonOption({
|
|
|
14458
14479
|
};
|
|
14459
14480
|
}
|
|
14460
14481
|
var jsonObjectSchema = z25.record(z25.string(), z25.unknown());
|
|
14482
|
+
var evalRunStatusSchema = z25.enum([
|
|
14483
|
+
"QUEUED",
|
|
14484
|
+
"RUNNING",
|
|
14485
|
+
"COMPLETE",
|
|
14486
|
+
"FAILED",
|
|
14487
|
+
"CANCELLED"
|
|
14488
|
+
]);
|
|
14489
|
+
var evalInputChoicesSchema = z25.record(
|
|
14490
|
+
z25.string(),
|
|
14491
|
+
z25.array(z25.unknown()).min(1)
|
|
14492
|
+
);
|
|
14493
|
+
var registeredEvalRunInputSchema = z25.object({
|
|
14494
|
+
description: z25.string().min(1).optional(),
|
|
14495
|
+
input: evalInputChoicesSchema,
|
|
14496
|
+
maxConcurrency: z25.number().int().positive().default(1),
|
|
14497
|
+
name: z25.string().min(1).optional(),
|
|
14498
|
+
repeatCount: z25.number().int().positive().default(1),
|
|
14499
|
+
slug: z25.string().min(1),
|
|
14500
|
+
tags: z25.array(z25.string().min(1)).default([])
|
|
14501
|
+
});
|
|
14502
|
+
var registeredEvalSelection = ` slug
|
|
14503
|
+
name
|
|
14504
|
+
description
|
|
14505
|
+
tags
|
|
14506
|
+
version
|
|
14507
|
+
inputSchema`;
|
|
14508
|
+
var evalRunSelection = ` id
|
|
14509
|
+
createdAt
|
|
14510
|
+
updatedAt
|
|
14511
|
+
userId
|
|
14512
|
+
slug
|
|
14513
|
+
evalName
|
|
14514
|
+
evalDescription
|
|
14515
|
+
evalTags
|
|
14516
|
+
evalVersion
|
|
14517
|
+
input
|
|
14518
|
+
name
|
|
14519
|
+
description
|
|
14520
|
+
tags
|
|
14521
|
+
scorerSlugs
|
|
14522
|
+
maxConcurrency
|
|
14523
|
+
repeatCount
|
|
14524
|
+
acknowledgedTrialCount
|
|
14525
|
+
idempotencyKey
|
|
14526
|
+
dashboardUrl
|
|
14527
|
+
workflowId
|
|
14528
|
+
workflowRunId
|
|
14529
|
+
status
|
|
14530
|
+
startedAt
|
|
14531
|
+
finishedAt
|
|
14532
|
+
trialStatusCounts {
|
|
14533
|
+
queued
|
|
14534
|
+
running
|
|
14535
|
+
complete
|
|
14536
|
+
failed
|
|
14537
|
+
cancelled
|
|
14538
|
+
}`;
|
|
14539
|
+
var evalRunExportSelection = ` exportId
|
|
14540
|
+
evalRunId
|
|
14541
|
+
status
|
|
14542
|
+
workflowId
|
|
14543
|
+
workflowRunId
|
|
14544
|
+
fileName
|
|
14545
|
+
trialCount
|
|
14546
|
+
downloadUrl
|
|
14547
|
+
error`;
|
|
14461
14548
|
function isRecord3(value) {
|
|
14462
14549
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14463
14550
|
}
|
|
14464
14551
|
function validateCustomInstructionsCommands({
|
|
14465
14552
|
commands,
|
|
14466
14553
|
ctx,
|
|
14467
|
-
path:
|
|
14554
|
+
path: path9
|
|
14468
14555
|
}) {
|
|
14469
14556
|
if (!Array.isArray(commands)) {
|
|
14470
14557
|
return;
|
|
@@ -14472,14 +14559,14 @@ function validateCustomInstructionsCommands({
|
|
|
14472
14559
|
const validationResult = fromThrowable(() => {
|
|
14473
14560
|
assertCustomInstructionsCommand({
|
|
14474
14561
|
commands: commands.map((command) => isRecord3(command) ? command : {}),
|
|
14475
|
-
path:
|
|
14562
|
+
path: path9.join(".").replaceAll(/\.(?<index>\d+)/gu, "[$<index>]")
|
|
14476
14563
|
});
|
|
14477
14564
|
}, "invalid-custom-instructions-command");
|
|
14478
14565
|
if (isErr(validationResult)) {
|
|
14479
14566
|
ctx.addIssue({
|
|
14480
14567
|
code: "custom",
|
|
14481
14568
|
message: `${getErrorMessage2(validationResult.error.cause)} Run mgcl catalog commands to find the standard command for this work.`,
|
|
14482
|
-
path:
|
|
14569
|
+
path: path9
|
|
14483
14570
|
});
|
|
14484
14571
|
}
|
|
14485
14572
|
}
|
|
@@ -14715,6 +14802,7 @@ ${agentLimitationsSelection}
|
|
|
14715
14802
|
systemPrompt
|
|
14716
14803
|
additionalSystemPrompt
|
|
14717
14804
|
ignoreUnstableSessionState
|
|
14805
|
+
stepFollowingVerification
|
|
14718
14806
|
resourcePools {
|
|
14719
14807
|
id
|
|
14720
14808
|
type
|
|
@@ -14784,6 +14872,7 @@ ${agentLimitationsSelection}
|
|
|
14784
14872
|
systemPrompt
|
|
14785
14873
|
additionalSystemPrompt
|
|
14786
14874
|
ignoreUnstableSessionState
|
|
14875
|
+
stepFollowingVerification
|
|
14787
14876
|
}
|
|
14788
14877
|
isCurrent
|
|
14789
14878
|
}
|
|
@@ -15493,6 +15582,193 @@ query GetAutomations($ids: [ID!]!) {
|
|
|
15493
15582
|
}
|
|
15494
15583
|
}
|
|
15495
15584
|
}
|
|
15585
|
+
}`
|
|
15586
|
+
}),
|
|
15587
|
+
createOperationSpec({
|
|
15588
|
+
operationName: "ListAutomationBranches",
|
|
15589
|
+
kind: "query",
|
|
15590
|
+
inputSchema: z25.object({
|
|
15591
|
+
automationId: z25.string().min(1)
|
|
15592
|
+
}),
|
|
15593
|
+
cli: {
|
|
15594
|
+
name: "list-automation-branches",
|
|
15595
|
+
path: ["automations", "branches", "list"],
|
|
15596
|
+
description: "List active branches for an automation.",
|
|
15597
|
+
resultKey: "automationBranches",
|
|
15598
|
+
options: [
|
|
15599
|
+
stringOption({
|
|
15600
|
+
inputKey: "automationId",
|
|
15601
|
+
flagName: "automation-id",
|
|
15602
|
+
description: "Automation ID.",
|
|
15603
|
+
required: true
|
|
15604
|
+
})
|
|
15605
|
+
]
|
|
15606
|
+
},
|
|
15607
|
+
mcp: { fileName: "automationBranches.graphql" },
|
|
15608
|
+
document: `# List active automation branches. Deleted branches are excluded.
|
|
15609
|
+
query ListAutomationBranches($automationId: ID!) {
|
|
15610
|
+
automationBranches(automationId: $automationId) {
|
|
15611
|
+
branchId
|
|
15612
|
+
automationId
|
|
15613
|
+
name
|
|
15614
|
+
headVersionId
|
|
15615
|
+
forkedFromBranchId
|
|
15616
|
+
forkedFromVersionId
|
|
15617
|
+
createdAt
|
|
15618
|
+
updatedAt
|
|
15619
|
+
}
|
|
15620
|
+
}`
|
|
15621
|
+
}),
|
|
15622
|
+
createOperationSpec({
|
|
15623
|
+
operationName: "CreateAutomationBranch",
|
|
15624
|
+
kind: "mutation",
|
|
15625
|
+
inputSchema: z25.object({
|
|
15626
|
+
automationId: z25.string().min(1),
|
|
15627
|
+
name: z25.string().regex(AUTOMATION_BRANCH_NAME_PATTERN, AUTOMATION_BRANCH_NAME_MESSAGE),
|
|
15628
|
+
sourceBranchId: z25.string().min(1).optional(),
|
|
15629
|
+
sourceVersionId: z25.string().min(1).optional()
|
|
15630
|
+
}),
|
|
15631
|
+
cli: {
|
|
15632
|
+
name: "create-automation-branch",
|
|
15633
|
+
path: ["automations", "branches", "create"],
|
|
15634
|
+
description: "Create an automation branch. The source defaults to the current main head.",
|
|
15635
|
+
resultKey: "createAutomationBranch",
|
|
15636
|
+
options: [
|
|
15637
|
+
stringOption({
|
|
15638
|
+
inputKey: "automationId",
|
|
15639
|
+
flagName: "automation-id",
|
|
15640
|
+
description: "Automation ID.",
|
|
15641
|
+
required: true
|
|
15642
|
+
}),
|
|
15643
|
+
stringOption({
|
|
15644
|
+
inputKey: "name",
|
|
15645
|
+
flagName: "name",
|
|
15646
|
+
description: 'Lowercase branch name with single dashes between words or numbers (for example, "release-2").',
|
|
15647
|
+
required: true
|
|
15648
|
+
}),
|
|
15649
|
+
stringOption({
|
|
15650
|
+
inputKey: "sourceBranchId",
|
|
15651
|
+
flagName: "source-branch-id",
|
|
15652
|
+
description: "Optional source branch ID. Omit to branch from main."
|
|
15653
|
+
}),
|
|
15654
|
+
stringOption({
|
|
15655
|
+
inputKey: "sourceVersionId",
|
|
15656
|
+
flagName: "source-version-id",
|
|
15657
|
+
description: "Optional version in the selected source history. Omit to use its head."
|
|
15658
|
+
})
|
|
15659
|
+
]
|
|
15660
|
+
},
|
|
15661
|
+
mcp: { fileName: "createAutomationBranch.graphql" },
|
|
15662
|
+
document: `# Create an automation branch from main or another branch.
|
|
15663
|
+
mutation CreateAutomationBranch(
|
|
15664
|
+
$automationId: ID!
|
|
15665
|
+
$name: String!
|
|
15666
|
+
$sourceBranchId: ID
|
|
15667
|
+
$sourceVersionId: ID
|
|
15668
|
+
) {
|
|
15669
|
+
createAutomationBranch(
|
|
15670
|
+
automationId: $automationId
|
|
15671
|
+
name: $name
|
|
15672
|
+
sourceBranchId: $sourceBranchId
|
|
15673
|
+
sourceVersionId: $sourceVersionId
|
|
15674
|
+
) {
|
|
15675
|
+
branchId
|
|
15676
|
+
automationId
|
|
15677
|
+
name
|
|
15678
|
+
headVersionId
|
|
15679
|
+
forkedFromBranchId
|
|
15680
|
+
forkedFromVersionId
|
|
15681
|
+
createdAt
|
|
15682
|
+
updatedAt
|
|
15683
|
+
}
|
|
15684
|
+
}`
|
|
15685
|
+
}),
|
|
15686
|
+
createOperationSpec({
|
|
15687
|
+
operationName: "GetAutomationBranch",
|
|
15688
|
+
kind: "query",
|
|
15689
|
+
inputSchema: z25.object({
|
|
15690
|
+
automationId: z25.string().min(1),
|
|
15691
|
+
branchId: z25.string().min(1)
|
|
15692
|
+
}),
|
|
15693
|
+
cli: {
|
|
15694
|
+
branchContext: "required",
|
|
15695
|
+
name: "get-automation-branch",
|
|
15696
|
+
path: ["automations", "branches", "get"],
|
|
15697
|
+
description: "Get the hydrated snapshot at an automation branch head without authentication secrets.",
|
|
15698
|
+
resultKey: "automationBranchHead",
|
|
15699
|
+
options: [
|
|
15700
|
+
stringOption({
|
|
15701
|
+
inputKey: "automationId",
|
|
15702
|
+
flagName: "automation-id",
|
|
15703
|
+
description: "Automation ID.",
|
|
15704
|
+
required: true
|
|
15705
|
+
})
|
|
15706
|
+
]
|
|
15707
|
+
},
|
|
15708
|
+
mcp: { fileName: "automationBranchHead.graphql" },
|
|
15709
|
+
document: `# Get the hydrated snapshot at an active branch head. Authentication secrets are excluded.
|
|
15710
|
+
query GetAutomationBranch($automationId: ID!, $branchId: ID!) {
|
|
15711
|
+
automationBranchHead(automationId: $automationId, branchId: $branchId) {
|
|
15712
|
+
branchId
|
|
15713
|
+
headVersionId
|
|
15714
|
+
automation
|
|
15715
|
+
}
|
|
15716
|
+
}`
|
|
15717
|
+
}),
|
|
15718
|
+
createOperationSpec({
|
|
15719
|
+
operationName: "MergeAutomationBranch",
|
|
15720
|
+
kind: "mutation",
|
|
15721
|
+
inputSchema: z25.object({
|
|
15722
|
+
automationId: z25.string().min(1),
|
|
15723
|
+
branchId: z25.string().min(1)
|
|
15724
|
+
}),
|
|
15725
|
+
cli: {
|
|
15726
|
+
branchContext: "required",
|
|
15727
|
+
name: "merge-automation-branch",
|
|
15728
|
+
path: ["automations", "branches", "merge"],
|
|
15729
|
+
description: "Preview and merge a branch into main when every change is conflict-free.",
|
|
15730
|
+
resultKey: "mergeAutomationBranch",
|
|
15731
|
+
options: [
|
|
15732
|
+
stringOption({
|
|
15733
|
+
inputKey: "automationId",
|
|
15734
|
+
flagName: "automation-id",
|
|
15735
|
+
description: "Automation ID.",
|
|
15736
|
+
required: true
|
|
15737
|
+
})
|
|
15738
|
+
]
|
|
15739
|
+
},
|
|
15740
|
+
mcp: { fileName: "mergeAutomationBranch.graphql" },
|
|
15741
|
+
document: `# Preview a branch merge and apply it only when there are no conflicts.
|
|
15742
|
+
mutation MergeAutomationBranch($automationId: ID!, $branchId: ID!) {
|
|
15743
|
+
mergeAutomationBranch(automationId: $automationId, branchId: $branchId) {
|
|
15744
|
+
automationId
|
|
15745
|
+
branchId
|
|
15746
|
+
status
|
|
15747
|
+
sourceBranchDeleted
|
|
15748
|
+
preview {
|
|
15749
|
+
baseVersionId
|
|
15750
|
+
sourceVersionId
|
|
15751
|
+
targetVersionId
|
|
15752
|
+
changes {
|
|
15753
|
+
id
|
|
15754
|
+
group
|
|
15755
|
+
label
|
|
15756
|
+
status
|
|
15757
|
+
}
|
|
15758
|
+
}
|
|
15759
|
+
conflicts {
|
|
15760
|
+
id
|
|
15761
|
+
group
|
|
15762
|
+
label
|
|
15763
|
+
status
|
|
15764
|
+
}
|
|
15765
|
+
applyResult {
|
|
15766
|
+
draftVersionId
|
|
15767
|
+
lastSavedAt
|
|
15768
|
+
publishedVersionId
|
|
15769
|
+
wasRebased
|
|
15770
|
+
}
|
|
15771
|
+
}
|
|
15496
15772
|
}`
|
|
15497
15773
|
}),
|
|
15498
15774
|
createOperationSpec({
|
|
@@ -15747,9 +16023,11 @@ query GetAutomationWorkbenchCredentials {
|
|
|
15747
16023
|
operationName: "GetAutomationWorkbenchDiagnostics",
|
|
15748
16024
|
kind: "query",
|
|
15749
16025
|
inputSchema: z25.object({
|
|
15750
|
-
draftAutomationId: z25.string().min(1)
|
|
16026
|
+
draftAutomationId: z25.string().min(1),
|
|
16027
|
+
branchId: z25.string().min(1).optional()
|
|
15751
16028
|
}),
|
|
15752
16029
|
cli: {
|
|
16030
|
+
branchContext: "optional",
|
|
15753
16031
|
name: "get-automation-workbench-diagnostics",
|
|
15754
16032
|
path: ["workbench", "diagnostics"],
|
|
15755
16033
|
description: "Fetch a compact draft automation graph plus workbench diagnostics.",
|
|
@@ -15765,8 +16043,10 @@ query GetAutomationWorkbenchCredentials {
|
|
|
15765
16043
|
},
|
|
15766
16044
|
mcp: { fileName: "automationWorkbenchDiagnostics.graphql" },
|
|
15767
16045
|
document: `# Query automation workbench diagnostics for a draft automation.
|
|
15768
|
-
query GetAutomationWorkbenchDiagnostics($draftAutomationId: ID
|
|
15769
|
-
automationWorkbenchDiagnostics(draftAutomationId: $draftAutomationId) {
|
|
16046
|
+
query GetAutomationWorkbenchDiagnostics($draftAutomationId: ID!, $branchId: ID) {
|
|
16047
|
+
automationWorkbenchDiagnostics(draftAutomationId: $draftAutomationId, branchId: $branchId) {
|
|
16048
|
+
branchId
|
|
16049
|
+
headVersionId
|
|
15770
16050
|
summary {
|
|
15771
16051
|
draftAutomationId
|
|
15772
16052
|
name
|
|
@@ -16111,10 +16391,19 @@ query GetAutomationWorkbenchAwaitRunCompletion(
|
|
|
16111
16391
|
inputSchema: z25.object({
|
|
16112
16392
|
automationRunId: z25.string().min(1),
|
|
16113
16393
|
draftAutomationId: z25.string().min(1).optional(),
|
|
16394
|
+
branchId: z25.string().min(1).optional(),
|
|
16114
16395
|
minConfidence: z25.number().min(0).max(1).optional(),
|
|
16115
16396
|
includeSensitive: z25.boolean().optional()
|
|
16397
|
+
}).superRefine((input, ctx) => {
|
|
16398
|
+
if (input.branchId && !input.draftAutomationId) {
|
|
16399
|
+
ctx.addIssue({
|
|
16400
|
+
code: z25.ZodIssueCode.custom,
|
|
16401
|
+
message: "--branch-id requires --draft-automation-id."
|
|
16402
|
+
});
|
|
16403
|
+
}
|
|
16116
16404
|
}),
|
|
16117
16405
|
cli: {
|
|
16406
|
+
branchContext: "optional",
|
|
16118
16407
|
name: "get-automation-workbench-schema-suggestions",
|
|
16119
16408
|
path: ["workbench", "schema-suggestions"],
|
|
16120
16409
|
description: "Heuristic suggestions for schema fields the agent observed on browser pages but were not declared in the input schema.",
|
|
@@ -16149,15 +16438,19 @@ query GetAutomationWorkbenchAwaitRunCompletion(
|
|
|
16149
16438
|
query GetAutomationWorkbenchSchemaSuggestions(
|
|
16150
16439
|
$automationRunId: ID!
|
|
16151
16440
|
$draftAutomationId: ID
|
|
16441
|
+
$branchId: ID
|
|
16152
16442
|
$minConfidence: Float
|
|
16153
16443
|
$includeSensitive: Boolean
|
|
16154
16444
|
) {
|
|
16155
16445
|
automationWorkbenchSchemaSuggestions(
|
|
16156
16446
|
automationRunId: $automationRunId
|
|
16157
16447
|
draftAutomationId: $draftAutomationId
|
|
16448
|
+
branchId: $branchId
|
|
16158
16449
|
minConfidence: $minConfidence
|
|
16159
16450
|
includeSensitive: $includeSensitive
|
|
16160
16451
|
) {
|
|
16452
|
+
branchId
|
|
16453
|
+
headVersionId
|
|
16161
16454
|
kind
|
|
16162
16455
|
fieldName
|
|
16163
16456
|
fieldLabel
|
|
@@ -16596,6 +16889,7 @@ mutation ResumeAutomationRun($automationRunId: ID!, $message: String) {
|
|
|
16596
16889
|
kind: "mutation",
|
|
16597
16890
|
inputSchema: z25.object({
|
|
16598
16891
|
draftAutomationId: z25.string().min(1),
|
|
16892
|
+
branchId: z25.string().min(1).optional(),
|
|
16599
16893
|
agentId: z25.string().min(1),
|
|
16600
16894
|
idempotencyKey: z25.string().min(1),
|
|
16601
16895
|
input: z25.unknown().optional(),
|
|
@@ -16605,6 +16899,7 @@ mutation ResumeAutomationRun($automationRunId: ID!, $message: String) {
|
|
|
16605
16899
|
consistencyCheckCount: z25.number().int().optional()
|
|
16606
16900
|
}),
|
|
16607
16901
|
cli: {
|
|
16902
|
+
branchContext: "optional",
|
|
16608
16903
|
name: "run-draft-automation",
|
|
16609
16904
|
path: ["automations", "run-draft"],
|
|
16610
16905
|
description: "Run a draft automation with an explicit trigger agent.",
|
|
@@ -16660,6 +16955,7 @@ mutation ResumeAutomationRun($automationRunId: ID!, $message: String) {
|
|
|
16660
16955
|
# \`draftAutomationId\` is the draft automation entity ID (\`Automation.id\`), not \`draftVersionId\`.
|
|
16661
16956
|
mutation RunDraftAutomation(
|
|
16662
16957
|
$draftAutomationId: ID!
|
|
16958
|
+
$branchId: ID
|
|
16663
16959
|
$agentId: ID!
|
|
16664
16960
|
$idempotencyKey: String!
|
|
16665
16961
|
$input: JSON
|
|
@@ -16670,6 +16966,7 @@ mutation RunDraftAutomation(
|
|
|
16670
16966
|
) {
|
|
16671
16967
|
runDraftAutomation(
|
|
16672
16968
|
draftAutomationId: $draftAutomationId
|
|
16969
|
+
branchId: $branchId
|
|
16673
16970
|
agentId: $agentId
|
|
16674
16971
|
idempotencyKey: $idempotencyKey
|
|
16675
16972
|
input: $input
|
|
@@ -16679,6 +16976,9 @@ mutation RunDraftAutomation(
|
|
|
16679
16976
|
consistencyCheckCount: $consistencyCheckCount
|
|
16680
16977
|
) {
|
|
16681
16978
|
automationRunId
|
|
16979
|
+
automationVersionId
|
|
16980
|
+
branchId
|
|
16981
|
+
headVersionId
|
|
16682
16982
|
workflowId
|
|
16683
16983
|
workflowRunId
|
|
16684
16984
|
}
|
|
@@ -16715,10 +17015,12 @@ mutation StopAutomationRun($automationRunId: ID!) {
|
|
|
16715
17015
|
kind: "mutation",
|
|
16716
17016
|
inputSchema: z25.object({
|
|
16717
17017
|
draftAutomationId: z25.string().min(1),
|
|
17018
|
+
branchId: z25.string().min(1).optional(),
|
|
16718
17019
|
expectedLastSavedAt: z25.string().optional(),
|
|
16719
17020
|
operations: automationPatchOperationsSchema
|
|
16720
17021
|
}),
|
|
16721
17022
|
cli: {
|
|
17023
|
+
branchContext: "optional",
|
|
16722
17024
|
name: "preview-automation-patch",
|
|
16723
17025
|
path: ["workbench", "patch", "preview"],
|
|
16724
17026
|
description: "Preview semantic workbench patch operations without saving the draft.",
|
|
@@ -16742,13 +17044,17 @@ mutation StopAutomationRun($automationRunId: ID!) {
|
|
|
16742
17044
|
document: `# Preview semantic automation patch operations without writing.
|
|
16743
17045
|
mutation PreviewAutomationPatch(
|
|
16744
17046
|
$draftAutomationId: ID!
|
|
17047
|
+
$branchId: ID
|
|
16745
17048
|
$operations: [AutomationWorkbenchPatchOperationInput!]!
|
|
16746
17049
|
) {
|
|
16747
17050
|
previewAutomationPatch(
|
|
16748
17051
|
draftAutomationId: $draftAutomationId
|
|
17052
|
+
branchId: $branchId
|
|
16749
17053
|
operations: $operations
|
|
16750
17054
|
) {
|
|
16751
17055
|
draftAutomationId
|
|
17056
|
+
branchId
|
|
17057
|
+
headVersionId
|
|
16752
17058
|
applied
|
|
16753
17059
|
updateInput
|
|
16754
17060
|
before {
|
|
@@ -16820,6 +17126,83 @@ mutation PreviewAutomationPatch(
|
|
|
16820
17126
|
name
|
|
16821
17127
|
}
|
|
16822
17128
|
}
|
|
17129
|
+
}`
|
|
17130
|
+
}),
|
|
17131
|
+
createOperationSpec({
|
|
17132
|
+
operationName: "ValidateAutomationPatchReadiness",
|
|
17133
|
+
kind: "mutation",
|
|
17134
|
+
inputSchema: z25.object({
|
|
17135
|
+
targetDraftAutomationId: z25.string().min(1).optional(),
|
|
17136
|
+
newAutomationName: z25.string().min(1).optional(),
|
|
17137
|
+
branchId: z25.string().min(1).optional(),
|
|
17138
|
+
operations: automationPatchOperationsSchema
|
|
17139
|
+
}).superRefine((input, ctx) => {
|
|
17140
|
+
if (input.branchId && !input.targetDraftAutomationId) {
|
|
17141
|
+
ctx.addIssue({
|
|
17142
|
+
code: z25.ZodIssueCode.custom,
|
|
17143
|
+
message: "--branch-id requires --target-draft-automation-id."
|
|
17144
|
+
});
|
|
17145
|
+
}
|
|
17146
|
+
}),
|
|
17147
|
+
cli: {
|
|
17148
|
+
branchContext: "optional",
|
|
17149
|
+
name: "validate-automation-patch-readiness",
|
|
17150
|
+
path: ["workbench", "patch", "readiness"],
|
|
17151
|
+
description: "Validate workbench patch readiness without changing an automation.",
|
|
17152
|
+
resultKey: "validateAutomationPatchReadiness",
|
|
17153
|
+
options: [
|
|
17154
|
+
stringOption({
|
|
17155
|
+
inputKey: "targetDraftAutomationId",
|
|
17156
|
+
flagName: "target-draft-automation-id",
|
|
17157
|
+
description: "Existing draft automation ID to validate."
|
|
17158
|
+
}),
|
|
17159
|
+
stringOption({
|
|
17160
|
+
inputKey: "newAutomationName",
|
|
17161
|
+
flagName: "new-automation-name",
|
|
17162
|
+
description: "New automation name when validating without an existing target."
|
|
17163
|
+
}),
|
|
17164
|
+
jsonOption({
|
|
17165
|
+
inputKey: "operations",
|
|
17166
|
+
flagName: "operations-json",
|
|
17167
|
+
description: `Automation patch operations array. ${COMMAND_CATALOG_HELP}`,
|
|
17168
|
+
required: true
|
|
17169
|
+
})
|
|
17170
|
+
]
|
|
17171
|
+
},
|
|
17172
|
+
mcp: { fileName: "validateAutomationPatchReadiness.graphql" },
|
|
17173
|
+
document: `# Validate automation patch readiness without writing.
|
|
17174
|
+
mutation ValidateAutomationPatchReadiness(
|
|
17175
|
+
$targetDraftAutomationId: ID
|
|
17176
|
+
$newAutomationName: String
|
|
17177
|
+
$branchId: ID
|
|
17178
|
+
$operations: [AutomationWorkbenchPatchOperationInput!]!
|
|
17179
|
+
) {
|
|
17180
|
+
validateAutomationPatchReadiness(
|
|
17181
|
+
targetDraftAutomationId: $targetDraftAutomationId
|
|
17182
|
+
newAutomationName: $newAutomationName
|
|
17183
|
+
branchId: $branchId
|
|
17184
|
+
operations: $operations
|
|
17185
|
+
) {
|
|
17186
|
+
targetDraftAutomationId
|
|
17187
|
+
branchId
|
|
17188
|
+
headVersionId
|
|
17189
|
+
issues {
|
|
17190
|
+
severity
|
|
17191
|
+
code
|
|
17192
|
+
message
|
|
17193
|
+
agentId
|
|
17194
|
+
localId
|
|
17195
|
+
path
|
|
17196
|
+
repair
|
|
17197
|
+
relatedAgentIds
|
|
17198
|
+
relatedLocalIds
|
|
17199
|
+
}
|
|
17200
|
+
createdAgents {
|
|
17201
|
+
localId
|
|
17202
|
+
id
|
|
17203
|
+
name
|
|
17204
|
+
}
|
|
17205
|
+
}
|
|
16823
17206
|
}`
|
|
16824
17207
|
}),
|
|
16825
17208
|
createOperationSpec({
|
|
@@ -16827,9 +17210,12 @@ mutation PreviewAutomationPatch(
|
|
|
16827
17210
|
kind: "mutation",
|
|
16828
17211
|
inputSchema: z25.object({
|
|
16829
17212
|
draftAutomationId: z25.string().min(1),
|
|
17213
|
+
branchId: z25.string().min(1).optional(),
|
|
17214
|
+
expectedLastSavedAt: z25.string().optional(),
|
|
16830
17215
|
operations: automationPatchOperationsSchema
|
|
16831
17216
|
}),
|
|
16832
17217
|
cli: {
|
|
17218
|
+
branchContext: "optional",
|
|
16833
17219
|
name: "apply-automation-patch",
|
|
16834
17220
|
path: ["workbench", "patch", "apply"],
|
|
16835
17221
|
description: "Apply semantic workbench patch operations through the versioned save path.",
|
|
@@ -16858,15 +17244,19 @@ mutation PreviewAutomationPatch(
|
|
|
16858
17244
|
document: `# Apply semantic automation patch operations through the versioned save path.
|
|
16859
17245
|
mutation ApplyAutomationPatch(
|
|
16860
17246
|
$draftAutomationId: ID!
|
|
17247
|
+
$branchId: ID
|
|
16861
17248
|
$operations: [AutomationWorkbenchPatchOperationInput!]!
|
|
16862
17249
|
$expectedLastSavedAt: String
|
|
16863
17250
|
) {
|
|
16864
17251
|
applyAutomationPatch(
|
|
16865
17252
|
draftAutomationId: $draftAutomationId
|
|
17253
|
+
branchId: $branchId
|
|
16866
17254
|
operations: $operations
|
|
16867
17255
|
expectedLastSavedAt: $expectedLastSavedAt
|
|
16868
17256
|
) {
|
|
16869
17257
|
draftAutomationId
|
|
17258
|
+
branchId
|
|
17259
|
+
headVersionId
|
|
16870
17260
|
applied
|
|
16871
17261
|
updateInput
|
|
16872
17262
|
before {
|
|
@@ -16945,9 +17335,11 @@ mutation ApplyAutomationPatch(
|
|
|
16945
17335
|
kind: "mutation",
|
|
16946
17336
|
inputSchema: z25.object({
|
|
16947
17337
|
id: z25.string().min(1),
|
|
17338
|
+
branchId: z25.string().min(1).optional(),
|
|
16948
17339
|
input: updateAutomationInputSchema
|
|
16949
17340
|
}),
|
|
16950
17341
|
cli: {
|
|
17342
|
+
branchContext: "optional",
|
|
16951
17343
|
name: "update-automation-by-id",
|
|
16952
17344
|
path: ["automations", "update"],
|
|
16953
17345
|
description: "Update an automation.",
|
|
@@ -16974,102 +17366,865 @@ mutation ApplyAutomationPatch(
|
|
|
16974
17366
|
# config.storeSchema remains additive. Use removeStoreSchemaPaths to delete named properties (and combine it with config.storeSchema for an atomic rename), or replaceStoreSchema for an exact replacement. replaceStoreSchema cannot be combined with either of those fields.
|
|
16975
17367
|
# Destructive Store schema changes are rejected when the final agent set still references a removed property. Rewrite those agent references in the same update or leave the property in place.
|
|
16976
17368
|
# Returns only id and lastSavedAt for MCP tool simplicity
|
|
16977
|
-
mutation UpdateAutomationById($id: ID!, $input: UpdateAutomationInput!) {
|
|
16978
|
-
updateAutomation(id: $id, input: $input) {
|
|
17369
|
+
mutation UpdateAutomationById($id: ID!, $branchId: ID, $input: UpdateAutomationInput!) {
|
|
17370
|
+
updateAutomation(id: $id, branchId: $branchId, input: $input) {
|
|
16979
17371
|
id
|
|
17372
|
+
branchId
|
|
17373
|
+
headVersionId
|
|
16980
17374
|
lastSavedAt
|
|
16981
17375
|
}
|
|
16982
17376
|
}`
|
|
16983
|
-
})
|
|
16984
|
-
|
|
16985
|
-
|
|
16986
|
-
|
|
16987
|
-
|
|
16988
|
-
|
|
16989
|
-
|
|
16990
|
-
|
|
16991
|
-
|
|
16992
|
-
|
|
16993
|
-
|
|
16994
|
-
|
|
16995
|
-
|
|
16996
|
-
|
|
16997
|
-
|
|
16998
|
-
|
|
16999
|
-
|
|
17000
|
-
|
|
17001
|
-
|
|
17002
|
-
|
|
17003
|
-
|
|
17004
|
-
|
|
17005
|
-
|
|
17006
|
-
|
|
17007
|
-
}
|
|
17008
|
-
|
|
17009
|
-
|
|
17010
|
-
|
|
17011
|
-
|
|
17012
|
-
|
|
17013
|
-
|
|
17014
|
-
|
|
17015
|
-
|
|
17016
|
-
|
|
17017
|
-
|
|
17018
|
-
|
|
17019
|
-
|
|
17020
|
-
|
|
17021
|
-
|
|
17022
|
-
|
|
17023
|
-
|
|
17024
|
-
|
|
17025
|
-
|
|
17026
|
-
|
|
17027
|
-
|
|
17028
|
-
|
|
17029
|
-
|
|
17030
|
-
})
|
|
17031
|
-
|
|
17032
|
-
|
|
17033
|
-
|
|
17034
|
-
|
|
17035
|
-
|
|
17036
|
-
|
|
17037
|
-
})
|
|
17038
|
-
|
|
17039
|
-
|
|
17040
|
-
|
|
17041
|
-
|
|
17042
|
-
|
|
17043
|
-
|
|
17044
|
-
|
|
17045
|
-
|
|
17046
|
-
|
|
17047
|
-
|
|
17048
|
-
|
|
17049
|
-
|
|
17050
|
-
|
|
17051
|
-
|
|
17052
|
-
|
|
17053
|
-
|
|
17054
|
-
|
|
17055
|
-
|
|
17056
|
-
|
|
17057
|
-
|
|
17058
|
-
|
|
17059
|
-
|
|
17060
|
-
|
|
17061
|
-
|
|
17062
|
-
|
|
17063
|
-
}
|
|
17064
|
-
|
|
17065
|
-
|
|
17066
|
-
|
|
17067
|
-
|
|
17068
|
-
|
|
17069
|
-
|
|
17070
|
-
|
|
17071
|
-
|
|
17072
|
-
|
|
17377
|
+
}),
|
|
17378
|
+
createOperationSpec({
|
|
17379
|
+
operationName: "ListRegisteredEvals",
|
|
17380
|
+
kind: "query",
|
|
17381
|
+
inputSchema: z25.object({}),
|
|
17382
|
+
cli: {
|
|
17383
|
+
name: "list-registered-evals",
|
|
17384
|
+
path: ["evals", "list"],
|
|
17385
|
+
description: "List globally registered eval definitions.",
|
|
17386
|
+
resultKey: "registeredEvals",
|
|
17387
|
+
options: []
|
|
17388
|
+
},
|
|
17389
|
+
mcp: { fileName: "registeredEvals.graphql" },
|
|
17390
|
+
scope: "global",
|
|
17391
|
+
document: `# List globally registered eval definitions available to the authenticated caller
|
|
17392
|
+
query ListRegisteredEvals {
|
|
17393
|
+
registeredEvals {
|
|
17394
|
+
${registeredEvalSelection}
|
|
17395
|
+
}
|
|
17396
|
+
}`
|
|
17397
|
+
}),
|
|
17398
|
+
createOperationSpec({
|
|
17399
|
+
operationName: "GetRegisteredEval",
|
|
17400
|
+
kind: "query",
|
|
17401
|
+
inputSchema: z25.object({ slug: z25.string().min(1) }),
|
|
17402
|
+
cli: {
|
|
17403
|
+
name: "get-registered-eval",
|
|
17404
|
+
path: ["evals", "get"],
|
|
17405
|
+
description: "Get one globally registered eval definition.",
|
|
17406
|
+
resultKey: "registeredEval",
|
|
17407
|
+
options: [
|
|
17408
|
+
stringOption({
|
|
17409
|
+
description: "Registered eval slug.",
|
|
17410
|
+
flagName: "slug",
|
|
17411
|
+
inputKey: "slug",
|
|
17412
|
+
required: true
|
|
17413
|
+
})
|
|
17414
|
+
]
|
|
17415
|
+
},
|
|
17416
|
+
mcp: { fileName: "registeredEval.graphql" },
|
|
17417
|
+
scope: "global",
|
|
17418
|
+
document: `# Get one globally registered eval definition by slug
|
|
17419
|
+
query GetRegisteredEval($slug: String!) {
|
|
17420
|
+
registeredEval(slug: $slug) {
|
|
17421
|
+
${registeredEvalSelection}
|
|
17422
|
+
}
|
|
17423
|
+
}`
|
|
17424
|
+
}),
|
|
17425
|
+
createOperationSpec({
|
|
17426
|
+
operationName: "TestRegisteredEval",
|
|
17427
|
+
kind: "mutation",
|
|
17428
|
+
inputSchema: z25.object({
|
|
17429
|
+
input: jsonObjectSchema,
|
|
17430
|
+
slug: z25.string().min(1)
|
|
17431
|
+
}),
|
|
17432
|
+
cli: {
|
|
17433
|
+
name: "test-registered-eval",
|
|
17434
|
+
path: ["evals", "test-run"],
|
|
17435
|
+
description: "Execute one registered eval input and its scorers without persistence.",
|
|
17436
|
+
resultKey: "testRegisteredEval",
|
|
17437
|
+
options: [
|
|
17438
|
+
stringOption({
|
|
17439
|
+
description: "Registered eval slug.",
|
|
17440
|
+
flagName: "slug",
|
|
17441
|
+
inputKey: "slug",
|
|
17442
|
+
required: true
|
|
17443
|
+
}),
|
|
17444
|
+
jsonOption({
|
|
17445
|
+
description: "Concrete eval input object.",
|
|
17446
|
+
flagName: "input-json",
|
|
17447
|
+
inputKey: "input"
|
|
17448
|
+
}),
|
|
17449
|
+
stringOption({
|
|
17450
|
+
clientOnly: true,
|
|
17451
|
+
description: "Path to a JSON file containing the concrete input.",
|
|
17452
|
+
flagName: "input-file",
|
|
17453
|
+
inputKey: "inputFile"
|
|
17454
|
+
})
|
|
17455
|
+
]
|
|
17456
|
+
},
|
|
17457
|
+
mcp: { fileName: "testRegisteredEval.graphql" },
|
|
17458
|
+
scope: "global",
|
|
17459
|
+
document: `# Execute exactly one registered eval input and its scorers without persistence or automatic retries
|
|
17460
|
+
# COMPLETE and FAILED execution outcomes are returned in the result body
|
|
17461
|
+
mutation TestRegisteredEval($slug: String!, $input: JSON!) {
|
|
17462
|
+
testRegisteredEval(input: { slug: $slug, input: $input }) {
|
|
17463
|
+
status
|
|
17464
|
+
input
|
|
17465
|
+
output
|
|
17466
|
+
scores
|
|
17467
|
+
error {
|
|
17468
|
+
type
|
|
17469
|
+
message
|
|
17470
|
+
}
|
|
17471
|
+
}
|
|
17472
|
+
}`
|
|
17473
|
+
}),
|
|
17474
|
+
createOperationSpec({
|
|
17475
|
+
operationName: "PlanRegisteredEvalRun",
|
|
17476
|
+
kind: "query",
|
|
17477
|
+
inputSchema: registeredEvalRunInputSchema,
|
|
17478
|
+
cli: {
|
|
17479
|
+
name: "plan-registered-eval-run",
|
|
17480
|
+
path: ["evals", "plan-run"],
|
|
17481
|
+
description: "Validate a registered eval run and calculate its exact trial count.",
|
|
17482
|
+
resultKey: "planRegisteredEvalRun",
|
|
17483
|
+
options: [
|
|
17484
|
+
stringOption({
|
|
17485
|
+
description: "Registered eval slug.",
|
|
17486
|
+
flagName: "slug",
|
|
17487
|
+
inputKey: "slug",
|
|
17488
|
+
required: true
|
|
17489
|
+
}),
|
|
17490
|
+
jsonOption({
|
|
17491
|
+
description: "Eval input choices keyed by registered input name.",
|
|
17492
|
+
flagName: "input-json",
|
|
17493
|
+
inputKey: "input"
|
|
17494
|
+
}),
|
|
17495
|
+
stringOption({
|
|
17496
|
+
clientOnly: true,
|
|
17497
|
+
description: "Path to a JSON file containing eval input choices.",
|
|
17498
|
+
flagName: "input-file",
|
|
17499
|
+
inputKey: "inputFile"
|
|
17500
|
+
}),
|
|
17501
|
+
stringOption({
|
|
17502
|
+
description: "Optional persisted run name.",
|
|
17503
|
+
flagName: "name",
|
|
17504
|
+
inputKey: "name"
|
|
17505
|
+
}),
|
|
17506
|
+
stringOption({
|
|
17507
|
+
description: "Optional persisted run description.",
|
|
17508
|
+
flagName: "description",
|
|
17509
|
+
inputKey: "description"
|
|
17510
|
+
}),
|
|
17511
|
+
stringArrayOption({
|
|
17512
|
+
description: "Persisted run tags.",
|
|
17513
|
+
flagName: "tags",
|
|
17514
|
+
inputKey: "tags"
|
|
17515
|
+
}),
|
|
17516
|
+
numberOption({
|
|
17517
|
+
description: "Maximum simultaneously executing trials.",
|
|
17518
|
+
flagName: "max-concurrency",
|
|
17519
|
+
inputKey: "maxConcurrency"
|
|
17520
|
+
}),
|
|
17521
|
+
numberOption({
|
|
17522
|
+
description: "Number of times to repeat each input combination.",
|
|
17523
|
+
flagName: "repeat-count",
|
|
17524
|
+
inputKey: "repeatCount"
|
|
17525
|
+
})
|
|
17526
|
+
]
|
|
17527
|
+
},
|
|
17528
|
+
mcp: { fileName: "planRegisteredEvalRun.graphql" },
|
|
17529
|
+
scope: "global",
|
|
17530
|
+
document: `# Validate the complete proposed run and return the exact trial count without persistence
|
|
17531
|
+
query PlanRegisteredEvalRun(
|
|
17532
|
+
$slug: String!
|
|
17533
|
+
$input: JSON!
|
|
17534
|
+
$name: String
|
|
17535
|
+
$description: String
|
|
17536
|
+
$tags: [String!]
|
|
17537
|
+
$maxConcurrency: Int
|
|
17538
|
+
$repeatCount: Int
|
|
17539
|
+
) {
|
|
17540
|
+
planRegisteredEvalRun(
|
|
17541
|
+
input: {
|
|
17542
|
+
slug: $slug
|
|
17543
|
+
input: $input
|
|
17544
|
+
name: $name
|
|
17545
|
+
description: $description
|
|
17546
|
+
tags: $tags
|
|
17547
|
+
maxConcurrency: $maxConcurrency
|
|
17548
|
+
repeatCount: $repeatCount
|
|
17549
|
+
}
|
|
17550
|
+
) {
|
|
17551
|
+
combinationCount
|
|
17552
|
+
repeatCount
|
|
17553
|
+
trialCount
|
|
17554
|
+
}
|
|
17555
|
+
}`
|
|
17556
|
+
}),
|
|
17557
|
+
createOperationSpec({
|
|
17558
|
+
operationName: "StartRegisteredEvalRun",
|
|
17559
|
+
kind: "mutation",
|
|
17560
|
+
inputSchema: registeredEvalRunInputSchema.extend({
|
|
17561
|
+
expectedTrialCount: z25.number().int().positive(),
|
|
17562
|
+
idempotencyKey: z25.string().trim().min(1)
|
|
17563
|
+
}),
|
|
17564
|
+
cli: {
|
|
17565
|
+
name: "start-registered-eval-run",
|
|
17566
|
+
path: ["evals", "run"],
|
|
17567
|
+
description: "Plan, confirm, and asynchronously start a registered eval run.",
|
|
17568
|
+
resultKey: "startRegisteredEvalRun",
|
|
17569
|
+
options: [
|
|
17570
|
+
stringOption({
|
|
17571
|
+
description: "Registered eval slug.",
|
|
17572
|
+
flagName: "slug",
|
|
17573
|
+
inputKey: "slug",
|
|
17574
|
+
required: true
|
|
17575
|
+
}),
|
|
17576
|
+
jsonOption({
|
|
17577
|
+
description: "Eval input choices keyed by registered input name.",
|
|
17578
|
+
flagName: "input-json",
|
|
17579
|
+
inputKey: "input"
|
|
17580
|
+
}),
|
|
17581
|
+
stringOption({
|
|
17582
|
+
clientOnly: true,
|
|
17583
|
+
description: "Path to a JSON file containing eval input choices.",
|
|
17584
|
+
flagName: "input-file",
|
|
17585
|
+
inputKey: "inputFile"
|
|
17586
|
+
}),
|
|
17587
|
+
stringOption({
|
|
17588
|
+
description: "Optional persisted run name.",
|
|
17589
|
+
flagName: "name",
|
|
17590
|
+
inputKey: "name"
|
|
17591
|
+
}),
|
|
17592
|
+
stringOption({
|
|
17593
|
+
description: "Optional persisted run description.",
|
|
17594
|
+
flagName: "description",
|
|
17595
|
+
inputKey: "description"
|
|
17596
|
+
}),
|
|
17597
|
+
stringArrayOption({
|
|
17598
|
+
description: "Persisted run tags.",
|
|
17599
|
+
flagName: "tags",
|
|
17600
|
+
inputKey: "tags"
|
|
17601
|
+
}),
|
|
17602
|
+
numberOption({
|
|
17603
|
+
description: "Maximum simultaneously executing trials.",
|
|
17604
|
+
flagName: "max-concurrency",
|
|
17605
|
+
inputKey: "maxConcurrency"
|
|
17606
|
+
}),
|
|
17607
|
+
numberOption({
|
|
17608
|
+
description: "Number of times to repeat each input combination.",
|
|
17609
|
+
flagName: "repeat-count",
|
|
17610
|
+
inputKey: "repeatCount"
|
|
17611
|
+
}),
|
|
17612
|
+
stringOption({
|
|
17613
|
+
description: "Idempotency key; generated by mgcl when omitted.",
|
|
17614
|
+
flagName: "idempotency-key",
|
|
17615
|
+
inputKey: "idempotencyKey"
|
|
17616
|
+
}),
|
|
17617
|
+
numberOption({
|
|
17618
|
+
clientOnly: true,
|
|
17619
|
+
description: "Explicitly acknowledge the planned trial count.",
|
|
17620
|
+
flagName: "confirm-trials",
|
|
17621
|
+
inputKey: "confirmTrials"
|
|
17622
|
+
}),
|
|
17623
|
+
booleanOption({
|
|
17624
|
+
clientOnly: true,
|
|
17625
|
+
description: "Wait until the persisted run reaches a terminal state.",
|
|
17626
|
+
flagName: "wait",
|
|
17627
|
+
inputKey: "wait"
|
|
17628
|
+
})
|
|
17629
|
+
]
|
|
17630
|
+
},
|
|
17631
|
+
mcp: { fileName: "startRegisteredEvalRun.graphql" },
|
|
17632
|
+
scope: "global",
|
|
17633
|
+
document: `# Start a registered eval run after PlanRegisteredEvalRun has returned an exact count
|
|
17634
|
+
# MCP callers must provide a unique idempotencyKey and the planned expectedTrialCount
|
|
17635
|
+
mutation StartRegisteredEvalRun(
|
|
17636
|
+
$slug: String!
|
|
17637
|
+
$input: JSON!
|
|
17638
|
+
$name: String
|
|
17639
|
+
$description: String
|
|
17640
|
+
$tags: [String!]
|
|
17641
|
+
$maxConcurrency: Int
|
|
17642
|
+
$repeatCount: Int
|
|
17643
|
+
$idempotencyKey: String!
|
|
17644
|
+
$expectedTrialCount: Int!
|
|
17645
|
+
) {
|
|
17646
|
+
startRegisteredEvalRun(
|
|
17647
|
+
input: {
|
|
17648
|
+
slug: $slug
|
|
17649
|
+
input: $input
|
|
17650
|
+
name: $name
|
|
17651
|
+
description: $description
|
|
17652
|
+
tags: $tags
|
|
17653
|
+
maxConcurrency: $maxConcurrency
|
|
17654
|
+
repeatCount: $repeatCount
|
|
17655
|
+
idempotencyKey: $idempotencyKey
|
|
17656
|
+
expectedTrialCount: $expectedTrialCount
|
|
17657
|
+
}
|
|
17658
|
+
) {
|
|
17659
|
+
idempotencyKey
|
|
17660
|
+
evalRunId
|
|
17661
|
+
workflowId
|
|
17662
|
+
workflowRunId
|
|
17663
|
+
}
|
|
17664
|
+
}`
|
|
17665
|
+
}),
|
|
17666
|
+
createOperationSpec({
|
|
17667
|
+
operationName: "ListEvalRuns",
|
|
17668
|
+
kind: "query",
|
|
17669
|
+
inputSchema: z25.object({
|
|
17670
|
+
page: z25.number().int().nonnegative().default(0),
|
|
17671
|
+
pageSize: z25.number().int().min(1).max(100).default(20),
|
|
17672
|
+
slug: z25.string().min(1).optional(),
|
|
17673
|
+
status: evalRunStatusSchema.optional()
|
|
17674
|
+
}),
|
|
17675
|
+
cli: {
|
|
17676
|
+
name: "list-eval-runs",
|
|
17677
|
+
path: ["evals", "runs", "list"],
|
|
17678
|
+
description: "List persisted eval runs with optional filters.",
|
|
17679
|
+
resultKey: "evalRuns",
|
|
17680
|
+
options: [
|
|
17681
|
+
stringOption({
|
|
17682
|
+
description: "Filter by registered eval slug.",
|
|
17683
|
+
flagName: "slug",
|
|
17684
|
+
inputKey: "slug"
|
|
17685
|
+
}),
|
|
17686
|
+
stringOption({
|
|
17687
|
+
description: "Filter by eval run status.",
|
|
17688
|
+
flagName: "status",
|
|
17689
|
+
inputKey: "status"
|
|
17690
|
+
}),
|
|
17691
|
+
numberOption({
|
|
17692
|
+
description: "Zero-based page number.",
|
|
17693
|
+
flagName: "page",
|
|
17694
|
+
inputKey: "page"
|
|
17695
|
+
}),
|
|
17696
|
+
numberOption({
|
|
17697
|
+
description: "Page size from 1 to 100.",
|
|
17698
|
+
flagName: "page-size",
|
|
17699
|
+
inputKey: "pageSize"
|
|
17700
|
+
})
|
|
17701
|
+
]
|
|
17702
|
+
},
|
|
17703
|
+
mcp: { fileName: "evalRuns.graphql" },
|
|
17704
|
+
scope: "global",
|
|
17705
|
+
document: `# List globally persisted eval runs with status counts and offset pagination
|
|
17706
|
+
query ListEvalRuns(
|
|
17707
|
+
$slug: String
|
|
17708
|
+
$status: EvalRunStatus
|
|
17709
|
+
$page: Int
|
|
17710
|
+
$pageSize: Int
|
|
17711
|
+
) {
|
|
17712
|
+
evalRuns(slug: $slug, status: $status, page: $page, pageSize: $pageSize) {
|
|
17713
|
+
items {
|
|
17714
|
+
${evalRunSelection}
|
|
17715
|
+
}
|
|
17716
|
+
total
|
|
17717
|
+
page
|
|
17718
|
+
pageSize
|
|
17719
|
+
}
|
|
17720
|
+
}`
|
|
17721
|
+
}),
|
|
17722
|
+
createOperationSpec({
|
|
17723
|
+
operationName: "GetEvalRun",
|
|
17724
|
+
kind: "query",
|
|
17725
|
+
inputSchema: z25.object({ id: z25.string().min(1) }),
|
|
17726
|
+
cli: {
|
|
17727
|
+
name: "get-eval-run",
|
|
17728
|
+
path: ["evals", "runs", "get"],
|
|
17729
|
+
description: "Get one persisted eval run with current status counts.",
|
|
17730
|
+
resultKey: "evalRun",
|
|
17731
|
+
options: [
|
|
17732
|
+
stringOption({
|
|
17733
|
+
description: "Eval run ID.",
|
|
17734
|
+
flagName: "id",
|
|
17735
|
+
inputKey: "id",
|
|
17736
|
+
required: true
|
|
17737
|
+
})
|
|
17738
|
+
]
|
|
17739
|
+
},
|
|
17740
|
+
mcp: { fileName: "evalRun.graphql" },
|
|
17741
|
+
scope: "global",
|
|
17742
|
+
document: `# Get one globally persisted eval run by ID
|
|
17743
|
+
query GetEvalRun($id: String!) {
|
|
17744
|
+
evalRun(id: $id) {
|
|
17745
|
+
${evalRunSelection}
|
|
17746
|
+
}
|
|
17747
|
+
}`
|
|
17748
|
+
}),
|
|
17749
|
+
createOperationSpec({
|
|
17750
|
+
operationName: "AwaitEvalRun",
|
|
17751
|
+
kind: "query",
|
|
17752
|
+
inputSchema: z25.object({
|
|
17753
|
+
id: z25.string().min(1),
|
|
17754
|
+
timeoutMs: z25.number().int().min(1e3).max(6e4).default(3e4)
|
|
17755
|
+
}),
|
|
17756
|
+
cli: {
|
|
17757
|
+
name: "await-eval-run",
|
|
17758
|
+
path: ["evals", "runs", "await"],
|
|
17759
|
+
description: "Wait for an eval run by repeating bounded server long-polls.",
|
|
17760
|
+
resultKey: "evalRunAwait",
|
|
17761
|
+
options: [
|
|
17762
|
+
stringOption({
|
|
17763
|
+
description: "Eval run ID.",
|
|
17764
|
+
flagName: "id",
|
|
17765
|
+
inputKey: "id",
|
|
17766
|
+
required: true
|
|
17767
|
+
}),
|
|
17768
|
+
stringOption({
|
|
17769
|
+
clientOnly: true,
|
|
17770
|
+
description: "Overall client wait timeout.",
|
|
17771
|
+
flagName: "timeout",
|
|
17772
|
+
inputKey: "timeout",
|
|
17773
|
+
valueHint: "duration, for example 30s or 5m"
|
|
17774
|
+
})
|
|
17775
|
+
]
|
|
17776
|
+
},
|
|
17777
|
+
mcp: { fileName: "evalRunAwait.graphql" },
|
|
17778
|
+
scope: "global",
|
|
17779
|
+
document: `# Wait up to 60 seconds for an eval run to reach COMPLETE, FAILED, or CANCELLED
|
|
17780
|
+
# Call again when reachedTerminal is false and a longer overall wait is needed
|
|
17781
|
+
query AwaitEvalRun($id: String!, $timeoutMs: Int) {
|
|
17782
|
+
evalRunAwait(id: $id, timeoutMs: $timeoutMs) {
|
|
17783
|
+
reachedTerminal
|
|
17784
|
+
pollCount
|
|
17785
|
+
elapsedMs
|
|
17786
|
+
evalRun {
|
|
17787
|
+
${evalRunSelection}
|
|
17788
|
+
}
|
|
17789
|
+
}
|
|
17790
|
+
}`
|
|
17791
|
+
}),
|
|
17792
|
+
createOperationSpec({
|
|
17793
|
+
operationName: "ListEvalRunTrials",
|
|
17794
|
+
kind: "query",
|
|
17795
|
+
inputSchema: z25.object({
|
|
17796
|
+
cursor: z25.string().min(1).optional(),
|
|
17797
|
+
id: z25.string().min(1),
|
|
17798
|
+
limit: z25.number().int().min(1).max(1e3).default(100)
|
|
17799
|
+
}),
|
|
17800
|
+
cli: {
|
|
17801
|
+
name: "list-eval-run-trials",
|
|
17802
|
+
path: ["evals", "runs", "trials"],
|
|
17803
|
+
description: "List eval trials in deterministic cursor order.",
|
|
17804
|
+
resultKey: "evalRunTrials",
|
|
17805
|
+
options: [
|
|
17806
|
+
stringOption({
|
|
17807
|
+
description: "Eval run ID.",
|
|
17808
|
+
flagName: "id",
|
|
17809
|
+
inputKey: "id",
|
|
17810
|
+
required: true
|
|
17811
|
+
}),
|
|
17812
|
+
numberOption({
|
|
17813
|
+
description: "Maximum trials to return, from 1 to 1000.",
|
|
17814
|
+
flagName: "limit",
|
|
17815
|
+
inputKey: "limit"
|
|
17816
|
+
}),
|
|
17817
|
+
stringOption({
|
|
17818
|
+
description: "Opaque cursor returned by the previous page.",
|
|
17819
|
+
flagName: "cursor",
|
|
17820
|
+
inputKey: "cursor"
|
|
17821
|
+
})
|
|
17822
|
+
]
|
|
17823
|
+
},
|
|
17824
|
+
mcp: { fileName: "evalRunTrials.graphql" },
|
|
17825
|
+
scope: "global",
|
|
17826
|
+
document: `# List eval trials in ascending deterministic order with an opaque continuation cursor
|
|
17827
|
+
query ListEvalRunTrials($id: String!, $limit: Int, $cursor: String) {
|
|
17828
|
+
evalRunTrials(id: $id, limit: $limit, cursor: $cursor) {
|
|
17829
|
+
trials {
|
|
17830
|
+
id
|
|
17831
|
+
createdAt
|
|
17832
|
+
updatedAt
|
|
17833
|
+
evalRunId
|
|
17834
|
+
repeatIndex
|
|
17835
|
+
input
|
|
17836
|
+
status
|
|
17837
|
+
startedAt
|
|
17838
|
+
finishedAt
|
|
17839
|
+
scores
|
|
17840
|
+
output
|
|
17841
|
+
workflowId
|
|
17842
|
+
workflowRunId
|
|
17843
|
+
}
|
|
17844
|
+
nextCursor
|
|
17845
|
+
}
|
|
17846
|
+
}`
|
|
17847
|
+
}),
|
|
17848
|
+
createOperationSpec({
|
|
17849
|
+
operationName: "CancelEvalRun",
|
|
17850
|
+
kind: "mutation",
|
|
17851
|
+
inputSchema: z25.object({ id: z25.string().min(1) }),
|
|
17852
|
+
cli: {
|
|
17853
|
+
name: "cancel-eval-run",
|
|
17854
|
+
path: ["evals", "runs", "cancel"],
|
|
17855
|
+
description: "Request cancellation for a queued or running eval run.",
|
|
17856
|
+
resultKey: "cancelEvalRun",
|
|
17857
|
+
options: [
|
|
17858
|
+
stringOption({
|
|
17859
|
+
description: "Eval run ID.",
|
|
17860
|
+
flagName: "id",
|
|
17861
|
+
inputKey: "id",
|
|
17862
|
+
required: true
|
|
17863
|
+
})
|
|
17864
|
+
]
|
|
17865
|
+
},
|
|
17866
|
+
mcp: { fileName: "cancelEvalRun.graphql" },
|
|
17867
|
+
scope: "global",
|
|
17868
|
+
document: `# Request cancellation without claiming the run has already reached CANCELLED
|
|
17869
|
+
mutation CancelEvalRun($id: String!) {
|
|
17870
|
+
cancelEvalRun(id: $id) {
|
|
17871
|
+
evalRunId
|
|
17872
|
+
cancellationRequested
|
|
17873
|
+
status
|
|
17874
|
+
}
|
|
17875
|
+
}`
|
|
17876
|
+
}),
|
|
17877
|
+
createOperationSpec({
|
|
17878
|
+
operationName: "RequestEvalRunExport",
|
|
17879
|
+
kind: "mutation",
|
|
17880
|
+
inputSchema: z25.object({ id: z25.string().min(1) }),
|
|
17881
|
+
cli: {
|
|
17882
|
+
name: "request-eval-run-export",
|
|
17883
|
+
path: ["evals", "runs", "export"],
|
|
17884
|
+
description: "Request an asynchronous raw-results export.",
|
|
17885
|
+
resultKey: "requestEvalRunExport",
|
|
17886
|
+
options: [
|
|
17887
|
+
stringOption({
|
|
17888
|
+
description: "Eval run ID.",
|
|
17889
|
+
flagName: "id",
|
|
17890
|
+
inputKey: "id",
|
|
17891
|
+
required: true
|
|
17892
|
+
}),
|
|
17893
|
+
stringOption({
|
|
17894
|
+
clientOnly: true,
|
|
17895
|
+
description: "Destination path for the completed export.",
|
|
17896
|
+
flagName: "output",
|
|
17897
|
+
inputKey: "output",
|
|
17898
|
+
required: true
|
|
17899
|
+
}),
|
|
17900
|
+
booleanOption({
|
|
17901
|
+
clientOnly: true,
|
|
17902
|
+
description: "Wait for export completion and download the file.",
|
|
17903
|
+
flagName: "wait",
|
|
17904
|
+
inputKey: "wait"
|
|
17905
|
+
}),
|
|
17906
|
+
booleanOption({
|
|
17907
|
+
clientOnly: true,
|
|
17908
|
+
description: "Authorize replacement of an existing output file.",
|
|
17909
|
+
flagName: "force",
|
|
17910
|
+
inputKey: "force"
|
|
17911
|
+
})
|
|
17912
|
+
]
|
|
17913
|
+
},
|
|
17914
|
+
mcp: { fileName: "requestEvalRunExport.graphql" },
|
|
17915
|
+
scope: "global",
|
|
17916
|
+
document: `# Request or reuse an asynchronous raw-results export for a terminal eval run
|
|
17917
|
+
mutation RequestEvalRunExport($id: String!) {
|
|
17918
|
+
requestEvalRunExport(id: $id) {
|
|
17919
|
+
${evalRunExportSelection}
|
|
17920
|
+
}
|
|
17921
|
+
}`
|
|
17922
|
+
}),
|
|
17923
|
+
createOperationSpec({
|
|
17924
|
+
operationName: "GetEvalRunExport",
|
|
17925
|
+
kind: "query",
|
|
17926
|
+
inputSchema: z25.object({ exportId: z25.string().min(1) }),
|
|
17927
|
+
cli: {
|
|
17928
|
+
hidden: true,
|
|
17929
|
+
name: "get-eval-run-export",
|
|
17930
|
+
path: ["evals", "runs", "export-status"],
|
|
17931
|
+
description: "Get asynchronous eval export status by export ID.",
|
|
17932
|
+
resultKey: "evalRunExport",
|
|
17933
|
+
options: [
|
|
17934
|
+
stringOption({
|
|
17935
|
+
description: "Eval export ID.",
|
|
17936
|
+
flagName: "export-id",
|
|
17937
|
+
inputKey: "exportId",
|
|
17938
|
+
required: true
|
|
17939
|
+
})
|
|
17940
|
+
]
|
|
17941
|
+
},
|
|
17942
|
+
mcp: { fileName: "evalRunExport.graphql" },
|
|
17943
|
+
scope: "global",
|
|
17944
|
+
document: `# Get asynchronous eval export status; downloadUrl is signed and only present when COMPLETE
|
|
17945
|
+
query GetEvalRunExport($exportId: String!) {
|
|
17946
|
+
evalRunExport(exportId: $exportId) {
|
|
17947
|
+
${evalRunExportSelection}
|
|
17948
|
+
}
|
|
17949
|
+
}`
|
|
17950
|
+
})
|
|
17951
|
+
];
|
|
17952
|
+
|
|
17953
|
+
// src/program.ts
|
|
17954
|
+
import { Command as Command2, InvalidArgumentError as InvalidArgumentError2, Option as Option2 } from "commander";
|
|
17955
|
+
|
|
17956
|
+
// src/api.ts
|
|
17957
|
+
import { randomUUID } from "node:crypto";
|
|
17958
|
+
import { createWriteStream } from "node:fs";
|
|
17959
|
+
import { access, link, rename, rm } from "node:fs/promises";
|
|
17960
|
+
import nodePath from "node:path";
|
|
17961
|
+
import { Readable } from "node:stream";
|
|
17962
|
+
import { pipeline } from "node:stream/promises";
|
|
17963
|
+
import { z as z26 } from "zod";
|
|
17964
|
+
|
|
17965
|
+
// src/version.ts
|
|
17966
|
+
import fs from "node:fs";
|
|
17967
|
+
import path from "node:path";
|
|
17968
|
+
import { fileURLToPath } from "node:url";
|
|
17969
|
+
var packageManifestPath = path.resolve(
|
|
17970
|
+
path.dirname(fileURLToPath(import.meta.url)),
|
|
17971
|
+
"../package.json"
|
|
17972
|
+
);
|
|
17973
|
+
var packageManifestResult = safeJsonParse(
|
|
17974
|
+
fs.readFileSync(packageManifestPath, "utf8")
|
|
17975
|
+
);
|
|
17976
|
+
if (isErr(packageManifestResult)) {
|
|
17977
|
+
throw new Error(`Failed to parse ${packageManifestPath}.`, {
|
|
17978
|
+
cause: packageManifestResult.error.cause
|
|
17979
|
+
});
|
|
17980
|
+
}
|
|
17981
|
+
var cliPackageVersion = packageManifestResult.value.version;
|
|
17982
|
+
if (typeof cliPackageVersion !== "string" || cliPackageVersion.length === 0) {
|
|
17983
|
+
throw new Error(`Expected a version in ${packageManifestPath}.`);
|
|
17984
|
+
}
|
|
17985
|
+
var CLI_VERSION = cliPackageVersion;
|
|
17986
|
+
|
|
17987
|
+
// src/api.ts
|
|
17988
|
+
var OTTO_AUTHORIZATION_HEADER_NAME = "X-Otto-Authorization";
|
|
17989
|
+
var OTTO_AUTHORIZATION_ISSUER = "magical:otto";
|
|
17990
|
+
var workosOrganizationsResponseSchema = z26.object({
|
|
17991
|
+
organizations: z26.array(
|
|
17992
|
+
z26.object({
|
|
17993
|
+
id: z26.string().min(1),
|
|
17994
|
+
name: z26.string().min(1),
|
|
17995
|
+
primaryDomain: z26.string().nullable().optional()
|
|
17996
|
+
})
|
|
17997
|
+
),
|
|
17998
|
+
success: z26.boolean()
|
|
17999
|
+
});
|
|
18000
|
+
var workosUserSchema = z26.object({
|
|
18001
|
+
email: z26.string().nullable(),
|
|
18002
|
+
id: z26.string().min(1)
|
|
18003
|
+
});
|
|
18004
|
+
var nangoIntegrationWireSchema = z26.object({
|
|
18005
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention -- mirrors Nango REST payload
|
|
18006
|
+
unique_key: z26.string().min(1)
|
|
18007
|
+
}).passthrough().transform((data) => ({
|
|
18008
|
+
...data,
|
|
18009
|
+
uniqueKey: data.unique_key
|
|
18010
|
+
}));
|
|
18011
|
+
var nangoIntegrationsResponseSchema = z26.array(nangoIntegrationWireSchema);
|
|
18012
|
+
var organizationAuthenticationSchema = z26.object({
|
|
18013
|
+
id: z26.string().min(1),
|
|
18014
|
+
type: z26.string().min(1),
|
|
18015
|
+
connectionId: z26.string().nullable().optional(),
|
|
18016
|
+
providerConfigKey: z26.string().nullable().optional(),
|
|
18017
|
+
description: z26.string().nullable().optional(),
|
|
18018
|
+
hostname: z26.string().nullable().optional()
|
|
18019
|
+
}).passthrough();
|
|
18020
|
+
var organizationAuthenticationsResponseSchema = z26.object({
|
|
18021
|
+
authentications: z26.array(organizationAuthenticationSchema),
|
|
18022
|
+
success: z26.boolean()
|
|
18023
|
+
});
|
|
18024
|
+
var pathwayRegressionRunStatusSchema = z26.enum([
|
|
18025
|
+
"queued",
|
|
18026
|
+
"running",
|
|
18027
|
+
"passed",
|
|
18028
|
+
"failed",
|
|
18029
|
+
"inconclusive",
|
|
18030
|
+
"errored"
|
|
18031
|
+
]);
|
|
18032
|
+
var pathwayRegressionReplayIterationStatusSchema = z26.enum([
|
|
18033
|
+
"running",
|
|
18034
|
+
"passed",
|
|
18035
|
+
"failed",
|
|
18036
|
+
"inconclusive",
|
|
18037
|
+
"errored"
|
|
18038
|
+
]);
|
|
18039
|
+
var pathwayRegressionMatchingRunSchema = z26.object({
|
|
18040
|
+
agentRunId: z26.string().min(1),
|
|
18041
|
+
agentVersionId: z26.string().min(1),
|
|
18042
|
+
automationRunId: z26.string().min(1),
|
|
18043
|
+
contractPathHash: z26.string().min(1),
|
|
18044
|
+
finishedAt: z26.string().min(1),
|
|
18045
|
+
signatureId: z26.string().min(1),
|
|
18046
|
+
stepCount: z26.number().nullable()
|
|
18047
|
+
});
|
|
18048
|
+
var pathwayRegressionMatchingRunsPathSchema = z26.object({
|
|
18049
|
+
contractPathId: z26.string().min(1),
|
|
18050
|
+
executablePathHash: z26.string().min(1),
|
|
18051
|
+
label: z26.string().min(1),
|
|
18052
|
+
pathwayKey: z26.string().min(1),
|
|
18053
|
+
runs: z26.array(pathwayRegressionMatchingRunSchema),
|
|
18054
|
+
sortOrder: z26.number()
|
|
18055
|
+
});
|
|
18056
|
+
var pathwayRegressionMatchingRunsResponseSchema = z26.object({
|
|
18057
|
+
agentVersionId: z26.string().min(1),
|
|
18058
|
+
automationId: z26.string().min(1),
|
|
18059
|
+
automationVersionId: z26.string().min(1),
|
|
18060
|
+
contractId: z26.string().min(1),
|
|
18061
|
+
paths: z26.array(pathwayRegressionMatchingRunsPathSchema)
|
|
18062
|
+
});
|
|
18063
|
+
var pathwayRegressionAgentVersionRunPathStatusSchema = z26.enum([
|
|
18064
|
+
"historical_path_missing_after_change",
|
|
18065
|
+
"missing_after_change",
|
|
18066
|
+
"new_pathway",
|
|
18067
|
+
"no_matching_runs",
|
|
18068
|
+
"queued"
|
|
18069
|
+
]);
|
|
18070
|
+
var pathwayRegressionAgentVersionRunStatusSchema = z26.enum([
|
|
18071
|
+
"queued",
|
|
18072
|
+
"running",
|
|
18073
|
+
"passed",
|
|
18074
|
+
"failed",
|
|
18075
|
+
"inconclusive",
|
|
18076
|
+
"errored",
|
|
18077
|
+
"contract_generation_queued",
|
|
18078
|
+
"not_started"
|
|
18079
|
+
]);
|
|
18080
|
+
var pathwayRegressionAgentVersionRunPathSideSchema = z26.object({
|
|
18081
|
+
contractPathId: z26.string().min(1),
|
|
18082
|
+
executablePathHash: z26.string().min(1),
|
|
18083
|
+
label: z26.string().min(1),
|
|
18084
|
+
sortOrder: z26.number()
|
|
18085
|
+
});
|
|
18086
|
+
var pathwayRegressionAgentVersionRunPathSchema = z26.object({
|
|
18087
|
+
baseline: pathwayRegressionAgentVersionRunPathSideSchema.nullable(),
|
|
18088
|
+
candidate: pathwayRegressionAgentVersionRunPathSideSchema.nullable(),
|
|
18089
|
+
isInLatestPublishedBaseline: z26.boolean().optional(),
|
|
18090
|
+
lastSeenPublishedAgentVersionId: z26.string().min(1).optional(),
|
|
18091
|
+
lastSeenPublishedAt: z26.string().min(1).nullable().optional(),
|
|
18092
|
+
lastSeenPublishedAutomationVersionId: z26.string().min(1).optional(),
|
|
18093
|
+
lastSeenPublishedSequence: z26.number().optional(),
|
|
18094
|
+
pathwayKey: z26.string().min(1),
|
|
18095
|
+
selectedRunCount: z26.number(),
|
|
18096
|
+
status: pathwayRegressionAgentVersionRunPathStatusSchema
|
|
18097
|
+
});
|
|
18098
|
+
var pathwayRegressionContractGenerationStatusSchema = z26.enum([
|
|
18099
|
+
"failed",
|
|
18100
|
+
"queued",
|
|
18101
|
+
"running",
|
|
18102
|
+
"succeeded"
|
|
18103
|
+
]);
|
|
18104
|
+
var pathwayRegressionAgentVersionContractQueuedResponseSchema = z26.object({
|
|
18105
|
+
agentVersionId: z26.string().min(1),
|
|
18106
|
+
automationId: z26.string().min(1),
|
|
18107
|
+
automationVersionId: z26.string().min(1),
|
|
18108
|
+
contractGenerationStatus: pathwayRegressionContractGenerationStatusSchema,
|
|
18109
|
+
contractWorkflowId: z26.string().min(1),
|
|
18110
|
+
regressionRunId: z26.null(),
|
|
18111
|
+
selectedReplayCount: z26.literal(0),
|
|
18112
|
+
status: z26.literal("contract_generation_queued"),
|
|
18113
|
+
workflowId: z26.null()
|
|
18114
|
+
});
|
|
18115
|
+
var pathwayRegressionAgentVersionRegressionRunResponseSchema = z26.object({
|
|
18116
|
+
agentVersionId: z26.string().min(1),
|
|
18117
|
+
automationId: z26.string().min(1),
|
|
18118
|
+
automationVersionId: z26.string().min(1),
|
|
18119
|
+
baselineAgentVersionId: z26.string().min(1),
|
|
18120
|
+
baselineAutomationVersionId: z26.string().min(1),
|
|
18121
|
+
baselineContractId: z26.string().min(1),
|
|
18122
|
+
candidateContractId: z26.string().min(1),
|
|
18123
|
+
contractId: z26.string().min(1),
|
|
18124
|
+
paths: z26.array(pathwayRegressionAgentVersionRunPathSchema),
|
|
18125
|
+
regressionRunId: z26.string().min(1).nullable(),
|
|
18126
|
+
selectedReplayCount: z26.number(),
|
|
18127
|
+
status: pathwayRegressionAgentVersionRunStatusSchema,
|
|
18128
|
+
workflowId: z26.string().min(1).nullable()
|
|
18129
|
+
});
|
|
18130
|
+
var pathwayRegressionAgentVersionRunResponseSchema = z26.union([
|
|
18131
|
+
pathwayRegressionAgentVersionContractQueuedResponseSchema,
|
|
18132
|
+
pathwayRegressionAgentVersionRegressionRunResponseSchema
|
|
18133
|
+
]);
|
|
18134
|
+
var pathwayRegressionCheckSummarySchema = z26.object({
|
|
18135
|
+
errored: z26.number(),
|
|
18136
|
+
failed: z26.number(),
|
|
18137
|
+
inconclusive: z26.number(),
|
|
18138
|
+
passed: z26.number(),
|
|
18139
|
+
total: z26.number()
|
|
18140
|
+
});
|
|
18141
|
+
var pathwayRegressionRunResultIterationSchema = z26.object({
|
|
18142
|
+
baselineIterationId: z26.string().min(1),
|
|
18143
|
+
createdAt: z26.string().min(1),
|
|
18144
|
+
expectedToolName: z26.string().min(1),
|
|
18145
|
+
id: z26.string().min(1),
|
|
18146
|
+
observedToolName: z26.string().min(1).nullable(),
|
|
18147
|
+
outputResult: z26.unknown().nullable(),
|
|
18148
|
+
sequence: z26.number(),
|
|
18149
|
+
status: pathwayRegressionReplayIterationStatusSchema,
|
|
18150
|
+
updatedAt: z26.string().min(1)
|
|
18151
|
+
});
|
|
18152
|
+
var pathwayRegressionReplayCheckResultSchema = z26.object({
|
|
18153
|
+
actualToolName: z26.string().min(1).nullable(),
|
|
18154
|
+
attemptIndex: z26.number(),
|
|
18155
|
+
createdAt: z26.string().min(1),
|
|
18156
|
+
expectedActionAssessment: z26.unknown().nullable(),
|
|
18157
|
+
expectedToolName: z26.string().min(1),
|
|
18158
|
+
id: z26.string().min(1),
|
|
18159
|
+
llmRequestId: z26.string().min(1).nullable(),
|
|
18160
|
+
modelId: z26.string().min(1).nullable(),
|
|
18161
|
+
outputResult: z26.unknown().nullable(),
|
|
18162
|
+
status: z26.enum(["passed", "failed", "errored"]),
|
|
18163
|
+
strictExactMatch: z26.boolean().nullable()
|
|
18164
|
+
});
|
|
18165
|
+
var pathwayRegressionReplayIterationCheckResultsResponseSchema = z26.object({
|
|
18166
|
+
regressionReplayIteration: pathwayRegressionRunResultIterationSchema.extend({
|
|
18167
|
+
checkResults: z26.array(pathwayRegressionReplayCheckResultSchema),
|
|
18168
|
+
regressionReplayId: z26.string().min(1)
|
|
18169
|
+
})
|
|
18170
|
+
});
|
|
18171
|
+
var pathwayRegressionRunResultReplaySchema = z26.object({
|
|
18172
|
+
baselineAgentRunId: z26.string().min(1),
|
|
18173
|
+
baselineAutomationRunId: z26.string().min(1),
|
|
18174
|
+
checks: pathwayRegressionCheckSummarySchema,
|
|
18175
|
+
createdAt: z26.string().min(1),
|
|
18176
|
+
finishedAt: z26.string().min(1).nullable(),
|
|
18177
|
+
id: z26.string().min(1),
|
|
18178
|
+
iterations: z26.array(pathwayRegressionRunResultIterationSchema),
|
|
18179
|
+
status: pathwayRegressionRunStatusSchema
|
|
18180
|
+
});
|
|
18181
|
+
var pathwayRegressionRunResultPathwaySchema = z26.object({
|
|
18182
|
+
contractId: z26.string().min(1),
|
|
18183
|
+
contractPathId: z26.string().min(1).nullable(),
|
|
18184
|
+
label: z26.string().min(1).nullable(),
|
|
18185
|
+
pathwayKey: z26.string().min(1),
|
|
18186
|
+
replays: z26.array(pathwayRegressionRunResultReplaySchema),
|
|
18187
|
+
sortOrder: z26.number().nullable()
|
|
18188
|
+
});
|
|
18189
|
+
var pathwayRegressionRunResultResponseSchema = z26.object({
|
|
18190
|
+
pathways: z26.array(pathwayRegressionRunResultPathwaySchema),
|
|
18191
|
+
regressionRun: z26.object({
|
|
18192
|
+
automationId: z26.string().min(1),
|
|
18193
|
+
candidateAgentVersionId: z26.string().min(1).nullable(),
|
|
18194
|
+
candidateAutomationVersionId: z26.string().min(1),
|
|
18195
|
+
createdAt: z26.string().min(1),
|
|
18196
|
+
finishedAt: z26.string().min(1).nullable(),
|
|
18197
|
+
id: z26.string().min(1),
|
|
18198
|
+
scope: z26.enum(["single_run", "contract_batch", "automation_version"]),
|
|
18199
|
+
status: pathwayRegressionRunStatusSchema,
|
|
18200
|
+
workflowId: z26.string().min(1)
|
|
18201
|
+
})
|
|
18202
|
+
});
|
|
18203
|
+
var graphQlResponseSchema = z26.object({
|
|
18204
|
+
data: z26.record(z26.string(), z26.unknown()).nullable().optional(),
|
|
18205
|
+
errors: z26.array(
|
|
18206
|
+
z26.object({
|
|
18207
|
+
extensions: z26.object({
|
|
18208
|
+
code: z26.string().min(1).optional()
|
|
18209
|
+
}).passthrough().optional(),
|
|
18210
|
+
message: z26.string().min(1)
|
|
18211
|
+
})
|
|
18212
|
+
).optional()
|
|
18213
|
+
});
|
|
18214
|
+
var apiErrorResponseSchema = z26.object({
|
|
18215
|
+
errors: z26.array(
|
|
18216
|
+
z26.object({
|
|
18217
|
+
message: z26.string().min(1)
|
|
18218
|
+
})
|
|
18219
|
+
).optional(),
|
|
18220
|
+
message: z26.string().min(1).optional()
|
|
18221
|
+
});
|
|
18222
|
+
function getApiErrorDetail(responseBody) {
|
|
18223
|
+
const parsedResponse = apiErrorResponseSchema.safeParse(responseBody);
|
|
18224
|
+
if (!parsedResponse.success) {
|
|
18225
|
+
return null;
|
|
18226
|
+
}
|
|
18227
|
+
if (parsedResponse.data.message) {
|
|
17073
18228
|
return parsedResponse.data.message;
|
|
17074
18229
|
}
|
|
17075
18230
|
if (!parsedResponse.data.errors || parsedResponse.data.errors.length === 0) {
|
|
@@ -17077,9 +18232,57 @@ function getApiErrorDetail(responseBody) {
|
|
|
17077
18232
|
}
|
|
17078
18233
|
return parsedResponse.data.errors.map((error) => error.message).join("\n");
|
|
17079
18234
|
}
|
|
18235
|
+
var DEFINITIVE_GRAPHQL_APPLICATION_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
18236
|
+
"BAD_REQUEST",
|
|
18237
|
+
"BAD_USER_INPUT",
|
|
18238
|
+
"FORBIDDEN",
|
|
18239
|
+
"GRAPHQL_PARSE_FAILED",
|
|
18240
|
+
"GRAPHQL_VALIDATION_FAILED",
|
|
18241
|
+
"NOT_FOUND",
|
|
18242
|
+
"OPERATION_RESOLUTION_FAILURE",
|
|
18243
|
+
"PERSISTED_QUERY_NOT_FOUND",
|
|
18244
|
+
"PERSISTED_QUERY_NOT_SUPPORTED",
|
|
18245
|
+
"UNAUTHORIZED"
|
|
18246
|
+
]);
|
|
18247
|
+
var GraphQlResponseError = class extends CliError {
|
|
18248
|
+
graphQlCodes;
|
|
18249
|
+
hasUnclassifiedGraphQlErrors;
|
|
18250
|
+
constructor(message, {
|
|
18251
|
+
graphQlCodes,
|
|
18252
|
+
hasUnclassifiedGraphQlErrors = false
|
|
18253
|
+
}) {
|
|
18254
|
+
super(message);
|
|
18255
|
+
this.name = "GraphQlResponseError";
|
|
18256
|
+
this.graphQlCodes = [...graphQlCodes];
|
|
18257
|
+
this.hasUnclassifiedGraphQlErrors = hasUnclassifiedGraphQlErrors;
|
|
18258
|
+
}
|
|
18259
|
+
};
|
|
18260
|
+
function isDefinitiveGraphQlApplicationError(error) {
|
|
18261
|
+
return error instanceof GraphQlResponseError && !error.hasUnclassifiedGraphQlErrors && error.graphQlCodes.length > 0 && error.graphQlCodes.every(
|
|
18262
|
+
(code) => DEFINITIVE_GRAPHQL_APPLICATION_ERROR_CODES.has(code)
|
|
18263
|
+
);
|
|
18264
|
+
}
|
|
17080
18265
|
function trimTrailingSlash(value) {
|
|
17081
18266
|
return value.replace(/\/+$/u, "");
|
|
17082
18267
|
}
|
|
18268
|
+
function isFileAlreadyExistsError(error) {
|
|
18269
|
+
return error instanceof Error && "code" in error && error.code === "EEXIST";
|
|
18270
|
+
}
|
|
18271
|
+
async function assertOutputDoesNotExist(outputPath) {
|
|
18272
|
+
const outputExists = await access(outputPath).then(() => true).catch((error) => {
|
|
18273
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
18274
|
+
return false;
|
|
18275
|
+
}
|
|
18276
|
+
throw new CliError(`Failed to inspect export path "${outputPath}".`, {
|
|
18277
|
+
cause: error
|
|
18278
|
+
});
|
|
18279
|
+
});
|
|
18280
|
+
if (outputExists) {
|
|
18281
|
+
throw new CliError(
|
|
18282
|
+
`Refusing to overwrite existing file "${outputPath}". Pass --force to authorize replacement.`
|
|
18283
|
+
);
|
|
18284
|
+
}
|
|
18285
|
+
}
|
|
17083
18286
|
function isRecord4(value) {
|
|
17084
18287
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17085
18288
|
}
|
|
@@ -17099,6 +18302,23 @@ function decodeJwtPayload(token) {
|
|
|
17099
18302
|
function isOttoAuthorizationToken(token) {
|
|
17100
18303
|
return decodeJwtPayload(token)?.["iss"] === OTTO_AUTHORIZATION_ISSUER;
|
|
17101
18304
|
}
|
|
18305
|
+
function buildPathwayRegressionAgentVersionPath({
|
|
18306
|
+
agentVersionId,
|
|
18307
|
+
automationVersionId,
|
|
18308
|
+
leafPath,
|
|
18309
|
+
runsPerPath
|
|
18310
|
+
}) {
|
|
18311
|
+
const path9 = `/pathway-regression/automation-versions/${encodeURIComponent(
|
|
18312
|
+
automationVersionId
|
|
18313
|
+
)}/agent-versions/${encodeURIComponent(agentVersionId)}/${leafPath}`;
|
|
18314
|
+
if (runsPerPath === void 0) {
|
|
18315
|
+
return path9;
|
|
18316
|
+
}
|
|
18317
|
+
const queryParams = new URLSearchParams({
|
|
18318
|
+
runsPerPath: String(runsPerPath)
|
|
18319
|
+
});
|
|
18320
|
+
return `${path9}?${queryParams.toString()}`;
|
|
18321
|
+
}
|
|
17102
18322
|
function applyAuthenticationHeaders({
|
|
17103
18323
|
accessToken,
|
|
17104
18324
|
allowOttoAuthorization,
|
|
@@ -17133,11 +18353,11 @@ function createMagicalApiClient({
|
|
|
17133
18353
|
accessToken,
|
|
17134
18354
|
impersonatedOrganizationId,
|
|
17135
18355
|
allowOttoAuthorization,
|
|
17136
|
-
path:
|
|
18356
|
+
path: path9,
|
|
17137
18357
|
init,
|
|
17138
18358
|
organizationId
|
|
17139
18359
|
}) {
|
|
17140
|
-
const url = `${trimTrailingSlash(await resolveApiBaseUrl())}${
|
|
18360
|
+
const url = `${trimTrailingSlash(await resolveApiBaseUrl())}${path9}`;
|
|
17141
18361
|
const headers = new Headers(init?.headers);
|
|
17142
18362
|
applyAuthenticationHeaders({
|
|
17143
18363
|
accessToken,
|
|
@@ -17182,6 +18402,51 @@ function createMagicalApiClient({
|
|
|
17182
18402
|
return responseBody;
|
|
17183
18403
|
}
|
|
17184
18404
|
return {
|
|
18405
|
+
async downloadFile({ outputPath, overwrite = false, url }) {
|
|
18406
|
+
if (!overwrite) {
|
|
18407
|
+
await assertOutputDoesNotExist(outputPath);
|
|
18408
|
+
}
|
|
18409
|
+
const temporaryPath = nodePath.join(
|
|
18410
|
+
nodePath.dirname(outputPath),
|
|
18411
|
+
`.${nodePath.basename(outputPath)}.${randomUUID()}.tmp`
|
|
18412
|
+
);
|
|
18413
|
+
await (async () => {
|
|
18414
|
+
const response = await fetchFn(url).catch((error) => {
|
|
18415
|
+
throw new CliError("Failed to download eval export.", {
|
|
18416
|
+
cause: error
|
|
18417
|
+
});
|
|
18418
|
+
});
|
|
18419
|
+
if (!response.ok) {
|
|
18420
|
+
throw new CliError(
|
|
18421
|
+
`Eval export download failed with status ${response.status}.`
|
|
18422
|
+
);
|
|
18423
|
+
}
|
|
18424
|
+
if (!response.body) {
|
|
18425
|
+
throw new CliError("Eval export download returned an empty body.");
|
|
18426
|
+
}
|
|
18427
|
+
await pipeline(
|
|
18428
|
+
Readable.fromWeb(response.body),
|
|
18429
|
+
createWriteStream(temporaryPath, { flags: "wx" })
|
|
18430
|
+
);
|
|
18431
|
+
if (overwrite) {
|
|
18432
|
+
await rename(temporaryPath, outputPath);
|
|
18433
|
+
return;
|
|
18434
|
+
}
|
|
18435
|
+
await link(temporaryPath, outputPath).catch((error) => {
|
|
18436
|
+
if (isFileAlreadyExistsError(error)) {
|
|
18437
|
+
throw new CliError(
|
|
18438
|
+
`Refusing to overwrite existing file "${outputPath}". Pass --force to authorize replacement.`,
|
|
18439
|
+
{ cause: error }
|
|
18440
|
+
);
|
|
18441
|
+
}
|
|
18442
|
+
throw error;
|
|
18443
|
+
});
|
|
18444
|
+
await rm(temporaryPath, { force: true });
|
|
18445
|
+
})().catch(async (error) => {
|
|
18446
|
+
await rm(temporaryPath, { force: true });
|
|
18447
|
+
throw error;
|
|
18448
|
+
});
|
|
18449
|
+
},
|
|
17185
18450
|
async executeGraphQl({
|
|
17186
18451
|
accessToken,
|
|
17187
18452
|
impersonatedOrganizationId,
|
|
@@ -17213,8 +18478,15 @@ function createMagicalApiClient({
|
|
|
17213
18478
|
throw new CliError("GraphQL response payload was invalid.");
|
|
17214
18479
|
}
|
|
17215
18480
|
if (parsedResponse.data.errors && parsedResponse.data.errors.length > 0) {
|
|
17216
|
-
|
|
17217
|
-
|
|
18481
|
+
const graphQlCodes = parsedResponse.data.errors.flatMap(
|
|
18482
|
+
(error) => error.extensions?.code ? [error.extensions.code] : []
|
|
18483
|
+
);
|
|
18484
|
+
throw new GraphQlResponseError(
|
|
18485
|
+
parsedResponse.data.errors.map((error) => error.message).join("\n"),
|
|
18486
|
+
{
|
|
18487
|
+
graphQlCodes,
|
|
18488
|
+
hasUnclassifiedGraphQlErrors: graphQlCodes.length !== parsedResponse.data.errors.length
|
|
18489
|
+
}
|
|
17218
18490
|
);
|
|
17219
18491
|
}
|
|
17220
18492
|
return parsedResponse.data.data?.[resultKey] ?? null;
|
|
@@ -17287,6 +18559,111 @@ function createMagicalApiClient({
|
|
|
17287
18559
|
throw new CliError("Organization authentications payload was invalid.");
|
|
17288
18560
|
}
|
|
17289
18561
|
return parsedResponse.data.authentications;
|
|
18562
|
+
},
|
|
18563
|
+
async previewPathwayRegressionMatchingRuns({
|
|
18564
|
+
accessToken,
|
|
18565
|
+
agentVersionId,
|
|
18566
|
+
automationVersionId,
|
|
18567
|
+
impersonatedOrganizationId,
|
|
18568
|
+
organizationId,
|
|
18569
|
+
runsPerPath
|
|
18570
|
+
}) {
|
|
18571
|
+
const parsedResponse = pathwayRegressionMatchingRunsResponseSchema.safeParse(
|
|
18572
|
+
await fetchJson({
|
|
18573
|
+
accessToken,
|
|
18574
|
+
allowOttoAuthorization: true,
|
|
18575
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
18576
|
+
...organizationId ? { organizationId } : {},
|
|
18577
|
+
path: buildPathwayRegressionAgentVersionPath({
|
|
18578
|
+
agentVersionId,
|
|
18579
|
+
automationVersionId,
|
|
18580
|
+
leafPath: "matching-runs",
|
|
18581
|
+
...runsPerPath === void 0 ? {} : { runsPerPath }
|
|
18582
|
+
})
|
|
18583
|
+
})
|
|
18584
|
+
);
|
|
18585
|
+
if (!parsedResponse.success) {
|
|
18586
|
+
throw new CliError(
|
|
18587
|
+
"Pathway regression matching-runs payload was invalid."
|
|
18588
|
+
);
|
|
18589
|
+
}
|
|
18590
|
+
return parsedResponse.data;
|
|
18591
|
+
},
|
|
18592
|
+
async startPathwayRegressionAgentVersionRun({
|
|
18593
|
+
accessToken,
|
|
18594
|
+
agentVersionId,
|
|
18595
|
+
automationVersionId,
|
|
18596
|
+
impersonatedOrganizationId,
|
|
18597
|
+
organizationId,
|
|
18598
|
+
runsPerPath
|
|
18599
|
+
}) {
|
|
18600
|
+
const parsedResponse = pathwayRegressionAgentVersionRunResponseSchema.safeParse(
|
|
18601
|
+
await fetchJson({
|
|
18602
|
+
accessToken,
|
|
18603
|
+
allowOttoAuthorization: true,
|
|
18604
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
18605
|
+
...organizationId ? { organizationId } : {},
|
|
18606
|
+
path: buildPathwayRegressionAgentVersionPath({
|
|
18607
|
+
agentVersionId,
|
|
18608
|
+
automationVersionId,
|
|
18609
|
+
leafPath: "run",
|
|
18610
|
+
...runsPerPath === void 0 ? {} : { runsPerPath }
|
|
18611
|
+
}),
|
|
18612
|
+
init: {
|
|
18613
|
+
method: "POST"
|
|
18614
|
+
}
|
|
18615
|
+
})
|
|
18616
|
+
);
|
|
18617
|
+
if (!parsedResponse.success) {
|
|
18618
|
+
throw new CliError("Pathway regression kickoff payload was invalid.");
|
|
18619
|
+
}
|
|
18620
|
+
return parsedResponse.data;
|
|
18621
|
+
},
|
|
18622
|
+
async getPathwayRegressionRunResult({
|
|
18623
|
+
accessToken,
|
|
18624
|
+
impersonatedOrganizationId,
|
|
18625
|
+
organizationId,
|
|
18626
|
+
regressionRunId
|
|
18627
|
+
}) {
|
|
18628
|
+
const parsedResponse = pathwayRegressionRunResultResponseSchema.safeParse(
|
|
18629
|
+
await fetchJson({
|
|
18630
|
+
accessToken,
|
|
18631
|
+
allowOttoAuthorization: true,
|
|
18632
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
18633
|
+
...organizationId ? { organizationId } : {},
|
|
18634
|
+
path: `/pathway-regression/runs/${encodeURIComponent(
|
|
18635
|
+
regressionRunId
|
|
18636
|
+
)}`
|
|
18637
|
+
})
|
|
18638
|
+
);
|
|
18639
|
+
if (!parsedResponse.success) {
|
|
18640
|
+
throw new CliError("Pathway regression run payload was invalid.");
|
|
18641
|
+
}
|
|
18642
|
+
return parsedResponse.data;
|
|
18643
|
+
},
|
|
18644
|
+
async getPathwayRegressionReplayIterationCheckResults({
|
|
18645
|
+
accessToken,
|
|
18646
|
+
impersonatedOrganizationId,
|
|
18647
|
+
organizationId,
|
|
18648
|
+
regressionReplayIterationId
|
|
18649
|
+
}) {
|
|
18650
|
+
const parsedResponse = pathwayRegressionReplayIterationCheckResultsResponseSchema.safeParse(
|
|
18651
|
+
await fetchJson({
|
|
18652
|
+
accessToken,
|
|
18653
|
+
allowOttoAuthorization: true,
|
|
18654
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
18655
|
+
...organizationId ? { organizationId } : {},
|
|
18656
|
+
path: `/pathway-regression/replay-iterations/${encodeURIComponent(
|
|
18657
|
+
regressionReplayIterationId
|
|
18658
|
+
)}/check-results`
|
|
18659
|
+
})
|
|
18660
|
+
);
|
|
18661
|
+
if (!parsedResponse.success) {
|
|
18662
|
+
throw new CliError(
|
|
18663
|
+
"Pathway regression replay iteration check-results payload was invalid."
|
|
18664
|
+
);
|
|
18665
|
+
}
|
|
18666
|
+
return parsedResponse.data;
|
|
17290
18667
|
}
|
|
17291
18668
|
};
|
|
17292
18669
|
}
|
|
@@ -17372,7 +18749,7 @@ function requireWorkosClientId(config) {
|
|
|
17372
18749
|
}
|
|
17373
18750
|
|
|
17374
18751
|
// src/settings.ts
|
|
17375
|
-
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
18752
|
+
import { mkdir, readFile, rm as rm2, writeFile } from "node:fs/promises";
|
|
17376
18753
|
import path3 from "node:path";
|
|
17377
18754
|
import { z as z27 } from "zod";
|
|
17378
18755
|
var cliSettingsSchema = z27.object({
|
|
@@ -17431,7 +18808,7 @@ function createFileSettingsStore(stateFilePath) {
|
|
|
17431
18808
|
},
|
|
17432
18809
|
async save(settings) {
|
|
17433
18810
|
if (!hasCliSettingsOverrides(settings)) {
|
|
17434
|
-
await
|
|
18811
|
+
await rm2(settingsFilePath, { force: true });
|
|
17435
18812
|
return;
|
|
17436
18813
|
}
|
|
17437
18814
|
await mkdir(path3.dirname(settingsFilePath), { recursive: true });
|
|
@@ -17520,6 +18897,7 @@ var rootOperationalGroupDescriptions = /* @__PURE__ */ new Map([
|
|
|
17520
18897
|
["automations", "Manage automations."],
|
|
17521
18898
|
["automation-runs", "Inspect and control automation runs."],
|
|
17522
18899
|
["catalog", "Inspect available commands, models, and tools."],
|
|
18900
|
+
["evals", "Discover registered evals and manage eval runs."],
|
|
17523
18901
|
["graphql", "Inspect GraphQL metadata."],
|
|
17524
18902
|
["skills", "Inspect and update root-level Workplace skills."]
|
|
17525
18903
|
]);
|
|
@@ -17529,29 +18907,525 @@ function configureCommandPresentation(command) {
|
|
|
17529
18907
|
command.createHelp = () => new MagicalHelp();
|
|
17530
18908
|
return command;
|
|
17531
18909
|
}
|
|
17532
|
-
function createOperationHelpExamples(operationSpec) {
|
|
17533
|
-
const
|
|
17534
|
-
const
|
|
17535
|
-
|
|
17536
|
-
|
|
18910
|
+
function createOperationHelpExamples(operationSpec) {
|
|
18911
|
+
const commandPath = operationSpec.cli.path.join(" ");
|
|
18912
|
+
const baseCommand = operationSpec.cli.branchContext === "required" ? `mgcl --branch-id <branch-id> ${commandPath}` : `mgcl ${commandPath}`;
|
|
18913
|
+
const requiredOptions = operationSpec.cli.options.filter((optionSpec) => optionSpec.required).map((optionSpec) => {
|
|
18914
|
+
if (optionSpec.valueType === "boolean") {
|
|
18915
|
+
return `--${optionSpec.flagName}`;
|
|
18916
|
+
}
|
|
18917
|
+
if (optionSpec.valueType === "number") {
|
|
18918
|
+
return `--${optionSpec.flagName} 10`;
|
|
18919
|
+
}
|
|
18920
|
+
if (optionSpec.valueType === "json") {
|
|
18921
|
+
return `--${optionSpec.flagName} '{...}'`;
|
|
18922
|
+
}
|
|
18923
|
+
if (optionSpec.valueType === "string-array") {
|
|
18924
|
+
return `--${optionSpec.flagName} value-a,value-b`;
|
|
18925
|
+
}
|
|
18926
|
+
return `--${optionSpec.flagName} <${optionSpec.flagName}>`;
|
|
18927
|
+
});
|
|
18928
|
+
const baseInvocation = [baseCommand, ...requiredOptions].join(" ");
|
|
18929
|
+
return [
|
|
18930
|
+
baseInvocation,
|
|
18931
|
+
...operationSpec.scope === "global" ? [] : [`${baseInvocation} --org <org>`],
|
|
18932
|
+
`${baseInvocation} --json`,
|
|
18933
|
+
...operationSpec.cli.branchContext === "optional" ? [
|
|
18934
|
+
[
|
|
18935
|
+
"mgcl --branch-id <branch-id>",
|
|
18936
|
+
commandPath,
|
|
18937
|
+
...requiredOptions,
|
|
18938
|
+
"--json"
|
|
18939
|
+
].join(" ")
|
|
18940
|
+
] : []
|
|
18941
|
+
];
|
|
18942
|
+
}
|
|
18943
|
+
|
|
18944
|
+
// src/eval-commands.ts
|
|
18945
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
18946
|
+
import { access as access2, readFile as readFile2 } from "node:fs/promises";
|
|
18947
|
+
import path4 from "node:path";
|
|
18948
|
+
import { createInterface } from "node:readline/promises";
|
|
18949
|
+
import { z as z28 } from "zod";
|
|
18950
|
+
var MAX_AWAIT_REQUEST_MS = 6e4;
|
|
18951
|
+
var MIN_AWAIT_REQUEST_MS = 1e3;
|
|
18952
|
+
var EXPORT_POLL_INTERVAL_MS = 1e3;
|
|
18953
|
+
var evalRunStatusSchema2 = z28.enum([
|
|
18954
|
+
"QUEUED",
|
|
18955
|
+
"RUNNING",
|
|
18956
|
+
"COMPLETE",
|
|
18957
|
+
"FAILED",
|
|
18958
|
+
"CANCELLED"
|
|
18959
|
+
]);
|
|
18960
|
+
var awaitResultSchema = z28.object({
|
|
18961
|
+
elapsedMs: z28.number().nonnegative(),
|
|
18962
|
+
evalRun: z28.object({
|
|
18963
|
+
id: z28.string().min(1),
|
|
18964
|
+
status: evalRunStatusSchema2
|
|
18965
|
+
}).passthrough(),
|
|
18966
|
+
pollCount: z28.number().int().nonnegative(),
|
|
18967
|
+
reachedTerminal: z28.boolean()
|
|
18968
|
+
}).passthrough();
|
|
18969
|
+
var planResultSchema = z28.object({ trialCount: z28.number().int().nonnegative() }).passthrough();
|
|
18970
|
+
var startResultSchema = z28.object({
|
|
18971
|
+
evalRunId: z28.string().min(1),
|
|
18972
|
+
idempotencyKey: z28.string().min(1),
|
|
18973
|
+
workflowId: z28.string().min(1),
|
|
18974
|
+
workflowRunId: z28.string().min(1)
|
|
18975
|
+
}).passthrough();
|
|
18976
|
+
var exportResultSchema = z28.object({
|
|
18977
|
+
downloadUrl: z28.string().min(1).nullable().optional(),
|
|
18978
|
+
evalRunId: z28.string().min(1),
|
|
18979
|
+
exportId: z28.string().min(1),
|
|
18980
|
+
status: z28.enum(["QUEUED", "RUNNING", "COMPLETE", "FAILED"])
|
|
18981
|
+
}).passthrough();
|
|
18982
|
+
var inputOptionsSchema = z28.object({
|
|
18983
|
+
inputFile: z28.string().min(1).optional(),
|
|
18984
|
+
inputJson: z28.unknown().optional()
|
|
18985
|
+
});
|
|
18986
|
+
var commonRunOptionsSchema = inputOptionsSchema.extend({
|
|
18987
|
+
description: z28.string().min(1).optional(),
|
|
18988
|
+
maxConcurrency: z28.number().int().positive().optional(),
|
|
18989
|
+
name: z28.string().min(1).optional(),
|
|
18990
|
+
repeatCount: z28.number().int().positive().optional(),
|
|
18991
|
+
slug: z28.string().min(1),
|
|
18992
|
+
tags: z28.array(z28.string().min(1)).optional()
|
|
18993
|
+
});
|
|
18994
|
+
function parseApiResult(value, schema, label) {
|
|
18995
|
+
const parsedResult = schema.safeParse(value);
|
|
18996
|
+
if (!parsedResult.success) {
|
|
18997
|
+
throw new CliError(`${label} returned an invalid response.`);
|
|
18998
|
+
}
|
|
18999
|
+
return parsedResult.data;
|
|
19000
|
+
}
|
|
19001
|
+
async function parseInputFile({
|
|
19002
|
+
inputFile,
|
|
19003
|
+
workingDirectory
|
|
19004
|
+
}) {
|
|
19005
|
+
const inputPath = path4.resolve(workingDirectory, inputFile);
|
|
19006
|
+
const contents = await readFile2(inputPath, "utf8").catch(
|
|
19007
|
+
(error) => {
|
|
19008
|
+
throw new CliError(`Failed to read eval input file "${inputPath}".`, {
|
|
19009
|
+
cause: error
|
|
19010
|
+
});
|
|
19011
|
+
}
|
|
19012
|
+
);
|
|
19013
|
+
const parsedJson = safeJsonParseWithoutLogging(contents);
|
|
19014
|
+
if (isErr(parsedJson)) {
|
|
19015
|
+
throw new CliError(
|
|
19016
|
+
`Eval input file "${inputPath}" must contain valid JSON.`,
|
|
19017
|
+
{ cause: parsedJson.error }
|
|
19018
|
+
);
|
|
19019
|
+
}
|
|
19020
|
+
return parsedJson.value;
|
|
19021
|
+
}
|
|
19022
|
+
async function resolveEvalInput({
|
|
19023
|
+
inputFile,
|
|
19024
|
+
inputJson,
|
|
19025
|
+
workingDirectory
|
|
19026
|
+
}) {
|
|
19027
|
+
const inputSourceCount = Number(inputFile !== void 0) + Number(inputJson !== void 0);
|
|
19028
|
+
if (inputSourceCount !== 1) {
|
|
19029
|
+
throw new CliError(
|
|
19030
|
+
"Pass exactly one of --input-file or --input-json for eval input."
|
|
19031
|
+
);
|
|
19032
|
+
}
|
|
19033
|
+
const input = inputFile === void 0 ? inputJson : await parseInputFile({ inputFile, workingDirectory });
|
|
19034
|
+
const parsedInput = z28.record(z28.string(), z28.unknown()).safeParse(input);
|
|
19035
|
+
if (!parsedInput.success) {
|
|
19036
|
+
throw new CliError("Eval input must be a JSON object.");
|
|
19037
|
+
}
|
|
19038
|
+
return parsedInput.data;
|
|
19039
|
+
}
|
|
19040
|
+
async function resolveEvalInputFromOptions({
|
|
19041
|
+
inputFile,
|
|
19042
|
+
inputJson,
|
|
19043
|
+
workingDirectory
|
|
19044
|
+
}) {
|
|
19045
|
+
return await resolveEvalInput({
|
|
19046
|
+
...inputFile === void 0 ? {} : { inputFile },
|
|
19047
|
+
...inputJson === void 0 ? {} : { inputJson },
|
|
19048
|
+
workingDirectory
|
|
19049
|
+
});
|
|
19050
|
+
}
|
|
19051
|
+
function buildCommonRunVariables({
|
|
19052
|
+
input,
|
|
19053
|
+
options
|
|
19054
|
+
}) {
|
|
19055
|
+
return {
|
|
19056
|
+
input,
|
|
19057
|
+
slug: options.slug,
|
|
19058
|
+
...options.description === void 0 ? {} : { description: options.description },
|
|
19059
|
+
...options.maxConcurrency === void 0 ? {} : { maxConcurrency: options.maxConcurrency },
|
|
19060
|
+
...options.name === void 0 ? {} : { name: options.name },
|
|
19061
|
+
...options.repeatCount === void 0 ? {} : { repeatCount: options.repeatCount },
|
|
19062
|
+
...options.tags === void 0 ? {} : { tags: options.tags }
|
|
19063
|
+
};
|
|
19064
|
+
}
|
|
19065
|
+
function parseDurationMs(value) {
|
|
19066
|
+
const match = /^(?<amount>\d+(?:\.\d+)?)(?<unit>ms|s|m|h)$/iu.exec(
|
|
19067
|
+
value.trim()
|
|
19068
|
+
);
|
|
19069
|
+
const amount = Number(match?.groups?.["amount"]);
|
|
19070
|
+
const multiplierByUnit = { h: 36e5, m: 6e4, ms: 1, s: 1e3 };
|
|
19071
|
+
const parsedUnit = z28.enum(["h", "m", "ms", "s"]).safeParse(match?.groups?.["unit"]?.toLowerCase());
|
|
19072
|
+
const durationMs = parsedUnit.success ? amount * multiplierByUnit[parsedUnit.data] : Number.NaN;
|
|
19073
|
+
if (!Number.isSafeInteger(durationMs) || durationMs < MIN_AWAIT_REQUEST_MS) {
|
|
19074
|
+
throw new CliError(
|
|
19075
|
+
"Expected --timeout to be a duration of at least 1s, such as 30s, 5m, or 1h."
|
|
19076
|
+
);
|
|
19077
|
+
}
|
|
19078
|
+
return durationMs;
|
|
19079
|
+
}
|
|
19080
|
+
function quotePosixShellArgument(value) {
|
|
19081
|
+
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
19082
|
+
}
|
|
19083
|
+
async function defaultConfirm(question) {
|
|
19084
|
+
const prompt = createInterface({
|
|
19085
|
+
input: process.stdin,
|
|
19086
|
+
output: process.stdout
|
|
19087
|
+
});
|
|
19088
|
+
const answer = await prompt.question(`${question} [y/N] `).finally(() => {
|
|
19089
|
+
prompt.close();
|
|
19090
|
+
});
|
|
19091
|
+
return answer.trim().toLowerCase() === "y" || answer.trim().toLowerCase() === "yes";
|
|
19092
|
+
}
|
|
19093
|
+
function terminalExitError(result) {
|
|
19094
|
+
const { id, status } = result.evalRun;
|
|
19095
|
+
if (status === "FAILED" || status === "CANCELLED") {
|
|
19096
|
+
return new CliError(`Eval run "${id}" finished with status ${status}.`);
|
|
19097
|
+
}
|
|
19098
|
+
return void 0;
|
|
19099
|
+
}
|
|
19100
|
+
async function awaitEvalRun({
|
|
19101
|
+
evalRunId,
|
|
19102
|
+
executeOperation,
|
|
19103
|
+
now: now2,
|
|
19104
|
+
timeoutMs
|
|
19105
|
+
}) {
|
|
19106
|
+
const deadline = timeoutMs === void 0 ? void 0 : now2() + timeoutMs;
|
|
19107
|
+
let previousResult = void 0;
|
|
19108
|
+
for (; ; ) {
|
|
19109
|
+
const remainingMs = deadline === void 0 ? void 0 : deadline - now2();
|
|
19110
|
+
if (remainingMs !== void 0 && remainingMs < MIN_AWAIT_REQUEST_MS) {
|
|
19111
|
+
return {
|
|
19112
|
+
exitError: new CliError(
|
|
19113
|
+
`Timed out waiting for eval run "${evalRunId}".`
|
|
19114
|
+
),
|
|
19115
|
+
result: previousResult ?? {
|
|
19116
|
+
elapsedMs: timeoutMs ?? 0,
|
|
19117
|
+
evalRun: { id: evalRunId, status: "QUEUED" },
|
|
19118
|
+
pollCount: 0,
|
|
19119
|
+
reachedTerminal: false
|
|
19120
|
+
}
|
|
19121
|
+
};
|
|
19122
|
+
}
|
|
19123
|
+
const requestTimeoutMs = Math.min(
|
|
19124
|
+
MAX_AWAIT_REQUEST_MS,
|
|
19125
|
+
remainingMs ?? MAX_AWAIT_REQUEST_MS
|
|
19126
|
+
);
|
|
19127
|
+
const result = parseApiResult(
|
|
19128
|
+
// eslint-disable-next-line no-await-in-loop -- each long-poll must finish before the next bounded request begins
|
|
19129
|
+
await executeOperation("AwaitEvalRun", {
|
|
19130
|
+
id: evalRunId,
|
|
19131
|
+
timeoutMs: requestTimeoutMs
|
|
19132
|
+
}),
|
|
19133
|
+
awaitResultSchema,
|
|
19134
|
+
"Eval run await"
|
|
19135
|
+
);
|
|
19136
|
+
if (result.reachedTerminal) {
|
|
19137
|
+
const exitError = terminalExitError(result);
|
|
19138
|
+
return { ...exitError ? { exitError } : {}, result };
|
|
19139
|
+
}
|
|
19140
|
+
previousResult = result;
|
|
19141
|
+
}
|
|
19142
|
+
}
|
|
19143
|
+
async function assertExportOutputAvailable({
|
|
19144
|
+
force,
|
|
19145
|
+
outputPath
|
|
19146
|
+
}) {
|
|
19147
|
+
if (force) {
|
|
19148
|
+
return;
|
|
19149
|
+
}
|
|
19150
|
+
const exists = await access2(outputPath).then(() => true).catch((error) => {
|
|
19151
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
19152
|
+
return false;
|
|
19153
|
+
}
|
|
19154
|
+
throw new CliError(`Failed to inspect export path "${outputPath}".`, {
|
|
19155
|
+
cause: error
|
|
19156
|
+
});
|
|
19157
|
+
});
|
|
19158
|
+
if (exists) {
|
|
19159
|
+
throw new CliError(
|
|
19160
|
+
`Refusing to overwrite existing file "${outputPath}". Pass --force to authorize replacement.`
|
|
19161
|
+
);
|
|
19162
|
+
}
|
|
19163
|
+
}
|
|
19164
|
+
async function finishExport({
|
|
19165
|
+
downloadFile,
|
|
19166
|
+
exportResult,
|
|
19167
|
+
force,
|
|
19168
|
+
outputPath
|
|
19169
|
+
}) {
|
|
19170
|
+
if (exportResult.status === "FAILED") {
|
|
19171
|
+
return {
|
|
19172
|
+
exitError: new CliError(`Eval export "${exportResult.exportId}" failed.`),
|
|
19173
|
+
result: exportResult
|
|
19174
|
+
};
|
|
19175
|
+
}
|
|
19176
|
+
if (exportResult.status !== "COMPLETE") {
|
|
19177
|
+
return { result: exportResult };
|
|
19178
|
+
}
|
|
19179
|
+
if (!exportResult.downloadUrl) {
|
|
19180
|
+
throw new CliError(
|
|
19181
|
+
`Completed eval export "${exportResult.exportId}" did not include a download URL.`
|
|
19182
|
+
);
|
|
19183
|
+
}
|
|
19184
|
+
if (!downloadFile) {
|
|
19185
|
+
throw new CliError("Eval export download is not configured.");
|
|
19186
|
+
}
|
|
19187
|
+
await downloadFile({
|
|
19188
|
+
outputPath,
|
|
19189
|
+
overwrite: force,
|
|
19190
|
+
url: exportResult.downloadUrl
|
|
19191
|
+
});
|
|
19192
|
+
const { downloadUrl: _downloadUrl, ...downloadedExport } = exportResult;
|
|
19193
|
+
return { result: { ...downloadedExport, outputPath } };
|
|
19194
|
+
}
|
|
19195
|
+
async function pollExport({
|
|
19196
|
+
executeOperation,
|
|
19197
|
+
exportId,
|
|
19198
|
+
sleep
|
|
19199
|
+
}) {
|
|
19200
|
+
for (; ; ) {
|
|
19201
|
+
await sleep(EXPORT_POLL_INTERVAL_MS);
|
|
19202
|
+
const result = parseApiResult(
|
|
19203
|
+
// eslint-disable-next-line no-await-in-loop -- do not overlap signed-export status requests
|
|
19204
|
+
await executeOperation("GetEvalRunExport", { exportId }),
|
|
19205
|
+
exportResultSchema,
|
|
19206
|
+
"Eval export status"
|
|
19207
|
+
);
|
|
19208
|
+
if (result.status !== "QUEUED" && result.status !== "RUNNING") {
|
|
19209
|
+
return result;
|
|
19210
|
+
}
|
|
19211
|
+
}
|
|
19212
|
+
}
|
|
19213
|
+
async function executeTestRegisteredEval({
|
|
19214
|
+
executeOperation,
|
|
19215
|
+
options,
|
|
19216
|
+
workingDirectory
|
|
19217
|
+
}) {
|
|
19218
|
+
const parsedOptions = commonRunOptionsSchema.pick({ slug: true }).merge(inputOptionsSchema).parse(options);
|
|
19219
|
+
const input = await resolveEvalInputFromOptions({
|
|
19220
|
+
...parsedOptions,
|
|
19221
|
+
workingDirectory
|
|
19222
|
+
});
|
|
19223
|
+
return {
|
|
19224
|
+
result: await executeOperation("TestRegisteredEval", {
|
|
19225
|
+
input,
|
|
19226
|
+
slug: parsedOptions.slug
|
|
19227
|
+
})
|
|
19228
|
+
};
|
|
19229
|
+
}
|
|
19230
|
+
async function executePlanRegisteredEvalRun({
|
|
19231
|
+
executeOperation,
|
|
19232
|
+
options,
|
|
19233
|
+
workingDirectory
|
|
19234
|
+
}) {
|
|
19235
|
+
const parsedOptions = commonRunOptionsSchema.parse(options);
|
|
19236
|
+
const input = await resolveEvalInputFromOptions({
|
|
19237
|
+
...parsedOptions,
|
|
19238
|
+
workingDirectory
|
|
19239
|
+
});
|
|
19240
|
+
return {
|
|
19241
|
+
result: await executeOperation(
|
|
19242
|
+
"PlanRegisteredEvalRun",
|
|
19243
|
+
buildCommonRunVariables({ input, options: parsedOptions })
|
|
19244
|
+
)
|
|
19245
|
+
};
|
|
19246
|
+
}
|
|
19247
|
+
async function confirmPlannedTrialCount({
|
|
19248
|
+
confirm,
|
|
19249
|
+
confirmedTrialCount,
|
|
19250
|
+
isInteractive,
|
|
19251
|
+
json,
|
|
19252
|
+
trialCount
|
|
19253
|
+
}) {
|
|
19254
|
+
if (confirmedTrialCount !== void 0) {
|
|
19255
|
+
if (confirmedTrialCount !== trialCount) {
|
|
19256
|
+
throw new CliError(
|
|
19257
|
+
`Planned ${trialCount} trials, but --confirm-trials was ${confirmedTrialCount}.`
|
|
19258
|
+
);
|
|
19259
|
+
}
|
|
19260
|
+
return;
|
|
19261
|
+
}
|
|
19262
|
+
if (json || !isInteractive) {
|
|
19263
|
+
throw new CliError(
|
|
19264
|
+
`This run will start ${trialCount} trials. Pass --confirm-trials ${trialCount} in non-interactive mode.`
|
|
19265
|
+
);
|
|
19266
|
+
}
|
|
19267
|
+
const confirmed = await confirm(`Start ${trialCount} eval trials?`);
|
|
19268
|
+
if (confirmed) {
|
|
19269
|
+
return;
|
|
19270
|
+
}
|
|
19271
|
+
throw new CliError("Eval run cancelled before starting.");
|
|
19272
|
+
}
|
|
19273
|
+
async function executeStartRegisteredEvalRun({
|
|
19274
|
+
executeOperation,
|
|
19275
|
+
options,
|
|
19276
|
+
runtime,
|
|
19277
|
+
workingDirectory
|
|
19278
|
+
}) {
|
|
19279
|
+
const parsedOptions = commonRunOptionsSchema.extend({
|
|
19280
|
+
confirmTrials: z28.number().int().positive().optional(),
|
|
19281
|
+
idempotencyKey: z28.string().trim().min(1).optional(),
|
|
19282
|
+
json: z28.boolean().optional(),
|
|
19283
|
+
wait: z28.boolean().optional()
|
|
19284
|
+
}).parse(options);
|
|
19285
|
+
const input = await resolveEvalInputFromOptions({
|
|
19286
|
+
...parsedOptions,
|
|
19287
|
+
workingDirectory
|
|
19288
|
+
});
|
|
19289
|
+
const commonVariables = buildCommonRunVariables({
|
|
19290
|
+
input,
|
|
19291
|
+
options: parsedOptions
|
|
19292
|
+
});
|
|
19293
|
+
const plan = parseApiResult(
|
|
19294
|
+
await executeOperation("PlanRegisteredEvalRun", commonVariables),
|
|
19295
|
+
planResultSchema,
|
|
19296
|
+
"Eval run plan"
|
|
19297
|
+
);
|
|
19298
|
+
await confirmPlannedTrialCount({
|
|
19299
|
+
confirm: runtime.confirm ?? defaultConfirm,
|
|
19300
|
+
...parsedOptions.confirmTrials === void 0 ? {} : { confirmedTrialCount: parsedOptions.confirmTrials },
|
|
19301
|
+
isInteractive: runtime.isInteractive?.() ?? (process.stdin.isTTY && process.stdout.isTTY),
|
|
19302
|
+
json: parsedOptions.json === true,
|
|
19303
|
+
trialCount: plan.trialCount
|
|
19304
|
+
});
|
|
19305
|
+
const idempotencyKey = parsedOptions.idempotencyKey ?? `mgcl-eval-${(runtime.randomUuid ?? randomUUID2)()}`;
|
|
19306
|
+
const start = await executeOperation("StartRegisteredEvalRun", {
|
|
19307
|
+
...commonVariables,
|
|
19308
|
+
expectedTrialCount: plan.trialCount,
|
|
19309
|
+
idempotencyKey
|
|
19310
|
+
}).catch((error) => {
|
|
19311
|
+
if (isDefinitiveGraphQlApplicationError(error)) {
|
|
19312
|
+
throw error;
|
|
19313
|
+
}
|
|
19314
|
+
throw new CliError(
|
|
19315
|
+
`${getErrorMessage(error)}
|
|
19316
|
+
If execution was accepted, retry with --idempotency-key ${quotePosixShellArgument(idempotencyKey)} to resolve the request safely.`,
|
|
19317
|
+
{ cause: error }
|
|
19318
|
+
);
|
|
19319
|
+
});
|
|
19320
|
+
const parsedStart = parseApiResult(
|
|
19321
|
+
start,
|
|
19322
|
+
startResultSchema,
|
|
19323
|
+
"Eval run start"
|
|
19324
|
+
);
|
|
19325
|
+
if (parsedOptions.wait !== true) {
|
|
19326
|
+
return { result: parsedStart };
|
|
19327
|
+
}
|
|
19328
|
+
const awaited = await awaitEvalRun({
|
|
19329
|
+
evalRunId: parsedStart.evalRunId,
|
|
19330
|
+
executeOperation,
|
|
19331
|
+
now: runtime.now ?? Date.now
|
|
19332
|
+
});
|
|
19333
|
+
return {
|
|
19334
|
+
...awaited.exitError ? { exitError: awaited.exitError } : {},
|
|
19335
|
+
result: { ...parsedStart, await: awaited.result }
|
|
19336
|
+
};
|
|
19337
|
+
}
|
|
19338
|
+
async function executeAwaitEvalRun({
|
|
19339
|
+
executeOperation,
|
|
19340
|
+
options,
|
|
19341
|
+
runtime
|
|
19342
|
+
}) {
|
|
19343
|
+
const parsedOptions = z28.object({ id: z28.string().min(1), timeout: z28.string().optional() }).parse(options);
|
|
19344
|
+
return await awaitEvalRun({
|
|
19345
|
+
evalRunId: parsedOptions.id,
|
|
19346
|
+
executeOperation,
|
|
19347
|
+
now: runtime.now ?? Date.now,
|
|
19348
|
+
...parsedOptions.timeout ? { timeoutMs: parseDurationMs(parsedOptions.timeout) } : {}
|
|
19349
|
+
});
|
|
19350
|
+
}
|
|
19351
|
+
async function defaultSleep(milliseconds) {
|
|
19352
|
+
await new Promise((resolve) => {
|
|
19353
|
+
setTimeout(resolve, milliseconds);
|
|
19354
|
+
});
|
|
19355
|
+
}
|
|
19356
|
+
async function executeRequestEvalRunExport({
|
|
19357
|
+
executeOperation,
|
|
19358
|
+
options,
|
|
19359
|
+
runtime,
|
|
19360
|
+
workingDirectory
|
|
19361
|
+
}) {
|
|
19362
|
+
const parsedOptions = z28.object({
|
|
19363
|
+
force: z28.boolean().optional(),
|
|
19364
|
+
id: z28.string().min(1),
|
|
19365
|
+
output: z28.string().min(1),
|
|
19366
|
+
wait: z28.boolean().optional()
|
|
19367
|
+
}).parse(options);
|
|
19368
|
+
const outputPath = path4.resolve(workingDirectory, parsedOptions.output);
|
|
19369
|
+
const force = parsedOptions.force === true;
|
|
19370
|
+
const shouldWait = parsedOptions.wait === true;
|
|
19371
|
+
if (shouldWait) {
|
|
19372
|
+
await assertExportOutputAvailable({ force, outputPath });
|
|
19373
|
+
}
|
|
19374
|
+
const requestedExport = parseApiResult(
|
|
19375
|
+
await executeOperation("RequestEvalRunExport", { id: parsedOptions.id }),
|
|
19376
|
+
exportResultSchema,
|
|
19377
|
+
"Eval export request"
|
|
19378
|
+
);
|
|
19379
|
+
if (!shouldWait) {
|
|
19380
|
+
return { result: requestedExport };
|
|
19381
|
+
}
|
|
19382
|
+
const exportResult = requestedExport.status === "QUEUED" || requestedExport.status === "RUNNING" ? await pollExport({
|
|
19383
|
+
executeOperation,
|
|
19384
|
+
exportId: requestedExport.exportId,
|
|
19385
|
+
sleep: runtime.sleep ?? defaultSleep
|
|
19386
|
+
}) : requestedExport;
|
|
19387
|
+
if (exportResult.status === "QUEUED" || exportResult.status === "RUNNING") {
|
|
19388
|
+
return { result: exportResult };
|
|
19389
|
+
}
|
|
19390
|
+
return await finishExport({
|
|
19391
|
+
...runtime.downloadFile ? { downloadFile: runtime.downloadFile } : {},
|
|
19392
|
+
exportResult,
|
|
19393
|
+
force,
|
|
19394
|
+
outputPath
|
|
19395
|
+
});
|
|
19396
|
+
}
|
|
19397
|
+
async function executeEvalCliOperation({
|
|
19398
|
+
executeOperation,
|
|
19399
|
+
operationName,
|
|
19400
|
+
options,
|
|
19401
|
+
runtime = {}
|
|
19402
|
+
}) {
|
|
19403
|
+
const handlerInput = {
|
|
19404
|
+
executeOperation,
|
|
19405
|
+
options,
|
|
19406
|
+
runtime,
|
|
19407
|
+
workingDirectory: runtime.workingDirectory ?? process.cwd()
|
|
19408
|
+
};
|
|
19409
|
+
switch (operationName) {
|
|
19410
|
+
case "TestRegisteredEval": {
|
|
19411
|
+
return await executeTestRegisteredEval(handlerInput);
|
|
17537
19412
|
}
|
|
17538
|
-
|
|
17539
|
-
return
|
|
19413
|
+
case "PlanRegisteredEvalRun": {
|
|
19414
|
+
return await executePlanRegisteredEvalRun(handlerInput);
|
|
17540
19415
|
}
|
|
17541
|
-
|
|
17542
|
-
return
|
|
19416
|
+
case "StartRegisteredEvalRun": {
|
|
19417
|
+
return await executeStartRegisteredEvalRun(handlerInput);
|
|
17543
19418
|
}
|
|
17544
|
-
|
|
17545
|
-
return
|
|
19419
|
+
case "AwaitEvalRun": {
|
|
19420
|
+
return await executeAwaitEvalRun(handlerInput);
|
|
17546
19421
|
}
|
|
17547
|
-
|
|
17548
|
-
|
|
17549
|
-
|
|
17550
|
-
|
|
17551
|
-
|
|
17552
|
-
|
|
17553
|
-
|
|
17554
|
-
];
|
|
19422
|
+
case "RequestEvalRunExport": {
|
|
19423
|
+
return await executeRequestEvalRunExport(handlerInput);
|
|
19424
|
+
}
|
|
19425
|
+
default: {
|
|
19426
|
+
return null;
|
|
19427
|
+
}
|
|
19428
|
+
}
|
|
17555
19429
|
}
|
|
17556
19430
|
|
|
17557
19431
|
// src/keychain.ts
|
|
@@ -17620,7 +19494,7 @@ function resolveOpenCommand(url) {
|
|
|
17620
19494
|
}
|
|
17621
19495
|
|
|
17622
19496
|
// src/program-session.ts
|
|
17623
|
-
import { readFile as
|
|
19497
|
+
import { readFile as readFile3, rm as rm3 } from "node:fs/promises";
|
|
17624
19498
|
async function withOrgScopedAccessToken({
|
|
17625
19499
|
dependencies,
|
|
17626
19500
|
organizationId,
|
|
@@ -17633,6 +19507,35 @@ async function withOrgScopedAccessToken({
|
|
|
17633
19507
|
if (directAccessToken) {
|
|
17634
19508
|
return { accessToken: directAccessToken };
|
|
17635
19509
|
}
|
|
19510
|
+
return await refreshAccessToken({
|
|
19511
|
+
dependencies,
|
|
19512
|
+
organizationId,
|
|
19513
|
+
state
|
|
19514
|
+
});
|
|
19515
|
+
}
|
|
19516
|
+
async function withGlobalAccessToken({
|
|
19517
|
+
authenticationOrganizationId,
|
|
19518
|
+
dependencies,
|
|
19519
|
+
state
|
|
19520
|
+
}) {
|
|
19521
|
+
const directAccessToken = await loadDirectAccessToken({
|
|
19522
|
+
dependencies,
|
|
19523
|
+
organizationId: authenticationOrganizationId
|
|
19524
|
+
});
|
|
19525
|
+
if (directAccessToken) {
|
|
19526
|
+
return { accessToken: directAccessToken };
|
|
19527
|
+
}
|
|
19528
|
+
return await refreshAccessToken({
|
|
19529
|
+
dependencies,
|
|
19530
|
+
organizationId: authenticationOrganizationId,
|
|
19531
|
+
state
|
|
19532
|
+
});
|
|
19533
|
+
}
|
|
19534
|
+
async function refreshAccessToken({
|
|
19535
|
+
dependencies,
|
|
19536
|
+
organizationId,
|
|
19537
|
+
state
|
|
19538
|
+
}) {
|
|
17636
19539
|
const refreshToken = await dependencies.refreshTokenStore.load(state.account);
|
|
17637
19540
|
if (!refreshToken) {
|
|
17638
19541
|
throw new CliError(
|
|
@@ -17664,7 +19567,7 @@ async function clearDirectAccessToken(runtimeConfig) {
|
|
|
17664
19567
|
if (!runtimeConfig.accessTokenFilePath) {
|
|
17665
19568
|
return;
|
|
17666
19569
|
}
|
|
17667
|
-
await
|
|
19570
|
+
await rm3(runtimeConfig.accessTokenFilePath, { force: true });
|
|
17668
19571
|
}
|
|
17669
19572
|
async function loadDirectAccessToken({
|
|
17670
19573
|
dependencies,
|
|
@@ -17674,7 +19577,7 @@ async function loadDirectAccessToken({
|
|
|
17674
19577
|
if (!accessTokenFilePath) {
|
|
17675
19578
|
return null;
|
|
17676
19579
|
}
|
|
17677
|
-
const accessTokenFileContents = await
|
|
19580
|
+
const accessTokenFileContents = await readFile3(accessTokenFilePath, "utf8").then((value) => value.trim()).catch((error) => {
|
|
17678
19581
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
17679
19582
|
return null;
|
|
17680
19583
|
}
|
|
@@ -17701,7 +19604,7 @@ async function loadDirectAccessToken({
|
|
|
17701
19604
|
}
|
|
17702
19605
|
return null;
|
|
17703
19606
|
}
|
|
17704
|
-
if (claims.org_id && claims.org_id !== organizationId) {
|
|
19607
|
+
if (organizationId !== void 0 && claims.org_id && claims.org_id !== organizationId) {
|
|
17705
19608
|
throw new CliError(
|
|
17706
19609
|
`The current Otto session is authenticated for organization "${claims.org_id}", not "${organizationId}". Start a new Otto session from the desired organization.`
|
|
17707
19610
|
);
|
|
@@ -17718,7 +19621,7 @@ function isExpiredAccessTokenClaims(claims) {
|
|
|
17718
19621
|
// src/self-update.ts
|
|
17719
19622
|
import { spawn as spawn2 } from "node:child_process";
|
|
17720
19623
|
import fs2 from "node:fs";
|
|
17721
|
-
import
|
|
19624
|
+
import path5 from "node:path";
|
|
17722
19625
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
17723
19626
|
var CLI_PACKAGE_NAME = "@getmagical/cli";
|
|
17724
19627
|
var DEFAULT_CLI_DIST_TAG2 = "latest";
|
|
@@ -17729,9 +19632,9 @@ function resolveInstalledPackageRoot({
|
|
|
17729
19632
|
packageName
|
|
17730
19633
|
}) {
|
|
17731
19634
|
const packagePathSegments = packageName.split("/");
|
|
17732
|
-
let currentPath =
|
|
19635
|
+
let currentPath = path5.dirname(entryFilePath);
|
|
17733
19636
|
for (; ; ) {
|
|
17734
|
-
const currentPathSegments = currentPath.split(
|
|
19637
|
+
const currentPathSegments = currentPath.split(path5.sep).filter(Boolean);
|
|
17735
19638
|
const currentPackageSegments = currentPathSegments.slice(
|
|
17736
19639
|
-packagePathSegments.length
|
|
17737
19640
|
);
|
|
@@ -17740,7 +19643,7 @@ function resolveInstalledPackageRoot({
|
|
|
17740
19643
|
)) {
|
|
17741
19644
|
return currentPath;
|
|
17742
19645
|
}
|
|
17743
|
-
const parentPath =
|
|
19646
|
+
const parentPath = path5.dirname(currentPath);
|
|
17744
19647
|
if (parentPath === currentPath) {
|
|
17745
19648
|
return null;
|
|
17746
19649
|
}
|
|
@@ -17750,14 +19653,14 @@ function resolveInstalledPackageRoot({
|
|
|
17750
19653
|
function resolveInstallPrefixFromPackageRoot(packageRootPath) {
|
|
17751
19654
|
let currentPath = packageRootPath;
|
|
17752
19655
|
for (; ; ) {
|
|
17753
|
-
if (
|
|
17754
|
-
const nodeModulesParentPath =
|
|
17755
|
-
if (
|
|
17756
|
-
return
|
|
19656
|
+
if (path5.basename(currentPath) === "node_modules") {
|
|
19657
|
+
const nodeModulesParentPath = path5.dirname(currentPath);
|
|
19658
|
+
if (path5.basename(nodeModulesParentPath) === "lib") {
|
|
19659
|
+
return path5.dirname(nodeModulesParentPath);
|
|
17757
19660
|
}
|
|
17758
19661
|
return nodeModulesParentPath;
|
|
17759
19662
|
}
|
|
17760
|
-
const parentPath =
|
|
19663
|
+
const parentPath = path5.dirname(currentPath);
|
|
17761
19664
|
if (parentPath === currentPath) {
|
|
17762
19665
|
return null;
|
|
17763
19666
|
}
|
|
@@ -17774,13 +19677,13 @@ function resolveManagedNpmCommand(installPrefix) {
|
|
|
17774
19677
|
if (process.platform === "win32") {
|
|
17775
19678
|
return null;
|
|
17776
19679
|
}
|
|
17777
|
-
const managedNodeExecutable =
|
|
19680
|
+
const managedNodeExecutable = path5.join(
|
|
17778
19681
|
installPrefix,
|
|
17779
19682
|
MANAGED_NODE_SUBPATH,
|
|
17780
19683
|
"bin",
|
|
17781
19684
|
"node"
|
|
17782
19685
|
);
|
|
17783
|
-
const managedNpmCli =
|
|
19686
|
+
const managedNpmCli = path5.join(
|
|
17784
19687
|
installPrefix,
|
|
17785
19688
|
MANAGED_NODE_SUBPATH,
|
|
17786
19689
|
"lib",
|
|
@@ -17979,20 +19882,20 @@ ${formatExamples("Examples", [
|
|
|
17979
19882
|
|
|
17980
19883
|
// src/skills-working-copy.ts
|
|
17981
19884
|
import { execFile } from "node:child_process";
|
|
17982
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
19885
|
+
import { createHash, randomUUID as randomUUID3 } from "node:crypto";
|
|
17983
19886
|
import {
|
|
17984
19887
|
lstat,
|
|
17985
19888
|
mkdir as mkdir2,
|
|
17986
19889
|
mkdtemp,
|
|
17987
|
-
readFile as
|
|
19890
|
+
readFile as readFile4,
|
|
17988
19891
|
readdir,
|
|
17989
|
-
rename,
|
|
17990
|
-
rm as
|
|
19892
|
+
rename as rename2,
|
|
19893
|
+
rm as rm4,
|
|
17991
19894
|
writeFile as writeFile2
|
|
17992
19895
|
} from "node:fs/promises";
|
|
17993
19896
|
import os2 from "node:os";
|
|
17994
|
-
import
|
|
17995
|
-
import { z as
|
|
19897
|
+
import path6 from "node:path";
|
|
19898
|
+
import { z as z29 } from "zod";
|
|
17996
19899
|
var SKILLS_ROOT_PATH = "skills";
|
|
17997
19900
|
var METADATA_DIRECTORY_NAME = "skill-working-copies";
|
|
17998
19901
|
var MAX_GIT_OUTPUT_BYTES = 10 * 1024 * 1024;
|
|
@@ -18001,40 +19904,40 @@ var FULL_COMMIT_SHA_PATTERN = /^[\dA-Fa-f]{40}$/u;
|
|
|
18001
19904
|
var UTF8_ENCODER = new TextEncoder();
|
|
18002
19905
|
var WINDOWS_RESERVED_PATH_CHARACTER_PATTERN = /[<>:"|?*]/u;
|
|
18003
19906
|
var WINDOWS_RESERVED_PATH_NAME_PATTERN = /^(?:AUX|CON|NUL|PRN|COM[1-9]|LPT[1-9])(?:\..*)?$/iu;
|
|
18004
|
-
var skillBundleSchema =
|
|
18005
|
-
files:
|
|
18006
|
-
|
|
18007
|
-
content:
|
|
18008
|
-
encoding:
|
|
18009
|
-
path:
|
|
18010
|
-
size:
|
|
19907
|
+
var skillBundleSchema = z29.object({
|
|
19908
|
+
files: z29.array(
|
|
19909
|
+
z29.object({
|
|
19910
|
+
content: z29.string(),
|
|
19911
|
+
encoding: z29.literal("base64"),
|
|
19912
|
+
path: z29.string().min(1),
|
|
19913
|
+
size: z29.number().int().nonnegative()
|
|
18011
19914
|
})
|
|
18012
19915
|
),
|
|
18013
|
-
path:
|
|
18014
|
-
ref:
|
|
19916
|
+
path: z29.string().min(1),
|
|
19917
|
+
ref: z29.string().regex(FULL_COMMIT_SHA_PATTERN)
|
|
18015
19918
|
});
|
|
18016
|
-
var skillsApplyPatchResultSchema =
|
|
18017
|
-
changedFiles:
|
|
18018
|
-
|
|
19919
|
+
var skillsApplyPatchResultSchema = z29.object({
|
|
19920
|
+
changedFiles: z29.array(
|
|
19921
|
+
z29.object({ path: z29.string().min(1), status: z29.string().min(1) })
|
|
18019
19922
|
),
|
|
18020
|
-
commit:
|
|
18021
|
-
ok:
|
|
18022
|
-
ref:
|
|
19923
|
+
commit: z29.string().regex(FULL_COMMIT_SHA_PATTERN),
|
|
19924
|
+
ok: z29.boolean(),
|
|
19925
|
+
ref: z29.string().min(1)
|
|
18023
19926
|
}).refine((result) => result.ok, {
|
|
18024
19927
|
message: "Skills patch result was not successful."
|
|
18025
19928
|
});
|
|
18026
|
-
var workingCopyMetadataSchema =
|
|
18027
|
-
version:
|
|
18028
|
-
files:
|
|
18029
|
-
|
|
18030
|
-
content:
|
|
18031
|
-
path:
|
|
19929
|
+
var workingCopyMetadataSchema = z29.object({
|
|
19930
|
+
version: z29.literal(1),
|
|
19931
|
+
files: z29.array(
|
|
19932
|
+
z29.object({
|
|
19933
|
+
content: z29.string(),
|
|
19934
|
+
path: z29.string().min(1)
|
|
18032
19935
|
})
|
|
18033
19936
|
),
|
|
18034
|
-
organizationId:
|
|
18035
|
-
requestedRef:
|
|
18036
|
-
skillPath:
|
|
18037
|
-
workingCopyPath:
|
|
19937
|
+
organizationId: z29.string().min(1),
|
|
19938
|
+
requestedRef: z29.string().min(1).nullable(),
|
|
19939
|
+
skillPath: z29.string().min(1),
|
|
19940
|
+
workingCopyPath: z29.string().min(1)
|
|
18038
19941
|
});
|
|
18039
19942
|
function hasControlCharacter2(value) {
|
|
18040
19943
|
return UTF8_ENCODER.encode(value).some((byte) => byte <= 31 || byte === 127);
|
|
@@ -18062,12 +19965,12 @@ function normalizeRootSkillPath(skill) {
|
|
|
18062
19965
|
return `${SKILLS_ROOT_PATH}/${skillName}`;
|
|
18063
19966
|
}
|
|
18064
19967
|
function resolveWorkingCopyPath(workingDirectory, skillPath) {
|
|
18065
|
-
return
|
|
19968
|
+
return path6.resolve(workingDirectory, ...skillPath.split("/"));
|
|
18066
19969
|
}
|
|
18067
19970
|
function resolveMetadataPath(stateFilePath, workingCopyPath) {
|
|
18068
19971
|
const key = createHash("sha256").update(workingCopyPath).digest("hex");
|
|
18069
|
-
return
|
|
18070
|
-
|
|
19972
|
+
return path6.join(
|
|
19973
|
+
path6.dirname(stateFilePath),
|
|
18071
19974
|
METADATA_DIRECTORY_NAME,
|
|
18072
19975
|
`${key}.json`
|
|
18073
19976
|
);
|
|
@@ -18095,7 +19998,7 @@ function metadataFilesToSnapshot(files) {
|
|
|
18095
19998
|
);
|
|
18096
19999
|
}
|
|
18097
20000
|
async function loadMetadata(metadataPath) {
|
|
18098
|
-
const fileContents = await
|
|
20001
|
+
const fileContents = await readFile4(metadataPath, "utf8").catch(
|
|
18099
20002
|
(error) => {
|
|
18100
20003
|
if (isMissingFileError(error)) {
|
|
18101
20004
|
return null;
|
|
@@ -18119,13 +20022,13 @@ async function loadMetadata(metadataPath) {
|
|
|
18119
20022
|
return parsed.data;
|
|
18120
20023
|
}
|
|
18121
20024
|
async function saveMetadata(metadataPath, metadata) {
|
|
18122
|
-
await mkdir2(
|
|
18123
|
-
const temporaryPath = `${metadataPath}.${
|
|
20025
|
+
await mkdir2(path6.dirname(metadataPath), { recursive: true });
|
|
20026
|
+
const temporaryPath = `${metadataPath}.${randomUUID3()}.tmp`;
|
|
18124
20027
|
await writeFile2(temporaryPath, `${JSON.stringify(metadata, null, 2)}
|
|
18125
20028
|
`, {
|
|
18126
20029
|
mode: 384
|
|
18127
20030
|
});
|
|
18128
|
-
await
|
|
20031
|
+
await rename2(temporaryPath, metadataPath);
|
|
18129
20032
|
}
|
|
18130
20033
|
function assertSafeRelativeFilePath(relativePath) {
|
|
18131
20034
|
const segments = relativePath.split("/");
|
|
@@ -18196,7 +20099,7 @@ async function readDirectorySnapshot({
|
|
|
18196
20099
|
const nextSegments = [...segments, entry.name];
|
|
18197
20100
|
const relativePath = nextSegments.join("/");
|
|
18198
20101
|
assertSafeRelativeFilePath(relativePath);
|
|
18199
|
-
const filePath =
|
|
20102
|
+
const filePath = path6.join(currentDirectory, entry.name);
|
|
18200
20103
|
if (entry.isDirectory()) {
|
|
18201
20104
|
return await visit(filePath, nextSegments);
|
|
18202
20105
|
}
|
|
@@ -18205,7 +20108,7 @@ async function readDirectorySnapshot({
|
|
|
18205
20108
|
`Skill working copy contains unsupported entry "${filePath}". Only regular files and directories are allowed.`
|
|
18206
20109
|
);
|
|
18207
20110
|
}
|
|
18208
|
-
return [[`${skillPath}/${relativePath}`, await
|
|
20111
|
+
return [[`${skillPath}/${relativePath}`, await readFile4(filePath)]];
|
|
18209
20112
|
})
|
|
18210
20113
|
);
|
|
18211
20114
|
return nestedEntries.flat();
|
|
@@ -18231,8 +20134,8 @@ async function writeSnapshotContents(rootPath, snapshot, prefix) {
|
|
|
18231
20134
|
[...snapshot.entries()].map(async ([filePath, content]) => {
|
|
18232
20135
|
const relativePath = prefix === null ? filePath : filePath.slice(`${prefix}/`.length);
|
|
18233
20136
|
assertSafeRelativeFilePath(relativePath);
|
|
18234
|
-
const targetPath =
|
|
18235
|
-
await mkdir2(
|
|
20137
|
+
const targetPath = path6.join(rootPath, ...relativePath.split("/"));
|
|
20138
|
+
await mkdir2(path6.dirname(targetPath), { recursive: true });
|
|
18236
20139
|
await writeFile2(targetPath, content);
|
|
18237
20140
|
})
|
|
18238
20141
|
);
|
|
@@ -18242,42 +20145,42 @@ async function replaceWorkingCopy({
|
|
|
18242
20145
|
skillPath,
|
|
18243
20146
|
workingCopyPath
|
|
18244
20147
|
}) {
|
|
18245
|
-
const parentPath =
|
|
20148
|
+
const parentPath = path6.dirname(workingCopyPath);
|
|
18246
20149
|
await mkdir2(parentPath, { recursive: true });
|
|
18247
|
-
const temporaryPath =
|
|
20150
|
+
const temporaryPath = path6.join(
|
|
18248
20151
|
parentPath,
|
|
18249
|
-
`.mgcl-${
|
|
20152
|
+
`.mgcl-${path6.basename(workingCopyPath)}-${randomUUID3()}.tmp`
|
|
18250
20153
|
);
|
|
18251
|
-
const backupPath = `${workingCopyPath}.${
|
|
20154
|
+
const backupPath = `${workingCopyPath}.${randomUUID3()}.bak`;
|
|
18252
20155
|
await mkdir2(temporaryPath);
|
|
18253
20156
|
const prepareResult = await fromThrowable(async () => {
|
|
18254
20157
|
await writeSnapshotContents(temporaryPath, snapshot, skillPath);
|
|
18255
20158
|
const hadExistingWorkingCopy = await pathExists(workingCopyPath);
|
|
18256
20159
|
if (hadExistingWorkingCopy) {
|
|
18257
|
-
await
|
|
20160
|
+
await rename2(workingCopyPath, backupPath);
|
|
18258
20161
|
}
|
|
18259
20162
|
return hadExistingWorkingCopy;
|
|
18260
20163
|
}, "skills-working-copy-replace-failed");
|
|
18261
20164
|
if (isErr(prepareResult)) {
|
|
18262
|
-
await
|
|
20165
|
+
await rm4(temporaryPath, { force: true, recursive: true });
|
|
18263
20166
|
throw new CliError("Failed to replace the skill working copy.", {
|
|
18264
20167
|
cause: prepareResult.error.cause
|
|
18265
20168
|
});
|
|
18266
20169
|
}
|
|
18267
20170
|
const activationResult = await fromThrowable(async () => {
|
|
18268
|
-
await
|
|
20171
|
+
await rename2(temporaryPath, workingCopyPath);
|
|
18269
20172
|
}, "skills-working-copy-activation-failed");
|
|
18270
20173
|
if (isErr(activationResult)) {
|
|
18271
20174
|
if (prepareResult.value) {
|
|
18272
|
-
await
|
|
20175
|
+
await rename2(backupPath, workingCopyPath);
|
|
18273
20176
|
}
|
|
18274
|
-
await
|
|
20177
|
+
await rm4(temporaryPath, { force: true, recursive: true });
|
|
18275
20178
|
throw new CliError("Failed to activate the new skill working copy.", {
|
|
18276
20179
|
cause: activationResult.error.cause
|
|
18277
20180
|
});
|
|
18278
20181
|
}
|
|
18279
20182
|
if (prepareResult.value) {
|
|
18280
|
-
await
|
|
20183
|
+
await rm4(backupPath, { force: true, recursive: true });
|
|
18281
20184
|
}
|
|
18282
20185
|
}
|
|
18283
20186
|
async function runGit(arguments_, cwd, allowedExitCodes = [0]) {
|
|
@@ -18317,7 +20220,7 @@ async function clearDirectoryExceptGit(directoryPath) {
|
|
|
18317
20220
|
const entries = await readdir(directoryPath);
|
|
18318
20221
|
await Promise.all(
|
|
18319
20222
|
entries.filter((entry) => entry !== ".git").map(async (entry) => {
|
|
18320
|
-
await
|
|
20223
|
+
await rm4(path6.join(directoryPath, entry), {
|
|
18321
20224
|
force: true,
|
|
18322
20225
|
recursive: true
|
|
18323
20226
|
});
|
|
@@ -18329,7 +20232,7 @@ async function createPatch(before, after) {
|
|
|
18329
20232
|
return "";
|
|
18330
20233
|
}
|
|
18331
20234
|
const repositoryPath = await mkdtemp(
|
|
18332
|
-
|
|
20235
|
+
path6.join(os2.tmpdir(), "mgcl-skills-diff-")
|
|
18333
20236
|
);
|
|
18334
20237
|
const patchResult = await fromThrowable(async () => {
|
|
18335
20238
|
await runGit(["init", "--quiet"], repositoryPath);
|
|
@@ -18372,7 +20275,7 @@ async function createPatch(before, after) {
|
|
|
18372
20275
|
);
|
|
18373
20276
|
return result.stdout.toString("utf8");
|
|
18374
20277
|
}, "skills-patch-generation-failed");
|
|
18375
|
-
await
|
|
20278
|
+
await rm4(repositoryPath, { force: true, recursive: true });
|
|
18376
20279
|
if (isErr(patchResult)) {
|
|
18377
20280
|
throw patchResult.error.cause;
|
|
18378
20281
|
}
|
|
@@ -18580,7 +20483,7 @@ async function pushSkillWorkingCopy({
|
|
|
18580
20483
|
assertTextPatch(patchContents);
|
|
18581
20484
|
const applyResult = await fromThrowable(
|
|
18582
20485
|
async () => await context.api.applyPatch({
|
|
18583
|
-
idempotencyKey: `mgcl-skills-${
|
|
20486
|
+
idempotencyKey: `mgcl-skills-${randomUUID3()}`,
|
|
18584
20487
|
message: message ?? `Update ${workingCopy.skillPath} via mgcl`,
|
|
18585
20488
|
patch: patchContents
|
|
18586
20489
|
}),
|
|
@@ -18651,34 +20554,34 @@ async function pushSkillWorkingCopy({
|
|
|
18651
20554
|
}
|
|
18652
20555
|
|
|
18653
20556
|
// src/state.ts
|
|
18654
|
-
import { mkdir as mkdir3, readFile as
|
|
18655
|
-
import
|
|
18656
|
-
import { z as
|
|
18657
|
-
var cliAccountSchema =
|
|
18658
|
-
clientId:
|
|
18659
|
-
email:
|
|
18660
|
-
userId:
|
|
20557
|
+
import { mkdir as mkdir3, readFile as readFile5, rm as rm5, writeFile as writeFile3 } from "node:fs/promises";
|
|
20558
|
+
import path7 from "node:path";
|
|
20559
|
+
import { z as z30 } from "zod";
|
|
20560
|
+
var cliAccountSchema = z30.object({
|
|
20561
|
+
clientId: z30.string().min(1),
|
|
20562
|
+
email: z30.string().nullable(),
|
|
20563
|
+
userId: z30.string().min(1)
|
|
18661
20564
|
});
|
|
18662
|
-
var cliOrganizationSchema =
|
|
18663
|
-
id:
|
|
18664
|
-
name:
|
|
18665
|
-
primaryDomain:
|
|
20565
|
+
var cliOrganizationSchema = z30.object({
|
|
20566
|
+
id: z30.string().min(1),
|
|
20567
|
+
name: z30.string().min(1),
|
|
20568
|
+
primaryDomain: z30.string().nullable().default(null)
|
|
18666
20569
|
});
|
|
18667
|
-
var cliStateSchema =
|
|
20570
|
+
var cliStateSchema = z30.object({
|
|
18668
20571
|
account: cliAccountSchema,
|
|
18669
|
-
defaultOrgId:
|
|
18670
|
-
lastUsedOrgId:
|
|
18671
|
-
organizations:
|
|
20572
|
+
defaultOrgId: z30.string().nullable(),
|
|
20573
|
+
lastUsedOrgId: z30.string().nullable(),
|
|
20574
|
+
organizations: z30.array(cliOrganizationSchema)
|
|
18672
20575
|
});
|
|
18673
|
-
var refreshTokenFileSchema =
|
|
20576
|
+
var refreshTokenFileSchema = z30.record(z30.string(), z30.string());
|
|
18674
20577
|
function createFileStateStore(stateFilePath) {
|
|
18675
20578
|
return {
|
|
18676
20579
|
async clear() {
|
|
18677
|
-
await
|
|
20580
|
+
await rm5(stateFilePath, { force: true });
|
|
18678
20581
|
},
|
|
18679
20582
|
async load() {
|
|
18680
20583
|
try {
|
|
18681
|
-
const fileContents = await
|
|
20584
|
+
const fileContents = await readFile5(stateFilePath, "utf8");
|
|
18682
20585
|
const parsed = cliStateSchema.safeParse(JSON.parse(fileContents));
|
|
18683
20586
|
if (!parsed.success) {
|
|
18684
20587
|
throw new CliError("Stored CLI state is invalid.");
|
|
@@ -18695,7 +20598,7 @@ function createFileStateStore(stateFilePath) {
|
|
|
18695
20598
|
}
|
|
18696
20599
|
},
|
|
18697
20600
|
async save(state) {
|
|
18698
|
-
await mkdir3(
|
|
20601
|
+
await mkdir3(path7.dirname(stateFilePath), { recursive: true });
|
|
18699
20602
|
await writeFile3(stateFilePath, `${JSON.stringify(state, null, 2)}
|
|
18700
20603
|
`);
|
|
18701
20604
|
}
|
|
@@ -18704,7 +20607,7 @@ function createFileStateStore(stateFilePath) {
|
|
|
18704
20607
|
function createFileRefreshTokenStore(refreshTokenFilePath) {
|
|
18705
20608
|
async function loadRefreshTokens() {
|
|
18706
20609
|
try {
|
|
18707
|
-
const fileContents = await
|
|
20610
|
+
const fileContents = await readFile5(refreshTokenFilePath, "utf8");
|
|
18708
20611
|
const parsed = refreshTokenFileSchema.safeParse(JSON.parse(fileContents));
|
|
18709
20612
|
if (!parsed.success) {
|
|
18710
20613
|
throw new CliError("Stored refresh tokens are invalid.");
|
|
@@ -18723,7 +20626,7 @@ function createFileRefreshTokenStore(refreshTokenFilePath) {
|
|
|
18723
20626
|
}
|
|
18724
20627
|
}
|
|
18725
20628
|
async function saveRefreshTokens(refreshTokens) {
|
|
18726
|
-
await mkdir3(
|
|
20629
|
+
await mkdir3(path7.dirname(refreshTokenFilePath), { recursive: true });
|
|
18727
20630
|
await writeFile3(
|
|
18728
20631
|
refreshTokenFilePath,
|
|
18729
20632
|
`${JSON.stringify(refreshTokens, null, 2)}
|
|
@@ -18740,7 +20643,7 @@ function createFileRefreshTokenStore(refreshTokenFilePath) {
|
|
|
18740
20643
|
)
|
|
18741
20644
|
);
|
|
18742
20645
|
if (Object.keys(nextRefreshTokens).length === 0) {
|
|
18743
|
-
await
|
|
20646
|
+
await rm5(refreshTokenFilePath, { force: true });
|
|
18744
20647
|
return;
|
|
18745
20648
|
}
|
|
18746
20649
|
await saveRefreshTokens(nextRefreshTokens);
|
|
@@ -18761,37 +20664,37 @@ function buildRefreshTokenKey(account) {
|
|
|
18761
20664
|
}
|
|
18762
20665
|
|
|
18763
20666
|
// src/workos-auth.ts
|
|
18764
|
-
import { z as
|
|
20667
|
+
import { z as z31 } from "zod";
|
|
18765
20668
|
var DEFAULT_DEVICE_POLL_INTERVAL_SECONDS = 5;
|
|
18766
20669
|
function buildFormHeaders() {
|
|
18767
20670
|
const headers = new Headers();
|
|
18768
20671
|
headers.set("content-type", "application/x-www-form-urlencoded");
|
|
18769
20672
|
return headers;
|
|
18770
20673
|
}
|
|
18771
|
-
var deviceAuthorizationSchema =
|
|
18772
|
-
device_code:
|
|
18773
|
-
expires_in:
|
|
18774
|
-
interval:
|
|
18775
|
-
user_code:
|
|
18776
|
-
verification_uri:
|
|
18777
|
-
verification_uri_complete:
|
|
20674
|
+
var deviceAuthorizationSchema = z31.object({
|
|
20675
|
+
device_code: z31.string().min(1),
|
|
20676
|
+
expires_in: z31.number().int().positive().optional(),
|
|
20677
|
+
interval: z31.number().int().positive().optional(),
|
|
20678
|
+
user_code: z31.string().min(1),
|
|
20679
|
+
verification_uri: z31.url(),
|
|
20680
|
+
verification_uri_complete: z31.url().optional()
|
|
18778
20681
|
});
|
|
18779
|
-
var tokenResponseSchema =
|
|
18780
|
-
access_token:
|
|
18781
|
-
expires_in:
|
|
18782
|
-
refresh_token:
|
|
18783
|
-
token_type:
|
|
20682
|
+
var tokenResponseSchema = z31.object({
|
|
20683
|
+
access_token: z31.string().min(1),
|
|
20684
|
+
expires_in: z31.number().int().positive().optional(),
|
|
20685
|
+
refresh_token: z31.string().min(1),
|
|
20686
|
+
token_type: z31.string().optional()
|
|
18784
20687
|
});
|
|
18785
|
-
var tokenErrorSchema =
|
|
18786
|
-
error:
|
|
18787
|
-
error_description:
|
|
20688
|
+
var tokenErrorSchema = z31.object({
|
|
20689
|
+
error: z31.string().min(1),
|
|
20690
|
+
error_description: z31.string().optional()
|
|
18788
20691
|
});
|
|
18789
|
-
var accessTokenClaimsSchema =
|
|
18790
|
-
exp:
|
|
18791
|
-
iss:
|
|
18792
|
-
org_id:
|
|
18793
|
-
sid:
|
|
18794
|
-
sub:
|
|
20692
|
+
var accessTokenClaimsSchema = z31.object({
|
|
20693
|
+
exp: z31.number().int().positive().optional(),
|
|
20694
|
+
iss: z31.string().min(1).optional(),
|
|
20695
|
+
org_id: z31.string().min(1).optional(),
|
|
20696
|
+
sid: z31.string().min(1).optional(),
|
|
20697
|
+
sub: z31.string().min(1)
|
|
18795
20698
|
});
|
|
18796
20699
|
function createWorkosAuthClient({
|
|
18797
20700
|
fetchFn = fetch,
|
|
@@ -18934,6 +20837,7 @@ function createWorkosAuthClient({
|
|
|
18934
20837
|
}
|
|
18935
20838
|
|
|
18936
20839
|
// src/program.ts
|
|
20840
|
+
var commandBranchContexts = /* @__PURE__ */ new WeakMap();
|
|
18937
20841
|
function buildCommandOptionProperty(flagName) {
|
|
18938
20842
|
const [firstSegment, ...remainingSegments] = flagName.split("-");
|
|
18939
20843
|
return [
|
|
@@ -18990,6 +20894,13 @@ function createCliCommanderOption(optionSpec, helpGroup) {
|
|
|
18990
20894
|
}
|
|
18991
20895
|
return nextOption;
|
|
18992
20896
|
}
|
|
20897
|
+
function parsePositiveIntegerOption(rawValue) {
|
|
20898
|
+
const parsedValue = Number(rawValue);
|
|
20899
|
+
if (!Number.isInteger(parsedValue) || parsedValue < 1) {
|
|
20900
|
+
throw new InvalidArgumentError2("Expected a positive integer.");
|
|
20901
|
+
}
|
|
20902
|
+
return parsedValue;
|
|
20903
|
+
}
|
|
18993
20904
|
function isRecord5(value) {
|
|
18994
20905
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18995
20906
|
}
|
|
@@ -19044,6 +20955,9 @@ function requireApiClientMethod(apiClient, key) {
|
|
|
19044
20955
|
function collectOperationVariables(operationSpec, options) {
|
|
19045
20956
|
const variables = Object.fromEntries(
|
|
19046
20957
|
operationSpec.cli.options.flatMap((optionSpec) => {
|
|
20958
|
+
if (optionSpec.clientOnly) {
|
|
20959
|
+
return [];
|
|
20960
|
+
}
|
|
19047
20961
|
const optionValue = options[buildCommandOptionProperty(optionSpec.flagName)];
|
|
19048
20962
|
if (optionValue === void 0) {
|
|
19049
20963
|
return [];
|
|
@@ -19051,6 +20965,13 @@ function collectOperationVariables(operationSpec, options) {
|
|
|
19051
20965
|
return [[optionSpec.inputKey, optionValue]];
|
|
19052
20966
|
})
|
|
19053
20967
|
);
|
|
20968
|
+
const { branchId } = options;
|
|
20969
|
+
if (operationSpec.cli.branchContext !== void 0 && typeof branchId === "string") {
|
|
20970
|
+
variables["branchId"] = branchId;
|
|
20971
|
+
}
|
|
20972
|
+
return parseOperationVariables(operationSpec, variables);
|
|
20973
|
+
}
|
|
20974
|
+
function parseOperationVariables(operationSpec, variables) {
|
|
19054
20975
|
const parsedVariables = operationSpec.inputSchema.safeParse(variables);
|
|
19055
20976
|
if (!parsedVariables.success) {
|
|
19056
20977
|
throw new CliError(
|
|
@@ -19130,6 +21051,14 @@ async function handleSelfUpdate(dependencies, options) {
|
|
|
19130
21051
|
);
|
|
19131
21052
|
}
|
|
19132
21053
|
async function handleOperationCommand(dependencies, operationSpec, commandOptions) {
|
|
21054
|
+
if (operationSpec.scope === "global") {
|
|
21055
|
+
await handleGlobalOperationCommand(
|
|
21056
|
+
dependencies,
|
|
21057
|
+
operationSpec,
|
|
21058
|
+
commandOptions
|
|
21059
|
+
);
|
|
21060
|
+
return;
|
|
21061
|
+
}
|
|
19133
21062
|
const { accessToken, impersonatedOrganizationId, organization, state } = await withSelectedOrganizationAndAccessToken({
|
|
19134
21063
|
dependencies,
|
|
19135
21064
|
options: commandOptions
|
|
@@ -19153,16 +21082,89 @@ async function handleOperationCommand(dependencies, operationSpec, commandOption
|
|
|
19153
21082
|
}
|
|
19154
21083
|
dependencies.io.info(formatHumanReadableOutput(result));
|
|
19155
21084
|
}
|
|
19156
|
-
function
|
|
21085
|
+
function getOperation(operationName) {
|
|
19157
21086
|
const operationSpec = operationSpecs.find(
|
|
19158
21087
|
(candidate) => candidate.operationName === operationName
|
|
19159
21088
|
);
|
|
19160
21089
|
if (!operationSpec) {
|
|
21090
|
+
throw new CliError(`Operation "${operationName}" is not registered.`);
|
|
21091
|
+
}
|
|
21092
|
+
return operationSpec;
|
|
21093
|
+
}
|
|
21094
|
+
async function withGlobalOperationAccessToken({
|
|
21095
|
+
dependencies
|
|
21096
|
+
}) {
|
|
21097
|
+
const state = requireLoggedInState(await dependencies.stateStore.load());
|
|
21098
|
+
const directAccessTokenOrganizationId = await resolveDirectAccessTokenOrganizationId({ dependencies });
|
|
21099
|
+
const authenticationOrganizationId = directAccessTokenOrganizationId ?? state.defaultOrgId ?? state.lastUsedOrgId ?? state.organizations[0]?.id;
|
|
21100
|
+
if (!authenticationOrganizationId) {
|
|
19161
21101
|
throw new CliError(
|
|
19162
|
-
|
|
21102
|
+
'No organization is available for authentication. Run "mgcl auth login" again.'
|
|
19163
21103
|
);
|
|
19164
21104
|
}
|
|
19165
|
-
|
|
21105
|
+
const { accessToken } = await withGlobalAccessToken({
|
|
21106
|
+
authenticationOrganizationId,
|
|
21107
|
+
dependencies,
|
|
21108
|
+
state
|
|
21109
|
+
});
|
|
21110
|
+
const usesOttoAuthorization = (() => {
|
|
21111
|
+
try {
|
|
21112
|
+
return dependencies.authClient.decodeAccessTokenClaims(accessToken).iss === "magical:otto";
|
|
21113
|
+
} catch {
|
|
21114
|
+
return false;
|
|
21115
|
+
}
|
|
21116
|
+
})();
|
|
21117
|
+
return {
|
|
21118
|
+
accessToken,
|
|
21119
|
+
...usesOttoAuthorization ? { organizationId: authenticationOrganizationId } : {}
|
|
21120
|
+
};
|
|
21121
|
+
}
|
|
21122
|
+
async function handleGlobalOperationCommand(dependencies, operationSpec, commandOptions) {
|
|
21123
|
+
const { accessToken, organizationId } = await withGlobalOperationAccessToken({
|
|
21124
|
+
dependencies
|
|
21125
|
+
});
|
|
21126
|
+
const executeOperation = async (operationName, variables) => {
|
|
21127
|
+
const nextOperationSpec = getOperation(operationName);
|
|
21128
|
+
if (nextOperationSpec.scope !== "global") {
|
|
21129
|
+
throw new CliError(
|
|
21130
|
+
`Global operation "${operationName}" cannot execute an organization-scoped operation.`
|
|
21131
|
+
);
|
|
21132
|
+
}
|
|
21133
|
+
return await dependencies.apiClient.executeGraphQl({
|
|
21134
|
+
accessToken,
|
|
21135
|
+
...organizationId ? { organizationId } : {},
|
|
21136
|
+
query: nextOperationSpec.document,
|
|
21137
|
+
resultKey: nextOperationSpec.cli.resultKey,
|
|
21138
|
+
variables: parseOperationVariables(nextOperationSpec, variables)
|
|
21139
|
+
});
|
|
21140
|
+
};
|
|
21141
|
+
const customResult = await executeEvalCliOperation({
|
|
21142
|
+
executeOperation,
|
|
21143
|
+
operationName: operationSpec.operationName,
|
|
21144
|
+
options: commandOptions,
|
|
21145
|
+
runtime: {
|
|
21146
|
+
...dependencies.evalCommandRuntime,
|
|
21147
|
+
...dependencies.apiClient.downloadFile ? { downloadFile: dependencies.apiClient.downloadFile } : {},
|
|
21148
|
+
workingDirectory: dependencies.evalCommandRuntime?.workingDirectory ?? dependencies.workingDirectory ?? process.cwd()
|
|
21149
|
+
}
|
|
21150
|
+
});
|
|
21151
|
+
const commandResult = customResult ?? {
|
|
21152
|
+
result: await executeOperation(
|
|
21153
|
+
operationSpec.operationName,
|
|
21154
|
+
collectOperationVariables(operationSpec, commandOptions)
|
|
21155
|
+
)
|
|
21156
|
+
};
|
|
21157
|
+
writeCommandOutput({
|
|
21158
|
+
dependencies,
|
|
21159
|
+
json: commandOptions.json,
|
|
21160
|
+
result: commandResult.result
|
|
21161
|
+
});
|
|
21162
|
+
if (commandResult.exitError) {
|
|
21163
|
+
throw commandResult.exitError;
|
|
21164
|
+
}
|
|
21165
|
+
}
|
|
21166
|
+
function getSkillsOperation(operationName) {
|
|
21167
|
+
return getOperation(operationName);
|
|
19166
21168
|
}
|
|
19167
21169
|
async function withSkillsWorkingCopyContext(dependencies, options) {
|
|
19168
21170
|
const { accessToken, impersonatedOrganizationId, organization, state } = await withSelectedOrganizationAndAccessToken({ dependencies, options });
|
|
@@ -19413,6 +21415,217 @@ async function handleNangoAuthsListCommand(dependencies, options) {
|
|
|
19413
21415
|
result: authentications
|
|
19414
21416
|
});
|
|
19415
21417
|
}
|
|
21418
|
+
function summarizePathwayRegressionPreview(result) {
|
|
21419
|
+
return {
|
|
21420
|
+
automationVersionId: result.automationVersionId,
|
|
21421
|
+
agentVersionId: result.agentVersionId,
|
|
21422
|
+
contractId: result.contractId,
|
|
21423
|
+
pathwayCount: result.paths.length,
|
|
21424
|
+
selectedReplayCount: result.paths.reduce(
|
|
21425
|
+
(sum, pathway) => sum + pathway.runs.length,
|
|
21426
|
+
0
|
|
21427
|
+
),
|
|
21428
|
+
paths: result.paths.map((pathway) => ({
|
|
21429
|
+
sortOrder: pathway.sortOrder,
|
|
21430
|
+
label: pathway.label,
|
|
21431
|
+
pathwayKey: pathway.pathwayKey,
|
|
21432
|
+
matchingRunCount: pathway.runs.length,
|
|
21433
|
+
runs: pathway.runs.map((run) => ({
|
|
21434
|
+
agentRunId: run.agentRunId,
|
|
21435
|
+
automationRunId: run.automationRunId,
|
|
21436
|
+
finishedAt: run.finishedAt,
|
|
21437
|
+
stepCount: run.stepCount
|
|
21438
|
+
}))
|
|
21439
|
+
}))
|
|
21440
|
+
};
|
|
21441
|
+
}
|
|
21442
|
+
function summarizePathwayRegressionKickoff(result) {
|
|
21443
|
+
if ("contractWorkflowId" in result) {
|
|
21444
|
+
return {
|
|
21445
|
+
status: result.status,
|
|
21446
|
+
contractGenerationStatus: result.contractGenerationStatus,
|
|
21447
|
+
contractWorkflowId: result.contractWorkflowId,
|
|
21448
|
+
regressionRunId: result.regressionRunId,
|
|
21449
|
+
workflowId: result.workflowId,
|
|
21450
|
+
selectedReplayCount: result.selectedReplayCount,
|
|
21451
|
+
automationVersionId: result.automationVersionId,
|
|
21452
|
+
agentVersionId: result.agentVersionId
|
|
21453
|
+
};
|
|
21454
|
+
}
|
|
21455
|
+
return {
|
|
21456
|
+
regressionRunId: result.regressionRunId,
|
|
21457
|
+
workflowId: result.workflowId,
|
|
21458
|
+
status: result.status,
|
|
21459
|
+
selectedReplayCount: result.selectedReplayCount,
|
|
21460
|
+
automationVersionId: result.automationVersionId,
|
|
21461
|
+
agentVersionId: result.agentVersionId,
|
|
21462
|
+
contractId: result.contractId,
|
|
21463
|
+
baselineAutomationVersionId: result.baselineAutomationVersionId,
|
|
21464
|
+
baselineAgentVersionId: result.baselineAgentVersionId,
|
|
21465
|
+
baselineContractId: result.baselineContractId,
|
|
21466
|
+
candidateContractId: result.candidateContractId,
|
|
21467
|
+
paths: result.paths.map((pathway) => ({
|
|
21468
|
+
sortOrder: pathway.candidate?.sortOrder ?? pathway.baseline?.sortOrder ?? null,
|
|
21469
|
+
baselineLabel: pathway.baseline?.label ?? null,
|
|
21470
|
+
candidateLabel: pathway.candidate?.label ?? null,
|
|
21471
|
+
pathwayKey: pathway.pathwayKey,
|
|
21472
|
+
selectedRunCount: pathway.selectedRunCount,
|
|
21473
|
+
status: pathway.status,
|
|
21474
|
+
isInLatestPublishedBaseline: pathway.isInLatestPublishedBaseline ?? null,
|
|
21475
|
+
lastSeenPublishedAutomationVersionId: pathway.lastSeenPublishedAutomationVersionId ?? null,
|
|
21476
|
+
lastSeenPublishedAgentVersionId: pathway.lastSeenPublishedAgentVersionId ?? null,
|
|
21477
|
+
lastSeenPublishedSequence: pathway.lastSeenPublishedSequence ?? null
|
|
21478
|
+
}))
|
|
21479
|
+
};
|
|
21480
|
+
}
|
|
21481
|
+
function summarizePathwayRegressionResult(result) {
|
|
21482
|
+
const replayCount = result.pathways.reduce(
|
|
21483
|
+
(sum, pathway) => sum + pathway.replays.length,
|
|
21484
|
+
0
|
|
21485
|
+
);
|
|
21486
|
+
return {
|
|
21487
|
+
regressionRunId: result.regressionRun.id,
|
|
21488
|
+
workflowId: result.regressionRun.workflowId,
|
|
21489
|
+
scope: result.regressionRun.scope,
|
|
21490
|
+
status: result.regressionRun.status,
|
|
21491
|
+
finishedAt: result.regressionRun.finishedAt,
|
|
21492
|
+
pathwayCount: result.pathways.length,
|
|
21493
|
+
replayCount,
|
|
21494
|
+
pathways: result.pathways.map((pathway) => ({
|
|
21495
|
+
sortOrder: pathway.sortOrder,
|
|
21496
|
+
label: pathway.label ?? pathway.pathwayKey,
|
|
21497
|
+
pathwayKey: pathway.pathwayKey,
|
|
21498
|
+
replays: pathway.replays.map((replay) => ({
|
|
21499
|
+
regressionReplayId: replay.id,
|
|
21500
|
+
baselineAgentRunId: replay.baselineAgentRunId,
|
|
21501
|
+
baselineAutomationRunId: replay.baselineAutomationRunId,
|
|
21502
|
+
status: replay.status,
|
|
21503
|
+
checks: replay.checks,
|
|
21504
|
+
nonPassingIterations: replay.iterations.filter((iteration) => iteration.status !== "passed").map((iteration) => ({
|
|
21505
|
+
regressionReplayIterationId: iteration.id,
|
|
21506
|
+
sequence: iteration.sequence,
|
|
21507
|
+
status: iteration.status,
|
|
21508
|
+
expectedToolName: iteration.expectedToolName,
|
|
21509
|
+
observedToolName: iteration.observedToolName
|
|
21510
|
+
}))
|
|
21511
|
+
}))
|
|
21512
|
+
}))
|
|
21513
|
+
};
|
|
21514
|
+
}
|
|
21515
|
+
function summarizePathwayRegressionReplayIterationCheckResults(result) {
|
|
21516
|
+
const { regressionReplayIteration } = result;
|
|
21517
|
+
return {
|
|
21518
|
+
regressionReplayId: regressionReplayIteration.regressionReplayId,
|
|
21519
|
+
regressionReplayIterationId: regressionReplayIteration.id,
|
|
21520
|
+
sequence: regressionReplayIteration.sequence,
|
|
21521
|
+
status: regressionReplayIteration.status,
|
|
21522
|
+
expectedToolName: regressionReplayIteration.expectedToolName,
|
|
21523
|
+
observedToolName: regressionReplayIteration.observedToolName,
|
|
21524
|
+
checkCount: regressionReplayIteration.checkResults.length,
|
|
21525
|
+
checks: regressionReplayIteration.checkResults.map((checkResult) => ({
|
|
21526
|
+
attemptIndex: checkResult.attemptIndex,
|
|
21527
|
+
status: checkResult.status,
|
|
21528
|
+
expectedToolName: checkResult.expectedToolName,
|
|
21529
|
+
actualToolName: checkResult.actualToolName,
|
|
21530
|
+
outputResult: checkResult.outputResult
|
|
21531
|
+
}))
|
|
21532
|
+
};
|
|
21533
|
+
}
|
|
21534
|
+
async function handlePathwayRegressionPreviewCommand(dependencies, options) {
|
|
21535
|
+
const { accessToken, impersonatedOrganizationId, organization, state } = await withSelectedOrganizationAndAccessToken({ dependencies, options });
|
|
21536
|
+
const previewPathwayRegressionMatchingRuns = requireApiClientMethod(
|
|
21537
|
+
dependencies.apiClient,
|
|
21538
|
+
"previewPathwayRegressionMatchingRuns"
|
|
21539
|
+
);
|
|
21540
|
+
const result = await previewPathwayRegressionMatchingRuns({
|
|
21541
|
+
accessToken,
|
|
21542
|
+
agentVersionId: options.agentVersionId,
|
|
21543
|
+
automationVersionId: options.automationVersionId,
|
|
21544
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
21545
|
+
organizationId: organization.id,
|
|
21546
|
+
...options.runsPerPath === void 0 ? {} : { runsPerPath: options.runsPerPath }
|
|
21547
|
+
});
|
|
21548
|
+
await saveLastUsedOrganization({
|
|
21549
|
+
dependencies,
|
|
21550
|
+
organizationId: organization.id,
|
|
21551
|
+
state
|
|
21552
|
+
});
|
|
21553
|
+
writeCommandOutput({
|
|
21554
|
+
dependencies,
|
|
21555
|
+
json: options.json,
|
|
21556
|
+
result: options.json ? result : summarizePathwayRegressionPreview(result)
|
|
21557
|
+
});
|
|
21558
|
+
}
|
|
21559
|
+
async function handlePathwayRegressionRunCommand(dependencies, options) {
|
|
21560
|
+
const { accessToken, impersonatedOrganizationId, organization, state } = await withSelectedOrganizationAndAccessToken({ dependencies, options });
|
|
21561
|
+
const startPathwayRegressionAgentVersionRun = requireApiClientMethod(
|
|
21562
|
+
dependencies.apiClient,
|
|
21563
|
+
"startPathwayRegressionAgentVersionRun"
|
|
21564
|
+
);
|
|
21565
|
+
const result = await startPathwayRegressionAgentVersionRun({
|
|
21566
|
+
accessToken,
|
|
21567
|
+
agentVersionId: options.agentVersionId,
|
|
21568
|
+
automationVersionId: options.automationVersionId,
|
|
21569
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
21570
|
+
organizationId: organization.id
|
|
21571
|
+
});
|
|
21572
|
+
await saveLastUsedOrganization({
|
|
21573
|
+
dependencies,
|
|
21574
|
+
organizationId: organization.id,
|
|
21575
|
+
state
|
|
21576
|
+
});
|
|
21577
|
+
writeCommandOutput({
|
|
21578
|
+
dependencies,
|
|
21579
|
+
json: options.json,
|
|
21580
|
+
result: options.json ? result : summarizePathwayRegressionKickoff(result)
|
|
21581
|
+
});
|
|
21582
|
+
}
|
|
21583
|
+
async function handlePathwayRegressionResultsCommand(dependencies, options) {
|
|
21584
|
+
const { accessToken, impersonatedOrganizationId, organization, state } = await withSelectedOrganizationAndAccessToken({ dependencies, options });
|
|
21585
|
+
const getPathwayRegressionRunResult = requireApiClientMethod(
|
|
21586
|
+
dependencies.apiClient,
|
|
21587
|
+
"getPathwayRegressionRunResult"
|
|
21588
|
+
);
|
|
21589
|
+
const result = await getPathwayRegressionRunResult({
|
|
21590
|
+
accessToken,
|
|
21591
|
+
regressionRunId: options.regressionRunId,
|
|
21592
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
21593
|
+
organizationId: organization.id
|
|
21594
|
+
});
|
|
21595
|
+
await saveLastUsedOrganization({
|
|
21596
|
+
dependencies,
|
|
21597
|
+
organizationId: organization.id,
|
|
21598
|
+
state
|
|
21599
|
+
});
|
|
21600
|
+
writeCommandOutput({
|
|
21601
|
+
dependencies,
|
|
21602
|
+
json: options.json,
|
|
21603
|
+
result: options.json ? result : summarizePathwayRegressionResult(result)
|
|
21604
|
+
});
|
|
21605
|
+
}
|
|
21606
|
+
async function handlePathwayRegressionCheckResultsCommand(dependencies, options) {
|
|
21607
|
+
const { accessToken, impersonatedOrganizationId, organization, state } = await withSelectedOrganizationAndAccessToken({ dependencies, options });
|
|
21608
|
+
const getPathwayRegressionReplayIterationCheckResults = requireApiClientMethod(
|
|
21609
|
+
dependencies.apiClient,
|
|
21610
|
+
"getPathwayRegressionReplayIterationCheckResults"
|
|
21611
|
+
);
|
|
21612
|
+
const result = await getPathwayRegressionReplayIterationCheckResults({
|
|
21613
|
+
accessToken,
|
|
21614
|
+
regressionReplayIterationId: options.regressionReplayIterationId,
|
|
21615
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
21616
|
+
organizationId: organization.id
|
|
21617
|
+
});
|
|
21618
|
+
await saveLastUsedOrganization({
|
|
21619
|
+
dependencies,
|
|
21620
|
+
organizationId: organization.id,
|
|
21621
|
+
state
|
|
21622
|
+
});
|
|
21623
|
+
writeCommandOutput({
|
|
21624
|
+
dependencies,
|
|
21625
|
+
json: options.json,
|
|
21626
|
+
result: options.json ? result : summarizePathwayRegressionReplayIterationCheckResults(result)
|
|
21627
|
+
});
|
|
21628
|
+
}
|
|
19416
21629
|
async function resolveDirectAccessTokenOrganizationId({
|
|
19417
21630
|
dependencies
|
|
19418
21631
|
}) {
|
|
@@ -19420,7 +21633,7 @@ async function resolveDirectAccessTokenOrganizationId({
|
|
|
19420
21633
|
if (!accessTokenFilePath) {
|
|
19421
21634
|
return null;
|
|
19422
21635
|
}
|
|
19423
|
-
const accessToken = await
|
|
21636
|
+
const accessToken = await readFile6(accessTokenFilePath, "utf8").then((value) => value.trim()).catch((error) => {
|
|
19424
21637
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
19425
21638
|
return null;
|
|
19426
21639
|
}
|
|
@@ -19452,6 +21665,9 @@ function addRegistryOperationCommand({
|
|
|
19452
21665
|
dependencies,
|
|
19453
21666
|
operationSpec
|
|
19454
21667
|
}) {
|
|
21668
|
+
if (operationSpec.cli.hidden) {
|
|
21669
|
+
return;
|
|
21670
|
+
}
|
|
19455
21671
|
const commandPath = [...operationSpec.cli.path];
|
|
19456
21672
|
const leafCommandName = commandPath.pop();
|
|
19457
21673
|
if (!leafCommandName) {
|
|
@@ -19488,12 +21704,17 @@ function addRegistryOperationCommand({
|
|
|
19488
21704
|
configureOperationalCommand(legacyAliasCommand, dependencies, operationSpec);
|
|
19489
21705
|
}
|
|
19490
21706
|
function configureOperationalCommand(command, dependencies, operationSpec) {
|
|
19491
|
-
|
|
19492
|
-
|
|
19493
|
-
|
|
19494
|
-
|
|
19495
|
-
|
|
19496
|
-
|
|
21707
|
+
commandBranchContexts.set(command, operationSpec.cli.branchContext);
|
|
21708
|
+
command.description(operationSpec.cli.description);
|
|
21709
|
+
if (operationSpec.scope !== "global") {
|
|
21710
|
+
command.addOption(
|
|
21711
|
+
new Option2(
|
|
21712
|
+
"--org <org>",
|
|
21713
|
+
"Organization ID or exact organization name to use."
|
|
21714
|
+
).helpGroup("Shared options:")
|
|
21715
|
+
);
|
|
21716
|
+
}
|
|
21717
|
+
command.addHelpText(
|
|
19497
21718
|
"after",
|
|
19498
21719
|
`
|
|
19499
21720
|
${formatExamples(
|
|
@@ -19532,12 +21753,12 @@ function createConsoleIo() {
|
|
|
19532
21753
|
function createDefaultDependencies() {
|
|
19533
21754
|
const runtimeConfig = getRuntimeConfig();
|
|
19534
21755
|
const settingsStore = createFileSettingsStore(runtimeConfig.stateFilePath);
|
|
19535
|
-
const accessTokenFilePath = runtimeConfig.accessTokenFilePath ??
|
|
19536
|
-
|
|
21756
|
+
const accessTokenFilePath = runtimeConfig.accessTokenFilePath ?? path8.join(
|
|
21757
|
+
path8.dirname(runtimeConfig.stateFilePath),
|
|
19537
21758
|
CLI_ACCESS_TOKEN_FILE_NAME
|
|
19538
21759
|
);
|
|
19539
|
-
const refreshTokenFilePath = runtimeConfig.refreshTokenFilePath ??
|
|
19540
|
-
|
|
21760
|
+
const refreshTokenFilePath = runtimeConfig.refreshTokenFilePath ?? path8.join(
|
|
21761
|
+
path8.dirname(runtimeConfig.stateFilePath),
|
|
19541
21762
|
CLI_REFRESH_TOKEN_FILE_NAME
|
|
19542
21763
|
);
|
|
19543
21764
|
const selfUpdateOptions = {
|
|
@@ -19569,7 +21790,12 @@ function createDefaultDependencies() {
|
|
|
19569
21790
|
function buildProgram(dependencies) {
|
|
19570
21791
|
const program2 = configureCommandPresentation(
|
|
19571
21792
|
new Command2().name("mgcl").description("Run Magical operations from the command line.")
|
|
19572
|
-
).addOption(new Option2("--json", "Render JSON output.")).
|
|
21793
|
+
).addOption(new Option2("--json", "Render JSON output.")).addOption(
|
|
21794
|
+
new Option2(
|
|
21795
|
+
"--branch-id <id>",
|
|
21796
|
+
"Target a supported automation command at one branch; omit it to target main."
|
|
21797
|
+
)
|
|
21798
|
+
).version(CLI_VERSION, "--version", `Display mgcl version (${CLI_VERSION}).`).addOption(
|
|
19573
21799
|
new Option2(
|
|
19574
21800
|
"--update",
|
|
19575
21801
|
"Update mgcl to the latest published npm release."
|
|
@@ -19587,6 +21813,18 @@ ${formatExamples("Quick start", [
|
|
|
19587
21813
|
|
|
19588
21814
|
${formatOutputModesNote()}`
|
|
19589
21815
|
);
|
|
21816
|
+
program2.hook("preAction", (_thisCommand, actionCommand) => {
|
|
21817
|
+
const options = actionCommand.optsWithGlobals();
|
|
21818
|
+
const branchContext = commandBranchContexts.get(actionCommand);
|
|
21819
|
+
if (options.branchId && branchContext === void 0) {
|
|
21820
|
+
throw new CliError(
|
|
21821
|
+
`Command "${actionCommand.name()}" does not support --branch-id.`
|
|
21822
|
+
);
|
|
21823
|
+
}
|
|
21824
|
+
if (!options.branchId && branchContext === "required") {
|
|
21825
|
+
throw new CliError("--branch-id is required for this command.");
|
|
21826
|
+
}
|
|
21827
|
+
});
|
|
19590
21828
|
program2.action(async function() {
|
|
19591
21829
|
const options = this.optsWithGlobals();
|
|
19592
21830
|
if (options.update) {
|
|
@@ -19631,6 +21869,88 @@ ${formatExamples("Examples", [
|
|
|
19631
21869
|
);
|
|
19632
21870
|
});
|
|
19633
21871
|
program2.addCommand(orgCommand);
|
|
21872
|
+
const pathwayRegressionCommand = configureCommandPresentation(
|
|
21873
|
+
new Command2("pathway-regression").description(
|
|
21874
|
+
"Preview, start, and inspect pathway regression runs."
|
|
21875
|
+
)
|
|
21876
|
+
).helpGroup("Workspace:").addHelpText(
|
|
21877
|
+
"after",
|
|
21878
|
+
`
|
|
21879
|
+
${formatExamples("Examples", [
|
|
21880
|
+
"mgcl pathway-regression preview --automation-version-id <id> --agent-version-id <id>",
|
|
21881
|
+
"mgcl pathway-regression run --automation-version-id <id> --agent-version-id <id>",
|
|
21882
|
+
"mgcl pathway-regression results --regression-run-id <id>",
|
|
21883
|
+
"mgcl pathway-regression check-results --regression-replay-iteration-id <id>"
|
|
21884
|
+
])}`
|
|
21885
|
+
);
|
|
21886
|
+
const addPathwayRegressionAgentVersionOptions = (command) => command.addOption(
|
|
21887
|
+
new Option2(
|
|
21888
|
+
"--org <org>",
|
|
21889
|
+
"Organization ID or exact organization name to use."
|
|
21890
|
+
).helpGroup("Shared options:")
|
|
21891
|
+
).addOption(
|
|
21892
|
+
new Option2(
|
|
21893
|
+
"--automation-version-id <id>",
|
|
21894
|
+
"Automation version to test against."
|
|
21895
|
+
).helpGroup("Pathway regression options:").makeOptionMandatory(true)
|
|
21896
|
+
).addOption(
|
|
21897
|
+
new Option2("--agent-version-id <id>", "Agent version to test.").helpGroup("Pathway regression options:").makeOptionMandatory(true)
|
|
21898
|
+
);
|
|
21899
|
+
const addPathwayRegressionPreviewOptions = (command) => addPathwayRegressionAgentVersionOptions(command).addOption(
|
|
21900
|
+
new Option2(
|
|
21901
|
+
"--runs-per-path <count>",
|
|
21902
|
+
"Number of historical runs to use per pathway. Defaults to the service value."
|
|
21903
|
+
).helpGroup("Pathway regression options:").argParser(parsePositiveIntegerOption)
|
|
21904
|
+
);
|
|
21905
|
+
addPathwayRegressionPreviewOptions(
|
|
21906
|
+
pathwayRegressionCommand.command("preview").description("Show which historical runs are available per pathway.")
|
|
21907
|
+
).action(async function() {
|
|
21908
|
+
await handlePathwayRegressionPreviewCommand(
|
|
21909
|
+
dependencies,
|
|
21910
|
+
this.optsWithGlobals()
|
|
21911
|
+
);
|
|
21912
|
+
});
|
|
21913
|
+
addPathwayRegressionAgentVersionOptions(
|
|
21914
|
+
pathwayRegressionCommand.command("run").description("Start regression replay for an agent version.")
|
|
21915
|
+
).action(async function() {
|
|
21916
|
+
await handlePathwayRegressionRunCommand(
|
|
21917
|
+
dependencies,
|
|
21918
|
+
this.optsWithGlobals()
|
|
21919
|
+
);
|
|
21920
|
+
});
|
|
21921
|
+
pathwayRegressionCommand.command("results").description("Read a pathway regression run result.").addOption(
|
|
21922
|
+
new Option2(
|
|
21923
|
+
"--org <org>",
|
|
21924
|
+
"Organization ID or exact organization name to use."
|
|
21925
|
+
).helpGroup("Shared options:")
|
|
21926
|
+
).addOption(
|
|
21927
|
+
new Option2(
|
|
21928
|
+
"--regression-run-id <id>",
|
|
21929
|
+
"Pathway regression run ID to inspect."
|
|
21930
|
+
).helpGroup("Pathway regression options:").makeOptionMandatory(true)
|
|
21931
|
+
).action(async function() {
|
|
21932
|
+
await handlePathwayRegressionResultsCommand(
|
|
21933
|
+
dependencies,
|
|
21934
|
+
this.optsWithGlobals()
|
|
21935
|
+
);
|
|
21936
|
+
});
|
|
21937
|
+
pathwayRegressionCommand.command("check-results").description("Read detailed check attempts for one replay iteration.").addOption(
|
|
21938
|
+
new Option2(
|
|
21939
|
+
"--org <org>",
|
|
21940
|
+
"Organization ID or exact organization name to use."
|
|
21941
|
+
).helpGroup("Shared options:")
|
|
21942
|
+
).addOption(
|
|
21943
|
+
new Option2(
|
|
21944
|
+
"--regression-replay-iteration-id <id>",
|
|
21945
|
+
"Pathway regression replay iteration ID to inspect."
|
|
21946
|
+
).helpGroup("Pathway regression options:").makeOptionMandatory(true)
|
|
21947
|
+
).action(async function() {
|
|
21948
|
+
await handlePathwayRegressionCheckResultsCommand(
|
|
21949
|
+
dependencies,
|
|
21950
|
+
this.optsWithGlobals()
|
|
21951
|
+
);
|
|
21952
|
+
});
|
|
21953
|
+
program2.addCommand(pathwayRegressionCommand);
|
|
19634
21954
|
const nangoCommand = configureCommandPresentation(
|
|
19635
21955
|
new Command2("nango").description(
|
|
19636
21956
|
"Inspect Nango integrations and org-scoped authentications."
|