@getmagical/cli 0.3.2 → 0.6.0
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 +30 -4
- package/dist/index.js +1183 -91
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6954,6 +6954,130 @@ function renderKeyValueBlock(entries) {
|
|
|
6954
6954
|
function renderSection(title, bodyLines) {
|
|
6955
6955
|
return [formatHeading(title), "", ...bodyLines].join("\n");
|
|
6956
6956
|
}
|
|
6957
|
+
function getRecordArray(value) {
|
|
6958
|
+
return Array.isArray(value) && value.every(isRecord) ? value : null;
|
|
6959
|
+
}
|
|
6960
|
+
function getRecordScalar(record, key) {
|
|
6961
|
+
const value = record[key];
|
|
6962
|
+
return isPrimitiveLike(value) ? formatScalar(value) : EMPTY_VALUE;
|
|
6963
|
+
}
|
|
6964
|
+
function getMergeChangeExplanation(change) {
|
|
6965
|
+
const explanation = change["statusDescription"] ?? change["conflictDescription"];
|
|
6966
|
+
return typeof explanation === "string" ? formatScalar(explanation) : EMPTY_VALUE;
|
|
6967
|
+
}
|
|
6968
|
+
function formatMergeChanges(changes, includeStatus) {
|
|
6969
|
+
return formatTable({
|
|
6970
|
+
columns: includeStatus ? ["Change", "Status", "Discardable", "Explanation", "Change ID"] : ["Change", "Explanation", "Change ID"],
|
|
6971
|
+
rows: changes.map((change) => {
|
|
6972
|
+
const cells = [getRecordScalar(change, "label")];
|
|
6973
|
+
if (includeStatus) {
|
|
6974
|
+
cells.push(
|
|
6975
|
+
getRecordScalar(change, "status"),
|
|
6976
|
+
change["discardable"] === true ? "yes" : "no"
|
|
6977
|
+
);
|
|
6978
|
+
}
|
|
6979
|
+
cells.push(
|
|
6980
|
+
getMergeChangeExplanation(change),
|
|
6981
|
+
getRecordScalar(change, "id")
|
|
6982
|
+
);
|
|
6983
|
+
return cells;
|
|
6984
|
+
})
|
|
6985
|
+
});
|
|
6986
|
+
}
|
|
6987
|
+
function renderMergePreviewSection(title, preview, changes) {
|
|
6988
|
+
return renderSection(title, [
|
|
6989
|
+
renderKeyValueBlock([
|
|
6990
|
+
["Base version", getRecordScalar(preview, "baseVersionId")],
|
|
6991
|
+
["Source version", getRecordScalar(preview, "sourceVersionId")],
|
|
6992
|
+
["Target version", getRecordScalar(preview, "targetVersionId")]
|
|
6993
|
+
]),
|
|
6994
|
+
"",
|
|
6995
|
+
changes.length > 0 ? formatMergeChanges(changes, true) : "No changes to merge."
|
|
6996
|
+
]);
|
|
6997
|
+
}
|
|
6998
|
+
function renderDiscardHint(preview, changes) {
|
|
6999
|
+
const hasDiscardable = changes.some(
|
|
7000
|
+
(change) => change["discardable"] === true
|
|
7001
|
+
);
|
|
7002
|
+
if (!hasDiscardable) {
|
|
7003
|
+
return null;
|
|
7004
|
+
}
|
|
7005
|
+
return renderSection("Resolve conflicts", [
|
|
7006
|
+
"Discards revert a change on the branch so main keeps its value; conflicts must be discarded or edited to match main before merging.",
|
|
7007
|
+
formatCommandSnippet(
|
|
7008
|
+
`mgcl --branch-id <branch-id> automations branches discard-changes --automation-id <automation-id> --change-ids <change-id,...> --source-version-id ${getRecordScalar(preview, "sourceVersionId")} --target-version-id ${getRecordScalar(preview, "targetVersionId")}`
|
|
7009
|
+
)
|
|
7010
|
+
]);
|
|
7011
|
+
}
|
|
7012
|
+
function formatAutomationBranchMergePreviewOutput(value) {
|
|
7013
|
+
const changes = isRecord(value) ? getRecordArray(value["changes"]) : null;
|
|
7014
|
+
if (!isRecord(value) || !changes) {
|
|
7015
|
+
return formatHumanReadableOutput(value);
|
|
7016
|
+
}
|
|
7017
|
+
const hint = renderDiscardHint(value, changes);
|
|
7018
|
+
return [
|
|
7019
|
+
renderMergePreviewSection("Merge Preview", value, changes),
|
|
7020
|
+
...hint ? [hint] : []
|
|
7021
|
+
].join("\n\n");
|
|
7022
|
+
}
|
|
7023
|
+
function formatAutomationBranchDiscardOutput(value) {
|
|
7024
|
+
const preview = isRecord(value) ? value["preview"] : null;
|
|
7025
|
+
const changes = isRecord(preview) ? getRecordArray(preview["changes"]) : null;
|
|
7026
|
+
if (!isRecord(value) || !isRecord(preview) || !changes) {
|
|
7027
|
+
return formatHumanReadableOutput(value);
|
|
7028
|
+
}
|
|
7029
|
+
const discardedChangeIds = Array.isArray(value["discardedChangeIds"]) ? value["discardedChangeIds"].map(formatScalar).join(", ") : EMPTY_VALUE;
|
|
7030
|
+
return [
|
|
7031
|
+
renderSection("Branch Discard", [
|
|
7032
|
+
renderKeyValueBlock([
|
|
7033
|
+
["Branch ID", getRecordScalar(value, "branchId")],
|
|
7034
|
+
["Previous head", getRecordScalar(value, "previousHeadVersionId")],
|
|
7035
|
+
["New head", getRecordScalar(value, "headVersionId")],
|
|
7036
|
+
["Discarded changes", discardedChangeIds]
|
|
7037
|
+
])
|
|
7038
|
+
]),
|
|
7039
|
+
renderMergePreviewSection("Refreshed Merge Preview", preview, changes)
|
|
7040
|
+
].join("\n\n");
|
|
7041
|
+
}
|
|
7042
|
+
function formatAutomationBranchMergeOutput(value) {
|
|
7043
|
+
if (!isRecord(value) || value["status"] !== "conflict") {
|
|
7044
|
+
return formatHumanReadableOutput(value);
|
|
7045
|
+
}
|
|
7046
|
+
const { preview } = value;
|
|
7047
|
+
const conflicts = getRecordArray(value["conflicts"]);
|
|
7048
|
+
if (!isRecord(preview) || !conflicts || conflicts.length === 0) {
|
|
7049
|
+
return formatHumanReadableOutput(value);
|
|
7050
|
+
}
|
|
7051
|
+
const changes = getRecordArray(preview["changes"]);
|
|
7052
|
+
if (!changes) {
|
|
7053
|
+
return formatHumanReadableOutput(value);
|
|
7054
|
+
}
|
|
7055
|
+
const hint = renderDiscardHint(preview, changes);
|
|
7056
|
+
return [
|
|
7057
|
+
renderSection("Branch Merge", [
|
|
7058
|
+
renderKeyValueBlock([
|
|
7059
|
+
["Status", getRecordScalar(value, "status")],
|
|
7060
|
+
["Automation ID", getRecordScalar(value, "automationId")],
|
|
7061
|
+
["Branch ID", getRecordScalar(value, "branchId")],
|
|
7062
|
+
[
|
|
7063
|
+
"Source branch deleted",
|
|
7064
|
+
getRecordScalar(value, "sourceBranchDeleted")
|
|
7065
|
+
]
|
|
7066
|
+
])
|
|
7067
|
+
]),
|
|
7068
|
+
renderSection("Merge Conflicts", [formatMergeChanges(conflicts, false)]),
|
|
7069
|
+
renderMergePreviewSection("Merge Preview", preview, changes),
|
|
7070
|
+
...hint ? [hint] : []
|
|
7071
|
+
].join("\n\n");
|
|
7072
|
+
}
|
|
7073
|
+
var BRANCH_MERGE_FORMATTERS = /* @__PURE__ */ new Map([
|
|
7074
|
+
["DiscardAutomationBranchChanges", formatAutomationBranchDiscardOutput],
|
|
7075
|
+
["MergeAutomationBranch", formatAutomationBranchMergeOutput],
|
|
7076
|
+
["PreviewAutomationBranchMerge", formatAutomationBranchMergePreviewOutput]
|
|
7077
|
+
]);
|
|
7078
|
+
function getBranchMergeFormatter(operationName) {
|
|
7079
|
+
return BRANCH_MERGE_FORMATTERS.get(operationName);
|
|
7080
|
+
}
|
|
6957
7081
|
var MagicalHelp = class extends Help {
|
|
6958
7082
|
outputHasColors = process.stdout.isTTY;
|
|
6959
7083
|
constructor() {
|
|
@@ -7073,12 +7197,14 @@ function formatOutputModesNote() {
|
|
|
7073
7197
|
|
|
7074
7198
|
// src/errors.ts
|
|
7075
7199
|
var CliError = class extends Error {
|
|
7200
|
+
apiErrorCode;
|
|
7076
7201
|
retryAfterMs;
|
|
7077
7202
|
retryable;
|
|
7078
7203
|
statusCode;
|
|
7079
7204
|
constructor(message, options) {
|
|
7080
7205
|
super(message, options);
|
|
7081
7206
|
this.name = "CliError";
|
|
7207
|
+
this.apiErrorCode = options?.apiErrorCode;
|
|
7082
7208
|
this.retryAfterMs = options?.retryAfterMs;
|
|
7083
7209
|
this.retryable = options?.retryable;
|
|
7084
7210
|
this.statusCode = options?.statusCode;
|
|
@@ -7095,7 +7221,7 @@ function getErrorMessage(error) {
|
|
|
7095
7221
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
7096
7222
|
import { readFile as readFile6 } from "node:fs/promises";
|
|
7097
7223
|
import path8 from "node:path";
|
|
7098
|
-
import { setTimeout as
|
|
7224
|
+
import { setTimeout as sleep2 } from "node:timers/promises";
|
|
7099
7225
|
|
|
7100
7226
|
// ../common/dist/src/stdlib/json.util.js
|
|
7101
7227
|
var import_ts_essentials = __toESM(require_dist(), 1);
|
|
@@ -7767,6 +7893,8 @@ function safeJsonParseWithoutLogging(json) {
|
|
|
7767
7893
|
// ../common/dist/src/constants/automation.js
|
|
7768
7894
|
var AUTOMATION_BRANCH_NAME_MAX_LENGTH = 100;
|
|
7769
7895
|
var AUTOMATION_BRANCH_NAME_MAX_LENGTH_MESSAGE = `Branch name must be ${AUTOMATION_BRANCH_NAME_MAX_LENGTH} characters or fewer.`;
|
|
7896
|
+
var AUTOMATION_BRANCH_DISCARD_MAX_CHANGE_IDS = 50;
|
|
7897
|
+
var AUTOMATION_BRANCH_CHANGE_ID_MAX_LENGTH = 256;
|
|
7770
7898
|
|
|
7771
7899
|
// ../common/dist/src/constants/tool-declarations.js
|
|
7772
7900
|
import { z as z15 } from "zod";
|
|
@@ -12365,6 +12493,27 @@ var clickComparisonSchema = z9.union([
|
|
|
12365
12493
|
[COMMON_PARAMETERS_KEY]: DEFAULT_COMMON_PARAMETERS
|
|
12366
12494
|
})
|
|
12367
12495
|
]);
|
|
12496
|
+
var holdClickMarkerInputSchema = z9.object({
|
|
12497
|
+
marker: markerSchema("The marker of the element to press and hold.")
|
|
12498
|
+
});
|
|
12499
|
+
var holdClickCoordinateInputSchema = z9.object({
|
|
12500
|
+
coordinates: coordinateSchema({
|
|
12501
|
+
xDescription: "The x coordinate of the element to press and hold.",
|
|
12502
|
+
yDescription: "The y coordinate of the element to press and hold."
|
|
12503
|
+
})
|
|
12504
|
+
});
|
|
12505
|
+
var holdClickComparisonSchema = z9.union([
|
|
12506
|
+
holdClickMarkerInputSchema.extend({
|
|
12507
|
+
[COMMON_PARAMETERS_KEY]: DEFAULT_COMMON_PARAMETERS
|
|
12508
|
+
}),
|
|
12509
|
+
holdClickCoordinateInputSchema.extend({
|
|
12510
|
+
[COMMON_PARAMETERS_KEY]: DEFAULT_COMMON_PARAMETERS
|
|
12511
|
+
})
|
|
12512
|
+
]);
|
|
12513
|
+
var releaseClickInputSchema = z9.object({});
|
|
12514
|
+
var releaseClickComparisonSchema = releaseClickInputSchema.extend({
|
|
12515
|
+
[COMMON_PARAMETERS_KEY]: DEFAULT_COMMON_PARAMETERS
|
|
12516
|
+
});
|
|
12368
12517
|
var moveMarkerInputSchema = z9.object({
|
|
12369
12518
|
marker: markerSchema("The marker to move the mouse to")
|
|
12370
12519
|
});
|
|
@@ -12735,7 +12884,8 @@ var PressEvent;
|
|
|
12735
12884
|
Response2.create = create;
|
|
12736
12885
|
})(Response = PressEvent2.Response || (PressEvent2.Response = {}));
|
|
12737
12886
|
})(PressEvent || (PressEvent = {}));
|
|
12738
|
-
var
|
|
12887
|
+
var ModifierKeys = ["Alt", "Control", "Meta", "Shift"];
|
|
12888
|
+
var PhysicalKeys = [
|
|
12739
12889
|
// Modifiers
|
|
12740
12890
|
"Alt",
|
|
12741
12891
|
"CapsLock",
|
|
@@ -12837,16 +12987,16 @@ var Keys = [
|
|
|
12837
12987
|
"y",
|
|
12838
12988
|
"Z",
|
|
12839
12989
|
"z",
|
|
12840
|
-
"
|
|
12841
|
-
"
|
|
12842
|
-
"
|
|
12843
|
-
"
|
|
12844
|
-
"
|
|
12845
|
-
"
|
|
12846
|
-
"
|
|
12847
|
-
"
|
|
12848
|
-
"
|
|
12849
|
-
"
|
|
12990
|
+
"Digit0",
|
|
12991
|
+
"Digit1",
|
|
12992
|
+
"Digit2",
|
|
12993
|
+
"Digit3",
|
|
12994
|
+
"Digit4",
|
|
12995
|
+
"Digit5",
|
|
12996
|
+
"Digit6",
|
|
12997
|
+
"Digit7",
|
|
12998
|
+
"Digit8",
|
|
12999
|
+
"Digit9",
|
|
12850
13000
|
// Punctuation
|
|
12851
13001
|
"Minus",
|
|
12852
13002
|
"Equal",
|
|
@@ -12863,8 +13013,106 @@ var Keys = [
|
|
|
12863
13013
|
"Insert",
|
|
12864
13014
|
"PrintScreen"
|
|
12865
13015
|
];
|
|
13016
|
+
var KeyAliases = [
|
|
13017
|
+
"0",
|
|
13018
|
+
"1",
|
|
13019
|
+
"2",
|
|
13020
|
+
"3",
|
|
13021
|
+
"4",
|
|
13022
|
+
"5",
|
|
13023
|
+
"6",
|
|
13024
|
+
"7",
|
|
13025
|
+
"8",
|
|
13026
|
+
"9",
|
|
13027
|
+
"`",
|
|
13028
|
+
"~",
|
|
13029
|
+
"-",
|
|
13030
|
+
"_",
|
|
13031
|
+
"=",
|
|
13032
|
+
"+",
|
|
13033
|
+
"[",
|
|
13034
|
+
"{",
|
|
13035
|
+
"]",
|
|
13036
|
+
"}",
|
|
13037
|
+
"\\",
|
|
13038
|
+
"|",
|
|
13039
|
+
";",
|
|
13040
|
+
":",
|
|
13041
|
+
"'",
|
|
13042
|
+
'"',
|
|
13043
|
+
",",
|
|
13044
|
+
"<",
|
|
13045
|
+
".",
|
|
13046
|
+
">",
|
|
13047
|
+
"/",
|
|
13048
|
+
"?",
|
|
13049
|
+
"!",
|
|
13050
|
+
"@",
|
|
13051
|
+
"#",
|
|
13052
|
+
"$",
|
|
13053
|
+
"%",
|
|
13054
|
+
"^",
|
|
13055
|
+
"&",
|
|
13056
|
+
"*",
|
|
13057
|
+
"(",
|
|
13058
|
+
")"
|
|
13059
|
+
];
|
|
13060
|
+
var Keys = [...PhysicalKeys, ...KeyAliases];
|
|
13061
|
+
var KeyAliasMappings = [
|
|
13062
|
+
["0", ["Digit0"]],
|
|
13063
|
+
["1", ["Digit1"]],
|
|
13064
|
+
["2", ["Digit2"]],
|
|
13065
|
+
["3", ["Digit3"]],
|
|
13066
|
+
["4", ["Digit4"]],
|
|
13067
|
+
["5", ["Digit5"]],
|
|
13068
|
+
["6", ["Digit6"]],
|
|
13069
|
+
["7", ["Digit7"]],
|
|
13070
|
+
["8", ["Digit8"]],
|
|
13071
|
+
["9", ["Digit9"]],
|
|
13072
|
+
["`", ["Backquote"]],
|
|
13073
|
+
["~", ["Shift", "Backquote"]],
|
|
13074
|
+
["-", ["Minus"]],
|
|
13075
|
+
["_", ["Shift", "Minus"]],
|
|
13076
|
+
["=", ["Equal"]],
|
|
13077
|
+
["+", ["Shift", "Equal"]],
|
|
13078
|
+
["[", ["BracketLeft"]],
|
|
13079
|
+
["{", ["Shift", "BracketLeft"]],
|
|
13080
|
+
["]", ["BracketRight"]],
|
|
13081
|
+
["}", ["Shift", "BracketRight"]],
|
|
13082
|
+
["\\", ["Backslash"]],
|
|
13083
|
+
["|", ["Shift", "Backslash"]],
|
|
13084
|
+
[";", ["Semicolon"]],
|
|
13085
|
+
[":", ["Shift", "Semicolon"]],
|
|
13086
|
+
["'", ["Quote"]],
|
|
13087
|
+
['"', ["Shift", "Quote"]],
|
|
13088
|
+
[",", ["Comma"]],
|
|
13089
|
+
["<", ["Shift", "Comma"]],
|
|
13090
|
+
[".", ["Period"]],
|
|
13091
|
+
[">", ["Shift", "Period"]],
|
|
13092
|
+
["/", ["Slash"]],
|
|
13093
|
+
["?", ["Shift", "Slash"]],
|
|
13094
|
+
["!", ["Shift", "Digit1"]],
|
|
13095
|
+
["@", ["Shift", "Digit2"]],
|
|
13096
|
+
["#", ["Shift", "Digit3"]],
|
|
13097
|
+
["$", ["Shift", "Digit4"]],
|
|
13098
|
+
["%", ["Shift", "Digit5"]],
|
|
13099
|
+
["^", ["Shift", "Digit6"]],
|
|
13100
|
+
["&", ["Shift", "Digit7"]],
|
|
13101
|
+
["*", ["Shift", "Digit8"]],
|
|
13102
|
+
["(", ["Shift", "Digit9"]],
|
|
13103
|
+
[")", ["Shift", "Digit0"]]
|
|
13104
|
+
];
|
|
13105
|
+
var KeyMappings = [
|
|
13106
|
+
...PhysicalKeys.map((key) => [
|
|
13107
|
+
key,
|
|
13108
|
+
[key]
|
|
13109
|
+
]),
|
|
13110
|
+
...KeyAliasMappings
|
|
13111
|
+
];
|
|
13112
|
+
var KeyMapping = new Map(KeyMappings);
|
|
13113
|
+
var ModifierKeySet = new Set(ModifierKeys);
|
|
12866
13114
|
var pressDataSchema = z12.object({
|
|
12867
|
-
keys: z12.array(z12.enum(Keys))
|
|
13115
|
+
keys: z12.array(z12.enum(Keys)).describe("Keys in one simultaneous keyboard chord. Use type for a sequence of characters. US keyboard characters and physical key codes such as Digit4 are supported.")
|
|
12868
13116
|
});
|
|
12869
13117
|
|
|
12870
13118
|
// ../common/dist/src/models/websocket/actions/report-stop.js
|
|
@@ -13190,6 +13438,16 @@ var baseToolDeclarations = {
|
|
|
13190
13438
|
description: 'ONLY USE FOR CLICKING WITHOUT ENTERING TEXT. This tool clicks on an element but DOES NOT allow entering text. Use for buttons, links, checkboxes, dropdown toggles, tabs, and other clickable elements. NEVER use this when you need to enter text into a field - for text entry, use "clickFill" instead, this tool automatically moves the cursor to the element, no need to use the move tool first.',
|
|
13191
13439
|
parameters: clickComparisonSchema
|
|
13192
13440
|
},
|
|
13441
|
+
holdClick: {
|
|
13442
|
+
id: "holdClick",
|
|
13443
|
+
description: "Press and hold the left mouse button on an element that reveals content only while pressed. The hold remains active during non-browser work and is released automatically before the next browser interaction.",
|
|
13444
|
+
parameters: holdClickComparisonSchema
|
|
13445
|
+
},
|
|
13446
|
+
releaseClick: {
|
|
13447
|
+
id: "releaseClick",
|
|
13448
|
+
description: "Release the left mouse button after holdClick. This is safe to call again when the mouse is already released.",
|
|
13449
|
+
parameters: releaseClickComparisonSchema
|
|
13450
|
+
},
|
|
13193
13451
|
multiClick: {
|
|
13194
13452
|
id: "multiClick",
|
|
13195
13453
|
description: "This object is deprecated, only adding here to satisfy the DB type check",
|
|
@@ -13798,12 +14056,109 @@ var apiAgentEmbeddedFilesSchema = z16.array(apiAgentEmbeddedFileSchema).superRef
|
|
|
13798
14056
|
// ../common/dist/src/zod-schemas/api-agent-request-file-encoding.schema.js
|
|
13799
14057
|
import { z as z17 } from "zod";
|
|
13800
14058
|
var API_REQUEST_FILE_PATH_PATTERN = /^[A-Za-z_$][\w$-]*(?:\.[A-Za-z_$][\w$-]*)*$/u;
|
|
14059
|
+
var API_REQUEST_BASE64_FILE_HELPER_PATTERN = /^\s*\{\{\s*base64File\s+(?<sourceInput>[^{}\s]+)\s*\}\}\s*$/u;
|
|
14060
|
+
var API_REQUEST_BASE64_FILE_HELPER_USAGE_PATTERN = /\{\{\s*base64File\b/u;
|
|
14061
|
+
var API_REQUEST_BASE64_FILE_HELPER_EXAMPLE = "{{base64File fileInput}}";
|
|
13801
14062
|
function parseApiRequestFilePath(path9) {
|
|
13802
14063
|
if (!API_REQUEST_FILE_PATH_PATTERN.test(path9)) {
|
|
13803
14064
|
return void 0;
|
|
13804
14065
|
}
|
|
13805
14066
|
return path9.split(".");
|
|
13806
14067
|
}
|
|
14068
|
+
function inspectApiRequestBase64FileHelperValue({ path: path9, value }) {
|
|
14069
|
+
const match = API_REQUEST_BASE64_FILE_HELPER_PATTERN.exec(value);
|
|
14070
|
+
if (match === null) {
|
|
14071
|
+
return API_REQUEST_BASE64_FILE_HELPER_USAGE_PATTERN.test(value) ? {
|
|
14072
|
+
helpers: [],
|
|
14073
|
+
issues: [
|
|
14074
|
+
{
|
|
14075
|
+
message: `Use ${API_REQUEST_BASE64_FILE_HELPER_EXAMPLE} as the entire JSON field value.`,
|
|
14076
|
+
path: path9
|
|
14077
|
+
}
|
|
14078
|
+
]
|
|
14079
|
+
} : { helpers: [], issues: [] };
|
|
14080
|
+
}
|
|
14081
|
+
const { sourceInput } = match.groups ?? {};
|
|
14082
|
+
if (sourceInput === void 0 || parseApiRequestFilePath(sourceInput) === void 0) {
|
|
14083
|
+
return {
|
|
14084
|
+
helpers: [],
|
|
14085
|
+
issues: [
|
|
14086
|
+
{
|
|
14087
|
+
message: "Base64 file helper input must use an object property path.",
|
|
14088
|
+
path: path9
|
|
14089
|
+
}
|
|
14090
|
+
]
|
|
14091
|
+
};
|
|
14092
|
+
}
|
|
14093
|
+
return {
|
|
14094
|
+
helpers: [{ destinationPath: path9, sourceInput }],
|
|
14095
|
+
issues: []
|
|
14096
|
+
};
|
|
14097
|
+
}
|
|
14098
|
+
function inspectApiRequestBase64FileHelpers(body, path9 = []) {
|
|
14099
|
+
if (typeof body === "string") {
|
|
14100
|
+
return inspectApiRequestBase64FileHelperValue({ path: path9, value: body });
|
|
14101
|
+
}
|
|
14102
|
+
if (Array.isArray(body)) {
|
|
14103
|
+
return body.reduce((inspection, value, index) => {
|
|
14104
|
+
const nestedInspection = inspectApiRequestBase64FileHelpers(value, [
|
|
14105
|
+
...path9,
|
|
14106
|
+
index
|
|
14107
|
+
]);
|
|
14108
|
+
return {
|
|
14109
|
+
helpers: [...inspection.helpers, ...nestedInspection.helpers],
|
|
14110
|
+
issues: [...inspection.issues, ...nestedInspection.issues]
|
|
14111
|
+
};
|
|
14112
|
+
}, { helpers: [], issues: [] });
|
|
14113
|
+
}
|
|
14114
|
+
if (body === null || typeof body !== "object") {
|
|
14115
|
+
return { helpers: [], issues: [] };
|
|
14116
|
+
}
|
|
14117
|
+
return Object.entries(body).reduce((inspection, [key, value]) => {
|
|
14118
|
+
const nestedInspection = inspectApiRequestBase64FileHelpers(value, [
|
|
14119
|
+
...path9,
|
|
14120
|
+
key
|
|
14121
|
+
]);
|
|
14122
|
+
return {
|
|
14123
|
+
helpers: [...inspection.helpers, ...nestedInspection.helpers],
|
|
14124
|
+
issues: [...inspection.issues, ...nestedInspection.issues]
|
|
14125
|
+
};
|
|
14126
|
+
}, { helpers: [], issues: [] });
|
|
14127
|
+
}
|
|
14128
|
+
function validateApiRequestBase64FileHelpers({ body, bodyType, context, supportsRequestBody }) {
|
|
14129
|
+
const inspection = inspectApiRequestBase64FileHelpers(body);
|
|
14130
|
+
for (const issue of inspection.issues) {
|
|
14131
|
+
context.addIssue({
|
|
14132
|
+
code: z17.ZodIssueCode.custom,
|
|
14133
|
+
message: issue.message,
|
|
14134
|
+
path: ["body", ...issue.path]
|
|
14135
|
+
});
|
|
14136
|
+
}
|
|
14137
|
+
if (inspection.helpers.length === 0) {
|
|
14138
|
+
return;
|
|
14139
|
+
}
|
|
14140
|
+
if (!supportsRequestBody) {
|
|
14141
|
+
context.addIssue({
|
|
14142
|
+
code: z17.ZodIssueCode.custom,
|
|
14143
|
+
message: "Base64 file helpers are not supported for this method",
|
|
14144
|
+
path: ["body"]
|
|
14145
|
+
});
|
|
14146
|
+
}
|
|
14147
|
+
if ((bodyType ?? "json") !== "json") {
|
|
14148
|
+
context.addIssue({
|
|
14149
|
+
code: z17.ZodIssueCode.custom,
|
|
14150
|
+
message: "Base64 file helpers are only supported for JSON bodies",
|
|
14151
|
+
path: ["body"]
|
|
14152
|
+
});
|
|
14153
|
+
}
|
|
14154
|
+
if (body === null || typeof body !== "object" || Array.isArray(body)) {
|
|
14155
|
+
context.addIssue({
|
|
14156
|
+
code: z17.ZodIssueCode.custom,
|
|
14157
|
+
message: "Base64 file helpers require a JSON object body",
|
|
14158
|
+
path: ["body"]
|
|
14159
|
+
});
|
|
14160
|
+
}
|
|
14161
|
+
}
|
|
13807
14162
|
var apiAgentRequestFileEncodingSchema = z17.object({
|
|
13808
14163
|
sourceInput: z17.string().trim().min(1, "File input is required.").refine((path9) => parseApiRequestFilePath(path9) !== void 0, {
|
|
13809
14164
|
message: "File input must use an object property path."
|
|
@@ -13978,6 +14333,13 @@ var apiToolSchema = z20.object({
|
|
|
13978
14333
|
}).refine((data) => !data.requestFileEncodings?.length || data.body !== null && typeof data.body === "object" && !Array.isArray(data.body), {
|
|
13979
14334
|
message: "Request file encoding requires a JSON object body",
|
|
13980
14335
|
path: ["body"]
|
|
14336
|
+
}).superRefine((data, context) => {
|
|
14337
|
+
validateApiRequestBase64FileHelpers({
|
|
14338
|
+
body: data.body,
|
|
14339
|
+
bodyType: data.bodyType,
|
|
14340
|
+
context,
|
|
14341
|
+
supportsRequestBody: methodsWithBody.has(data.type)
|
|
14342
|
+
});
|
|
13981
14343
|
}).refine((data) => isValidApiMultipartFormDataBody({
|
|
13982
14344
|
bodyType: data.bodyType,
|
|
13983
14345
|
body: data.body
|
|
@@ -14385,6 +14747,13 @@ var apiAgentConfigSchema = baseAgentConfigFieldsSchema.safeExtend({
|
|
|
14385
14747
|
}).refine((data) => !data.requestFileEncodings?.length || data.body !== null && typeof data.body === "object" && !Array.isArray(data.body), {
|
|
14386
14748
|
message: "Request file encoding requires a JSON object body",
|
|
14387
14749
|
path: ["body"]
|
|
14750
|
+
}).superRefine((data, context) => {
|
|
14751
|
+
validateApiRequestBase64FileHelpers({
|
|
14752
|
+
body: data.body,
|
|
14753
|
+
bodyType: data.bodyType,
|
|
14754
|
+
context,
|
|
14755
|
+
supportsRequestBody: METHODS_WITH_BODY.has(data.method)
|
|
14756
|
+
});
|
|
14388
14757
|
}).refine((data) => isValidApiMultipartFormDataBody({
|
|
14389
14758
|
bodyType: data.bodyType,
|
|
14390
14759
|
body: data.body
|
|
@@ -15161,6 +15530,7 @@ ${agentLimitationsSelection}
|
|
|
15161
15530
|
operationName: "GetAgentVersion",
|
|
15162
15531
|
kind: "query",
|
|
15163
15532
|
inputSchema: z27.object({
|
|
15533
|
+
draftAutomationId: z27.string().min(1),
|
|
15164
15534
|
agentId: z27.string().min(1),
|
|
15165
15535
|
versionId: z27.string().min(1)
|
|
15166
15536
|
}),
|
|
@@ -15170,6 +15540,12 @@ ${agentLimitationsSelection}
|
|
|
15170
15540
|
description: "Fetch one saved version for an agent.",
|
|
15171
15541
|
resultKey: "agentVersion",
|
|
15172
15542
|
options: [
|
|
15543
|
+
stringOption({
|
|
15544
|
+
inputKey: "draftAutomationId",
|
|
15545
|
+
flagName: "automation-id",
|
|
15546
|
+
description: "Automation ID whose main draft lineage scopes the agent's history.",
|
|
15547
|
+
required: true
|
|
15548
|
+
}),
|
|
15173
15549
|
stringOption({
|
|
15174
15550
|
inputKey: "agentId",
|
|
15175
15551
|
flagName: "agent-id",
|
|
@@ -15186,8 +15562,12 @@ ${agentLimitationsSelection}
|
|
|
15186
15562
|
},
|
|
15187
15563
|
mcp: { fileName: "agentVersion.graphql" },
|
|
15188
15564
|
document: `# Query to fetch a specific saved version for an agent
|
|
15189
|
-
query GetAgentVersion($agentId: ID!, $versionId: ID!) {
|
|
15190
|
-
agentVersion(
|
|
15565
|
+
query GetAgentVersion($draftAutomationId: ID!, $agentId: ID!, $versionId: ID!) {
|
|
15566
|
+
agentVersion(
|
|
15567
|
+
draftAutomationId: $draftAutomationId
|
|
15568
|
+
agentId: $agentId
|
|
15569
|
+
versionId: $versionId
|
|
15570
|
+
) {
|
|
15191
15571
|
id
|
|
15192
15572
|
agentId
|
|
15193
15573
|
sequence
|
|
@@ -15227,6 +15607,7 @@ ${agentLimitationsSelection}
|
|
|
15227
15607
|
operationName: "GetAgentVersions",
|
|
15228
15608
|
kind: "query",
|
|
15229
15609
|
inputSchema: z27.object({
|
|
15610
|
+
draftAutomationId: z27.string().min(1),
|
|
15230
15611
|
agentId: z27.string().min(1)
|
|
15231
15612
|
}),
|
|
15232
15613
|
cli: {
|
|
@@ -15235,6 +15616,12 @@ ${agentLimitationsSelection}
|
|
|
15235
15616
|
description: "Fetch version history for an agent.",
|
|
15236
15617
|
resultKey: "agentVersions",
|
|
15237
15618
|
options: [
|
|
15619
|
+
stringOption({
|
|
15620
|
+
inputKey: "draftAutomationId",
|
|
15621
|
+
flagName: "automation-id",
|
|
15622
|
+
description: "Automation ID whose main draft lineage scopes the agent's history.",
|
|
15623
|
+
required: true
|
|
15624
|
+
}),
|
|
15238
15625
|
stringOption({
|
|
15239
15626
|
inputKey: "agentId",
|
|
15240
15627
|
flagName: "agent-id",
|
|
@@ -15245,8 +15632,8 @@ ${agentLimitationsSelection}
|
|
|
15245
15632
|
},
|
|
15246
15633
|
mcp: { fileName: "agentVersions.graphql" },
|
|
15247
15634
|
document: `# Query to fetch version history metadata for an agent
|
|
15248
|
-
query GetAgentVersions($agentId: ID!) {
|
|
15249
|
-
agentVersions(agentId: $agentId) {
|
|
15635
|
+
query GetAgentVersions($draftAutomationId: ID!, $agentId: ID!) {
|
|
15636
|
+
agentVersions(draftAutomationId: $draftAutomationId, agentId: $agentId) {
|
|
15250
15637
|
id
|
|
15251
15638
|
sequence
|
|
15252
15639
|
name
|
|
@@ -15262,6 +15649,7 @@ query GetAgentVersions($agentId: ID!) {
|
|
|
15262
15649
|
operationName: "DiffAgentVersion",
|
|
15263
15650
|
kind: "query",
|
|
15264
15651
|
inputSchema: z27.object({
|
|
15652
|
+
draftAutomationId: z27.string().min(1),
|
|
15265
15653
|
agentId: z27.string().min(1),
|
|
15266
15654
|
versionId: z27.string().min(1),
|
|
15267
15655
|
compareVersionId: z27.string().min(1).optional()
|
|
@@ -15269,9 +15657,15 @@ query GetAgentVersions($agentId: ID!) {
|
|
|
15269
15657
|
cli: {
|
|
15270
15658
|
name: "diff-agent-version",
|
|
15271
15659
|
path: ["agents", "versions", "diff"],
|
|
15272
|
-
description: "Diff one agent version against another version or the current
|
|
15660
|
+
description: "Diff one agent version against another version or the automation's current draft version.",
|
|
15273
15661
|
resultKey: "agentVersionDiff",
|
|
15274
15662
|
options: [
|
|
15663
|
+
stringOption({
|
|
15664
|
+
inputKey: "draftAutomationId",
|
|
15665
|
+
flagName: "automation-id",
|
|
15666
|
+
description: "Automation ID whose main draft lineage scopes the agent's history.",
|
|
15667
|
+
required: true
|
|
15668
|
+
}),
|
|
15275
15669
|
stringOption({
|
|
15276
15670
|
inputKey: "agentId",
|
|
15277
15671
|
flagName: "agent-id",
|
|
@@ -15287,18 +15681,20 @@ query GetAgentVersions($agentId: ID!) {
|
|
|
15287
15681
|
stringOption({
|
|
15288
15682
|
inputKey: "compareVersionId",
|
|
15289
15683
|
flagName: "compare-version-id",
|
|
15290
|
-
description: "Optional target version ID. Defaults to the current
|
|
15684
|
+
description: "Optional target version ID. Defaults to the automation's current draft version."
|
|
15291
15685
|
})
|
|
15292
15686
|
]
|
|
15293
15687
|
},
|
|
15294
15688
|
mcp: { fileName: "agentVersionDiff.graphql" },
|
|
15295
|
-
document: `# Query to diff one agent version against another or the current
|
|
15689
|
+
document: `# Query to diff one agent version against another or the automation's current draft version
|
|
15296
15690
|
query DiffAgentVersion(
|
|
15691
|
+
$draftAutomationId: ID!
|
|
15297
15692
|
$agentId: ID!
|
|
15298
15693
|
$versionId: ID!
|
|
15299
15694
|
$compareVersionId: ID
|
|
15300
15695
|
) {
|
|
15301
15696
|
agentVersionDiff(
|
|
15697
|
+
draftAutomationId: $draftAutomationId
|
|
15302
15698
|
agentId: $agentId
|
|
15303
15699
|
versionId: $versionId
|
|
15304
15700
|
compareVersionId: $compareVersionId
|
|
@@ -15340,6 +15736,7 @@ query DiffAgentVersion(
|
|
|
15340
15736
|
query GetAgentRun($id: ID!) {
|
|
15341
15737
|
agentRun(id: $id) {
|
|
15342
15738
|
id
|
|
15739
|
+
agentId
|
|
15343
15740
|
agentVersionId
|
|
15344
15741
|
agentName
|
|
15345
15742
|
status
|
|
@@ -15566,12 +15963,15 @@ query GetAutomationRun($id: ID!) {
|
|
|
15566
15963
|
automationRun(id: $id) {
|
|
15567
15964
|
id
|
|
15568
15965
|
automationId
|
|
15966
|
+
automationVersionId
|
|
15569
15967
|
parentAutomationRunId
|
|
15570
15968
|
status
|
|
15571
15969
|
statusDetail
|
|
15572
15970
|
summary
|
|
15573
15971
|
invocationType
|
|
15574
15972
|
input
|
|
15973
|
+
initialStore
|
|
15974
|
+
currentStore
|
|
15575
15975
|
additionalPrompt
|
|
15576
15976
|
debugUrl
|
|
15577
15977
|
createdAt
|
|
@@ -15606,6 +16006,7 @@ query GetAutomationRun($id: ID!) {
|
|
|
15606
16006
|
query GetAutomationRunAgentRuns($automationRunId: ID!) {
|
|
15607
16007
|
automationRunAgentRuns(automationRunId: $automationRunId) {
|
|
15608
16008
|
id
|
|
16009
|
+
agentId
|
|
15609
16010
|
agentVersionId
|
|
15610
16011
|
agentName
|
|
15611
16012
|
status
|
|
@@ -15625,6 +16026,7 @@ query GetAutomationRunAgentRuns($automationRunId: ID!) {
|
|
|
15625
16026
|
automationRunId: z27.string().min(1),
|
|
15626
16027
|
agentRunId: z27.string().min(1).optional(),
|
|
15627
16028
|
limit: z27.number().int().positive().optional(),
|
|
16029
|
+
page: z27.number().int().nonnegative().optional(),
|
|
15628
16030
|
reverse: z27.boolean().optional()
|
|
15629
16031
|
}),
|
|
15630
16032
|
cli: {
|
|
@@ -15649,6 +16051,11 @@ query GetAutomationRunAgentRuns($automationRunId: ID!) {
|
|
|
15649
16051
|
flagName: "limit",
|
|
15650
16052
|
description: "Maximum number of iterations to return."
|
|
15651
16053
|
}),
|
|
16054
|
+
numberOption({
|
|
16055
|
+
inputKey: "page",
|
|
16056
|
+
flagName: "page",
|
|
16057
|
+
description: "Zero-based page number."
|
|
16058
|
+
}),
|
|
15652
16059
|
booleanOption({
|
|
15653
16060
|
inputKey: "reverse",
|
|
15654
16061
|
flagName: "reverse",
|
|
@@ -15662,18 +16069,21 @@ query GetAutomationRunIterations(
|
|
|
15662
16069
|
$automationRunId: ID!
|
|
15663
16070
|
$agentRunId: ID
|
|
15664
16071
|
$limit: Int
|
|
16072
|
+
$page: Int
|
|
15665
16073
|
$reverse: Boolean
|
|
15666
16074
|
) {
|
|
15667
16075
|
automationRunIterations(
|
|
15668
16076
|
automationRunId: $automationRunId
|
|
15669
16077
|
agentRunId: $agentRunId
|
|
15670
16078
|
limit: $limit
|
|
16079
|
+
page: $page
|
|
15671
16080
|
reverse: $reverse
|
|
15672
16081
|
) {
|
|
15673
16082
|
id
|
|
15674
16083
|
sequence
|
|
15675
16084
|
agentRunId
|
|
15676
16085
|
metadata
|
|
16086
|
+
store
|
|
15677
16087
|
startedAt
|
|
15678
16088
|
finishedAt
|
|
15679
16089
|
totalDurationMs
|
|
@@ -15689,6 +16099,42 @@ query GetAutomationRunIterations(
|
|
|
15689
16099
|
screenshotMimeType
|
|
15690
16100
|
}
|
|
15691
16101
|
}
|
|
16102
|
+
}`
|
|
16103
|
+
}),
|
|
16104
|
+
createOperationSpec({
|
|
16105
|
+
operationName: "GetIterationScreenshot",
|
|
16106
|
+
kind: "query",
|
|
16107
|
+
inputSchema: z27.object({
|
|
16108
|
+
iterationId: z27.string().min(1),
|
|
16109
|
+
hasMarks: z27.boolean().default(false)
|
|
16110
|
+
}),
|
|
16111
|
+
cli: {
|
|
16112
|
+
name: "get-iteration-screenshot",
|
|
16113
|
+
path: ["automation-runs", "iteration-screenshot"],
|
|
16114
|
+
description: "Fetch a fresh screenshot URL for an iteration.",
|
|
16115
|
+
resultKey: "iterationScreenshot",
|
|
16116
|
+
options: [
|
|
16117
|
+
stringOption({
|
|
16118
|
+
inputKey: "iterationId",
|
|
16119
|
+
flagName: "iteration-id",
|
|
16120
|
+
description: "Automation run iteration ID.",
|
|
16121
|
+
required: true
|
|
16122
|
+
}),
|
|
16123
|
+
booleanOption({
|
|
16124
|
+
inputKey: "hasMarks",
|
|
16125
|
+
flagName: "with-marks",
|
|
16126
|
+
description: "Fetch the marked screenshot instead of the base screenshot."
|
|
16127
|
+
})
|
|
16128
|
+
]
|
|
16129
|
+
},
|
|
16130
|
+
mcp: { fileName: "iterationScreenshot.graphql" },
|
|
16131
|
+
document: `# Fetch a fresh screenshot URL for an automation run iteration
|
|
16132
|
+
query GetIterationScreenshot($iterationId: ID!, $hasMarks: Boolean = false) {
|
|
16133
|
+
iterationScreenshot(iterationId: $iterationId, hasMarks: $hasMarks) {
|
|
16134
|
+
status
|
|
16135
|
+
url
|
|
16136
|
+
mimeType
|
|
16137
|
+
}
|
|
15692
16138
|
}`
|
|
15693
16139
|
}),
|
|
15694
16140
|
createOperationSpec({
|
|
@@ -15777,6 +16223,7 @@ query GetAutomationRuns(
|
|
|
15777
16223
|
) {
|
|
15778
16224
|
id
|
|
15779
16225
|
automationId
|
|
16226
|
+
automationVersionId
|
|
15780
16227
|
parentAutomationRunId
|
|
15781
16228
|
status
|
|
15782
16229
|
statusDetail
|
|
@@ -15825,6 +16272,7 @@ query GetAutomationRunsPage(
|
|
|
15825
16272
|
items {
|
|
15826
16273
|
id
|
|
15827
16274
|
automationId
|
|
16275
|
+
automationVersionId
|
|
15828
16276
|
parentAutomationRunId
|
|
15829
16277
|
status
|
|
15830
16278
|
statusDetail
|
|
@@ -16123,7 +16571,7 @@ query GetAutomationBranch($automationId: ID!, $branchId: ID!) {
|
|
|
16123
16571
|
branchContext: "required",
|
|
16124
16572
|
name: "merge-automation-branch",
|
|
16125
16573
|
path: ["automations", "branches", "merge"],
|
|
16126
|
-
description: "Preview and merge a branch into main when every change is conflict-free. Exits nonzero when conflicts block the merge.",
|
|
16574
|
+
description: "Preview and merge a branch into main when every change is conflict-free. Exits nonzero when conflicts block the merge; use `automations branches discard-changes` to resolve them.",
|
|
16127
16575
|
resultKey: "mergeAutomationBranch",
|
|
16128
16576
|
options: [
|
|
16129
16577
|
stringOption({
|
|
@@ -16148,16 +16596,36 @@ mutation MergeAutomationBranch($automationId: ID!, $branchId: ID!) {
|
|
|
16148
16596
|
targetVersionId
|
|
16149
16597
|
changes {
|
|
16150
16598
|
id
|
|
16599
|
+
kind
|
|
16151
16600
|
group
|
|
16152
|
-
label
|
|
16153
16601
|
status
|
|
16602
|
+
label
|
|
16603
|
+
discardable
|
|
16604
|
+
agentId
|
|
16605
|
+
agentName
|
|
16606
|
+
field
|
|
16607
|
+
configKey
|
|
16608
|
+
fromAgentId
|
|
16609
|
+
toAgentId
|
|
16610
|
+
conflictDescription
|
|
16611
|
+
statusDescription
|
|
16154
16612
|
}
|
|
16155
16613
|
}
|
|
16156
16614
|
conflicts {
|
|
16157
16615
|
id
|
|
16616
|
+
kind
|
|
16158
16617
|
group
|
|
16159
|
-
label
|
|
16160
16618
|
status
|
|
16619
|
+
label
|
|
16620
|
+
discardable
|
|
16621
|
+
agentId
|
|
16622
|
+
agentName
|
|
16623
|
+
field
|
|
16624
|
+
configKey
|
|
16625
|
+
fromAgentId
|
|
16626
|
+
toAgentId
|
|
16627
|
+
conflictDescription
|
|
16628
|
+
statusDescription
|
|
16161
16629
|
}
|
|
16162
16630
|
applyResult {
|
|
16163
16631
|
draftVersionId
|
|
@@ -16166,6 +16634,150 @@ mutation MergeAutomationBranch($automationId: ID!, $branchId: ID!) {
|
|
|
16166
16634
|
wasRebased
|
|
16167
16635
|
}
|
|
16168
16636
|
}
|
|
16637
|
+
}`
|
|
16638
|
+
}),
|
|
16639
|
+
createOperationSpec({
|
|
16640
|
+
operationName: "PreviewAutomationBranchMerge",
|
|
16641
|
+
kind: "query",
|
|
16642
|
+
inputSchema: z27.object({
|
|
16643
|
+
automationId: z27.uuid("--automation-id must be a UUID."),
|
|
16644
|
+
branchId: z27.uuid("--branch-id must be a UUID.")
|
|
16645
|
+
}),
|
|
16646
|
+
cli: {
|
|
16647
|
+
branchContext: "required",
|
|
16648
|
+
name: "preview-automation-branch-merge",
|
|
16649
|
+
path: ["automations", "branches", "merge-preview"],
|
|
16650
|
+
description: "Explain how a branch would merge into main: one change per agent field with its status and, for conflicts, why it conflicts. Writes nothing.",
|
|
16651
|
+
resultKey: "automationBranchMergePreview",
|
|
16652
|
+
options: [
|
|
16653
|
+
stringOption({
|
|
16654
|
+
inputKey: "automationId",
|
|
16655
|
+
flagName: "automation-id",
|
|
16656
|
+
description: "Automation ID.",
|
|
16657
|
+
required: true
|
|
16658
|
+
})
|
|
16659
|
+
]
|
|
16660
|
+
},
|
|
16661
|
+
mcp: { fileName: "automationBranchMergePreview.graphql" },
|
|
16662
|
+
document: `# Explain how a branch would merge into main without writing anything.
|
|
16663
|
+
query PreviewAutomationBranchMerge($automationId: ID!, $branchId: ID!) {
|
|
16664
|
+
automationBranchMergePreview(automationId: $automationId, branchId: $branchId) {
|
|
16665
|
+
baseVersionId
|
|
16666
|
+
sourceVersionId
|
|
16667
|
+
targetVersionId
|
|
16668
|
+
changes {
|
|
16669
|
+
id
|
|
16670
|
+
kind
|
|
16671
|
+
group
|
|
16672
|
+
status
|
|
16673
|
+
label
|
|
16674
|
+
discardable
|
|
16675
|
+
agentId
|
|
16676
|
+
agentName
|
|
16677
|
+
field
|
|
16678
|
+
configKey
|
|
16679
|
+
fromAgentId
|
|
16680
|
+
toAgentId
|
|
16681
|
+
conflictDescription
|
|
16682
|
+
statusDescription
|
|
16683
|
+
}
|
|
16684
|
+
}
|
|
16685
|
+
}`
|
|
16686
|
+
}),
|
|
16687
|
+
createOperationSpec({
|
|
16688
|
+
operationName: "DiscardAutomationBranchChanges",
|
|
16689
|
+
kind: "mutation",
|
|
16690
|
+
inputSchema: z27.object({
|
|
16691
|
+
automationId: z27.uuid("--automation-id must be a UUID."),
|
|
16692
|
+
branchId: z27.uuid("--branch-id must be a UUID."),
|
|
16693
|
+
changeIds: z27.array(
|
|
16694
|
+
z27.string().min(1).max(
|
|
16695
|
+
AUTOMATION_BRANCH_CHANGE_ID_MAX_LENGTH,
|
|
16696
|
+
`--change-ids entries must be at most ${AUTOMATION_BRANCH_CHANGE_ID_MAX_LENGTH} characters.`
|
|
16697
|
+
)
|
|
16698
|
+
).min(1, "--change-ids must name at least one preview change id.").max(
|
|
16699
|
+
AUTOMATION_BRANCH_DISCARD_MAX_CHANGE_IDS,
|
|
16700
|
+
`--change-ids can name at most ${AUTOMATION_BRANCH_DISCARD_MAX_CHANGE_IDS} preview change ids per run.`
|
|
16701
|
+
),
|
|
16702
|
+
sourceVersionId: z27.uuid("--source-version-id must be a UUID."),
|
|
16703
|
+
targetVersionId: z27.uuid("--target-version-id must be a UUID.")
|
|
16704
|
+
}),
|
|
16705
|
+
cli: {
|
|
16706
|
+
branchContext: "required",
|
|
16707
|
+
name: "discard-automation-branch-changes",
|
|
16708
|
+
path: ["automations", "branches", "discard-changes"],
|
|
16709
|
+
description: "Revert preview changes on the branch so main keeps its values. Pass the change ids plus the source and target version ids from the preview you are acting on.",
|
|
16710
|
+
resultKey: "discardAutomationBranchChanges",
|
|
16711
|
+
options: [
|
|
16712
|
+
stringOption({
|
|
16713
|
+
inputKey: "automationId",
|
|
16714
|
+
flagName: "automation-id",
|
|
16715
|
+
description: "Automation ID.",
|
|
16716
|
+
required: true
|
|
16717
|
+
}),
|
|
16718
|
+
stringArrayOption({
|
|
16719
|
+
inputKey: "changeIds",
|
|
16720
|
+
flagName: "change-ids",
|
|
16721
|
+
description: "Preview change ids to revert on the branch, for example agent:update:<agent-id>:instructions.",
|
|
16722
|
+
required: true
|
|
16723
|
+
}),
|
|
16724
|
+
stringOption({
|
|
16725
|
+
inputKey: "sourceVersionId",
|
|
16726
|
+
flagName: "source-version-id",
|
|
16727
|
+
description: "sourceVersionId from the preview being acted on.",
|
|
16728
|
+
required: true
|
|
16729
|
+
}),
|
|
16730
|
+
stringOption({
|
|
16731
|
+
inputKey: "targetVersionId",
|
|
16732
|
+
flagName: "target-version-id",
|
|
16733
|
+
description: "targetVersionId from the preview being acted on.",
|
|
16734
|
+
required: true
|
|
16735
|
+
})
|
|
16736
|
+
]
|
|
16737
|
+
},
|
|
16738
|
+
mcp: { fileName: "discardAutomationBranchChanges.graphql" },
|
|
16739
|
+
document: `# Revert preview changes on a branch and return the refreshed merge preview.
|
|
16740
|
+
mutation DiscardAutomationBranchChanges(
|
|
16741
|
+
$automationId: ID!
|
|
16742
|
+
$branchId: ID!
|
|
16743
|
+
$changeIds: [String!]!
|
|
16744
|
+
$sourceVersionId: ID!
|
|
16745
|
+
$targetVersionId: ID!
|
|
16746
|
+
) {
|
|
16747
|
+
discardAutomationBranchChanges(
|
|
16748
|
+
automationId: $automationId
|
|
16749
|
+
branchId: $branchId
|
|
16750
|
+
changeIds: $changeIds
|
|
16751
|
+
sourceVersionId: $sourceVersionId
|
|
16752
|
+
targetVersionId: $targetVersionId
|
|
16753
|
+
) {
|
|
16754
|
+
automationId
|
|
16755
|
+
branchId
|
|
16756
|
+
previousHeadVersionId
|
|
16757
|
+
headVersionId
|
|
16758
|
+
discardedChangeIds
|
|
16759
|
+
preview {
|
|
16760
|
+
baseVersionId
|
|
16761
|
+
sourceVersionId
|
|
16762
|
+
targetVersionId
|
|
16763
|
+
changes {
|
|
16764
|
+
id
|
|
16765
|
+
kind
|
|
16766
|
+
group
|
|
16767
|
+
status
|
|
16768
|
+
label
|
|
16769
|
+
discardable
|
|
16770
|
+
agentId
|
|
16771
|
+
agentName
|
|
16772
|
+
field
|
|
16773
|
+
configKey
|
|
16774
|
+
fromAgentId
|
|
16775
|
+
toAgentId
|
|
16776
|
+
conflictDescription
|
|
16777
|
+
statusDescription
|
|
16778
|
+
}
|
|
16779
|
+
}
|
|
16780
|
+
}
|
|
16169
16781
|
}`
|
|
16170
16782
|
}),
|
|
16171
16783
|
createOperationSpec({
|
|
@@ -16276,7 +16888,8 @@ query GetAvailableCommands($env: AvailableCommandsEnv!) {
|
|
|
16276
16888
|
operationName: "GetAvailableModels",
|
|
16277
16889
|
kind: "query",
|
|
16278
16890
|
inputSchema: z27.object({
|
|
16279
|
-
agentId: z27.string().min(1)
|
|
16891
|
+
agentId: z27.string().min(1),
|
|
16892
|
+
automationId: z27.string().min(1)
|
|
16280
16893
|
}),
|
|
16281
16894
|
cli: {
|
|
16282
16895
|
name: "get-available-models",
|
|
@@ -16289,13 +16902,20 @@ query GetAvailableCommands($env: AvailableCommandsEnv!) {
|
|
|
16289
16902
|
flagName: "agent-id",
|
|
16290
16903
|
description: "Agent ID.",
|
|
16291
16904
|
required: true
|
|
16905
|
+
}),
|
|
16906
|
+
stringOption({
|
|
16907
|
+
inputKey: "automationId",
|
|
16908
|
+
flagName: "automation-id",
|
|
16909
|
+
description: "Automation whose head pins the agent (required with agent-id).",
|
|
16910
|
+
required: true
|
|
16292
16911
|
})
|
|
16293
16912
|
]
|
|
16294
16913
|
},
|
|
16295
16914
|
mcp: { fileName: "availableModels.graphql" },
|
|
16296
16915
|
document: `# Query to fetch available model definitions and pools for a specific agent
|
|
16297
|
-
|
|
16298
|
-
|
|
16916
|
+
# from that automation's head (agent model config resolves branch-safely).
|
|
16917
|
+
query GetAvailableModels($agentId: String!, $automationId: String!) {
|
|
16918
|
+
availableModels(agentId: $agentId, automationId: $automationId) {
|
|
16299
16919
|
availableModelPools {
|
|
16300
16920
|
name
|
|
16301
16921
|
poolId
|
|
@@ -18348,7 +18968,7 @@ ${evalRunExportSelection}
|
|
|
18348
18968
|
];
|
|
18349
18969
|
|
|
18350
18970
|
// src/program.ts
|
|
18351
|
-
import { Command as
|
|
18971
|
+
import { Command as Command4, InvalidArgumentError as InvalidArgumentError2, Option as Option4 } from "commander";
|
|
18352
18972
|
|
|
18353
18973
|
// src/api.ts
|
|
18354
18974
|
import { randomUUID } from "node:crypto";
|
|
@@ -18682,8 +19302,110 @@ var pathwayRegressionRunResultResponseSchema = z28.object({
|
|
|
18682
19302
|
workflowId: z28.string().min(1)
|
|
18683
19303
|
})
|
|
18684
19304
|
});
|
|
18685
|
-
var
|
|
18686
|
-
|
|
19305
|
+
var regressionTestPathwayStatusSchema = z28.enum([
|
|
19306
|
+
"new_pathway",
|
|
19307
|
+
"missing_after_change",
|
|
19308
|
+
"historical_path_missing_after_change",
|
|
19309
|
+
"no_matching_runs",
|
|
19310
|
+
"queued",
|
|
19311
|
+
"running",
|
|
19312
|
+
"passed",
|
|
19313
|
+
"failed",
|
|
19314
|
+
"inconclusive",
|
|
19315
|
+
"errored"
|
|
19316
|
+
]);
|
|
19317
|
+
var regressionTestStatusSchema = z28.enum([
|
|
19318
|
+
"queued",
|
|
19319
|
+
"running",
|
|
19320
|
+
"passed",
|
|
19321
|
+
"failed",
|
|
19322
|
+
"inconclusive",
|
|
19323
|
+
"errored"
|
|
19324
|
+
]);
|
|
19325
|
+
var regressionTestKickoffPathwaySchema = z28.object({
|
|
19326
|
+
baselineContractPathId: z28.string().min(1).nullable(),
|
|
19327
|
+
baselineLabel: z28.string().nullable(),
|
|
19328
|
+
candidateContractPathId: z28.string().min(1).nullable(),
|
|
19329
|
+
candidateLabel: z28.string().nullable(),
|
|
19330
|
+
id: z28.string().min(1),
|
|
19331
|
+
pathwayKey: z28.string().min(1),
|
|
19332
|
+
status: regressionTestPathwayStatusSchema
|
|
19333
|
+
});
|
|
19334
|
+
var regressionTestKickoffResponseSchema = z28.object({
|
|
19335
|
+
pathways: z28.array(regressionTestKickoffPathwaySchema),
|
|
19336
|
+
regressionTestId: z28.string().min(1),
|
|
19337
|
+
status: regressionTestStatusSchema
|
|
19338
|
+
});
|
|
19339
|
+
var regressionTestIterationCountsSchema = z28.object({
|
|
19340
|
+
errored: z28.number(),
|
|
19341
|
+
failed: z28.number(),
|
|
19342
|
+
passed: z28.number(),
|
|
19343
|
+
total: z28.number()
|
|
19344
|
+
});
|
|
19345
|
+
var regressionTestBaselineRunSummarySchema = z28.object({
|
|
19346
|
+
id: z28.string().min(1),
|
|
19347
|
+
iterationCounts: regressionTestIterationCountsSchema
|
|
19348
|
+
});
|
|
19349
|
+
var regressionTestPathwaySummarySchema = z28.object({
|
|
19350
|
+
baselineLabel: z28.string().nullable(),
|
|
19351
|
+
baselineRuns: z28.array(regressionTestBaselineRunSummarySchema),
|
|
19352
|
+
candidateLabel: z28.string().nullable(),
|
|
19353
|
+
id: z28.string().min(1),
|
|
19354
|
+
pathwayKey: z28.string().min(1),
|
|
19355
|
+
status: regressionTestPathwayStatusSchema
|
|
19356
|
+
});
|
|
19357
|
+
var regressionTestResultResponseSchema = z28.object({
|
|
19358
|
+
pathways: z28.array(regressionTestPathwaySummarySchema),
|
|
19359
|
+
regressionTest: z28.object({
|
|
19360
|
+
finishedAt: z28.string().nullable(),
|
|
19361
|
+
id: z28.string().min(1),
|
|
19362
|
+
startedAt: z28.string().nullable(),
|
|
19363
|
+
status: regressionTestStatusSchema
|
|
19364
|
+
})
|
|
19365
|
+
});
|
|
19366
|
+
var regressionTestBaselineStepSchema = z28.object({
|
|
19367
|
+
expectedToolCall: z28.unknown().nullable(),
|
|
19368
|
+
id: z28.string().min(1),
|
|
19369
|
+
iterationIndex: z28.number()
|
|
19370
|
+
});
|
|
19371
|
+
var regressionTestFailedToolCallSchema = z28.object({
|
|
19372
|
+
count: z28.number(),
|
|
19373
|
+
observedToolCall: z28.unknown()
|
|
19374
|
+
});
|
|
19375
|
+
var regressionTestFailedIterationSchema = z28.object({
|
|
19376
|
+
baselineIterationId: z28.string().min(1),
|
|
19377
|
+
failedToolCalls: z28.array(regressionTestFailedToolCallSchema)
|
|
19378
|
+
});
|
|
19379
|
+
var regressionTestReplayCountsSchema = z28.object({
|
|
19380
|
+
errored: z28.number(),
|
|
19381
|
+
failed: z28.number(),
|
|
19382
|
+
passed: z28.number()
|
|
19383
|
+
});
|
|
19384
|
+
var regressionTestBaselineRunSchema = z28.object({
|
|
19385
|
+
baselineAgentRunId: z28.string().min(1),
|
|
19386
|
+
baselineIterations: z28.array(regressionTestBaselineStepSchema),
|
|
19387
|
+
failedIterations: z28.array(regressionTestFailedIterationSchema),
|
|
19388
|
+
replayCounts: regressionTestReplayCountsSchema
|
|
19389
|
+
});
|
|
19390
|
+
var regressionTestPathwayDetailSchema = z28.object({
|
|
19391
|
+
baselineLabel: z28.string().nullable(),
|
|
19392
|
+
baselineRuns: z28.array(regressionTestBaselineRunSchema),
|
|
19393
|
+
candidateLabel: z28.string().nullable(),
|
|
19394
|
+
id: z28.string().min(1),
|
|
19395
|
+
pathwayKey: z28.string().min(1),
|
|
19396
|
+
status: regressionTestPathwayStatusSchema
|
|
19397
|
+
});
|
|
19398
|
+
var regressionTestPathwayResultResponseSchema = z28.object({
|
|
19399
|
+
pathway: regressionTestPathwayDetailSchema,
|
|
19400
|
+
regressionTest: z28.object({
|
|
19401
|
+
finishedAt: z28.string().nullable(),
|
|
19402
|
+
id: z28.string().min(1),
|
|
19403
|
+
startedAt: z28.string().nullable(),
|
|
19404
|
+
status: regressionTestStatusSchema
|
|
19405
|
+
})
|
|
19406
|
+
});
|
|
19407
|
+
var graphQlResponseSchema = z28.object({
|
|
19408
|
+
data: z28.record(z28.string(), z28.unknown()).nullable().optional(),
|
|
18687
19409
|
errors: z28.array(
|
|
18688
19410
|
z28.object({
|
|
18689
19411
|
extensions: z28.object({
|
|
@@ -18723,6 +19445,7 @@ function getGraphQlErrorStatus(error) {
|
|
|
18723
19445
|
return error.extensions?.appErrorType?.includes("not-found") ? 404 : void 0;
|
|
18724
19446
|
}
|
|
18725
19447
|
var apiErrorResponseSchema = z28.object({
|
|
19448
|
+
code: z28.string().min(1).optional(),
|
|
18726
19449
|
errors: z28.array(
|
|
18727
19450
|
z28.object({
|
|
18728
19451
|
message: z28.string().min(1)
|
|
@@ -18743,6 +19466,13 @@ function getApiErrorDetail(responseBody) {
|
|
|
18743
19466
|
}
|
|
18744
19467
|
return parsedResponse.data.errors.map((error) => error.message).join("\n");
|
|
18745
19468
|
}
|
|
19469
|
+
function getApiErrorCode(responseBody) {
|
|
19470
|
+
const parsedResponse = apiErrorResponseSchema.safeParse(responseBody);
|
|
19471
|
+
if (!parsedResponse.success) {
|
|
19472
|
+
return null;
|
|
19473
|
+
}
|
|
19474
|
+
return parsedResponse.data.code ?? null;
|
|
19475
|
+
}
|
|
18746
19476
|
function getRetryAfterMs(response) {
|
|
18747
19477
|
const retryAfter = response.headers.get("retry-after");
|
|
18748
19478
|
if (!retryAfter) {
|
|
@@ -18872,12 +19602,12 @@ function applyAuthenticationHeaders({
|
|
|
18872
19602
|
headers.set(OTTO_AUTHORIZATION_HEADER_NAME, `Bearer ${accessToken}`);
|
|
18873
19603
|
headers.set("x-organization-id", organizationId);
|
|
18874
19604
|
}
|
|
18875
|
-
function
|
|
19605
|
+
function createFetchJson({
|
|
18876
19606
|
apiBaseUrl,
|
|
18877
|
-
fetchFn
|
|
19607
|
+
fetchFn
|
|
18878
19608
|
}) {
|
|
18879
19609
|
const resolveApiBaseUrl = typeof apiBaseUrl === "string" ? () => apiBaseUrl : apiBaseUrl;
|
|
18880
|
-
async function fetchJson({
|
|
19610
|
+
return async function fetchJson({
|
|
18881
19611
|
accessToken,
|
|
18882
19612
|
impersonatedOrganizationId,
|
|
18883
19613
|
allowOttoAuthorization,
|
|
@@ -18929,13 +19659,23 @@ function createMagicalApiClient({
|
|
|
18929
19659
|
});
|
|
18930
19660
|
if (!response.ok) {
|
|
18931
19661
|
const errorDetail = getApiErrorDetail(responseBody);
|
|
19662
|
+
const apiErrorCode = getApiErrorCode(responseBody);
|
|
18932
19663
|
throw new CliError(
|
|
18933
19664
|
`Magical API request to ${url} failed with status ${response.status}${errorDetail ? `: ${errorDetail}` : "."}`,
|
|
18934
|
-
|
|
19665
|
+
{
|
|
19666
|
+
...errorOptions,
|
|
19667
|
+
...apiErrorCode === null ? {} : { apiErrorCode }
|
|
19668
|
+
}
|
|
18935
19669
|
);
|
|
18936
19670
|
}
|
|
18937
19671
|
return responseBody;
|
|
18938
|
-
}
|
|
19672
|
+
};
|
|
19673
|
+
}
|
|
19674
|
+
function createMagicalApiClient({
|
|
19675
|
+
apiBaseUrl,
|
|
19676
|
+
fetchFn = fetch
|
|
19677
|
+
}) {
|
|
19678
|
+
const fetchJson = createFetchJson({ apiBaseUrl, fetchFn });
|
|
18939
19679
|
return {
|
|
18940
19680
|
async downloadFile({ outputPath, overwrite = false, url }) {
|
|
18941
19681
|
if (!overwrite) {
|
|
@@ -19228,6 +19968,77 @@ function createMagicalApiClient({
|
|
|
19228
19968
|
);
|
|
19229
19969
|
}
|
|
19230
19970
|
return parsedResponse.data;
|
|
19971
|
+
},
|
|
19972
|
+
async startAgentVersionRegressionTest({
|
|
19973
|
+
accessToken,
|
|
19974
|
+
agentVersionId,
|
|
19975
|
+
automationVersionId,
|
|
19976
|
+
impersonatedOrganizationId,
|
|
19977
|
+
organizationId
|
|
19978
|
+
}) {
|
|
19979
|
+
const parsedResponse = regressionTestKickoffResponseSchema.safeParse(
|
|
19980
|
+
await fetchJson({
|
|
19981
|
+
accessToken,
|
|
19982
|
+
allowOttoAuthorization: true,
|
|
19983
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
19984
|
+
...organizationId ? { organizationId } : {},
|
|
19985
|
+
path: `/pathway-regression/tests/automation-versions/${encodeURIComponent(
|
|
19986
|
+
automationVersionId
|
|
19987
|
+
)}/agent-versions/${encodeURIComponent(agentVersionId)}/run`,
|
|
19988
|
+
init: {
|
|
19989
|
+
method: "POST"
|
|
19990
|
+
}
|
|
19991
|
+
})
|
|
19992
|
+
);
|
|
19993
|
+
if (!parsedResponse.success) {
|
|
19994
|
+
throw new CliError("Regression test kickoff payload was invalid.");
|
|
19995
|
+
}
|
|
19996
|
+
return parsedResponse.data;
|
|
19997
|
+
},
|
|
19998
|
+
async getAgentVersionRegressionTestResult({
|
|
19999
|
+
accessToken,
|
|
20000
|
+
impersonatedOrganizationId,
|
|
20001
|
+
organizationId,
|
|
20002
|
+
regressionTestId
|
|
20003
|
+
}) {
|
|
20004
|
+
const parsedResponse = regressionTestResultResponseSchema.safeParse(
|
|
20005
|
+
await fetchJson({
|
|
20006
|
+
accessToken,
|
|
20007
|
+
allowOttoAuthorization: true,
|
|
20008
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
20009
|
+
...organizationId ? { organizationId } : {},
|
|
20010
|
+
path: `/pathway-regression/tests/${encodeURIComponent(
|
|
20011
|
+
regressionTestId
|
|
20012
|
+
)}`
|
|
20013
|
+
})
|
|
20014
|
+
);
|
|
20015
|
+
if (!parsedResponse.success) {
|
|
20016
|
+
throw new CliError("Regression test result payload was invalid.");
|
|
20017
|
+
}
|
|
20018
|
+
return parsedResponse.data;
|
|
20019
|
+
},
|
|
20020
|
+
async getAgentVersionRegressionTestPathway({
|
|
20021
|
+
accessToken,
|
|
20022
|
+
impersonatedOrganizationId,
|
|
20023
|
+
organizationId,
|
|
20024
|
+
regressionTestId,
|
|
20025
|
+
testPathwayId
|
|
20026
|
+
}) {
|
|
20027
|
+
const parsedResponse = regressionTestPathwayResultResponseSchema.safeParse(
|
|
20028
|
+
await fetchJson({
|
|
20029
|
+
accessToken,
|
|
20030
|
+
allowOttoAuthorization: true,
|
|
20031
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
20032
|
+
...organizationId ? { organizationId } : {},
|
|
20033
|
+
path: `/pathway-regression/tests/${encodeURIComponent(
|
|
20034
|
+
regressionTestId
|
|
20035
|
+
)}/pathways/${encodeURIComponent(testPathwayId)}`
|
|
20036
|
+
})
|
|
20037
|
+
);
|
|
20038
|
+
if (!parsedResponse.success) {
|
|
20039
|
+
throw new CliError("Regression test pathway payload was invalid.");
|
|
20040
|
+
}
|
|
20041
|
+
return parsedResponse.data;
|
|
19231
20042
|
}
|
|
19232
20043
|
};
|
|
19233
20044
|
}
|
|
@@ -19454,6 +20265,18 @@ async function handleAuthLogin(dependencies, options) {
|
|
|
19454
20265
|
);
|
|
19455
20266
|
}
|
|
19456
20267
|
|
|
20268
|
+
// src/branch-merge.ts
|
|
20269
|
+
function isRecord5(value) {
|
|
20270
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20271
|
+
}
|
|
20272
|
+
function assertBranchMergeApplied(operationSpec, result) {
|
|
20273
|
+
if (operationSpec.operationName === "MergeAutomationBranch" && (!isRecord5(result) || result["status"] !== "merged")) {
|
|
20274
|
+
throw new CliError(
|
|
20275
|
+
isRecord5(result) && result["status"] === "conflict" ? "Merge not applied. Discard the conflicting changes with `mgcl automations branches discard-changes` (main keeps its values) or edit the branch to match main, then rerun this merge command." : "Merge not applied. Review the merge output, resolve any conflicts, then merge again."
|
|
20276
|
+
);
|
|
20277
|
+
}
|
|
20278
|
+
}
|
|
20279
|
+
|
|
19457
20280
|
// src/capture-commands.ts
|
|
19458
20281
|
import { Command, Option } from "commander";
|
|
19459
20282
|
|
|
@@ -19746,7 +20569,7 @@ async function pollCaptureRecording({
|
|
|
19746
20569
|
onStatus,
|
|
19747
20570
|
recordingId,
|
|
19748
20571
|
signal,
|
|
19749
|
-
sleep:
|
|
20572
|
+
sleep: sleep3 = async (delayMs) => {
|
|
19750
20573
|
await defaultSleep(delayMs, signal);
|
|
19751
20574
|
}
|
|
19752
20575
|
}) {
|
|
@@ -19772,7 +20595,7 @@ async function pollCaptureRecording({
|
|
|
19772
20595
|
throw error;
|
|
19773
20596
|
}
|
|
19774
20597
|
onRetry?.(error, retryDelay);
|
|
19775
|
-
await
|
|
20598
|
+
await sleep3(retryDelay);
|
|
19776
20599
|
return await pollNext(state);
|
|
19777
20600
|
}
|
|
19778
20601
|
const status = statusResult.value;
|
|
@@ -19787,7 +20610,7 @@ async function pollCaptureRecording({
|
|
|
19787
20610
|
if (TERMINAL_STATUSES.has(status.status)) {
|
|
19788
20611
|
return status;
|
|
19789
20612
|
}
|
|
19790
|
-
await
|
|
20613
|
+
await sleep3(DEFAULT_POLL_INTERVAL_MS);
|
|
19791
20614
|
return await pollNext({
|
|
19792
20615
|
effectiveDeadlineMs,
|
|
19793
20616
|
hasObservedRecording: true
|
|
@@ -20053,10 +20876,10 @@ async function finishExport({
|
|
|
20053
20876
|
async function pollExport({
|
|
20054
20877
|
executeOperation,
|
|
20055
20878
|
exportId,
|
|
20056
|
-
sleep:
|
|
20879
|
+
sleep: sleep3
|
|
20057
20880
|
}) {
|
|
20058
20881
|
for (; ; ) {
|
|
20059
|
-
await
|
|
20882
|
+
await sleep3(EXPORT_POLL_INTERVAL_MS);
|
|
20060
20883
|
const result = parseApiResult(
|
|
20061
20884
|
// eslint-disable-next-line no-await-in-loop -- do not overlap signed-export status requests
|
|
20062
20885
|
await executeOperation("GetEvalRunExport", { exportId }),
|
|
@@ -20476,6 +21299,267 @@ function isExpiredAccessTokenClaims(claims) {
|
|
|
20476
21299
|
return claims.exp * 1e3 <= Date.now();
|
|
20477
21300
|
}
|
|
20478
21301
|
|
|
21302
|
+
// src/regression-commands.ts
|
|
21303
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
21304
|
+
import { Command as Command2, Option as Option2 } from "commander";
|
|
21305
|
+
var REGRESSION_TEST_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
21306
|
+
"passed",
|
|
21307
|
+
"failed",
|
|
21308
|
+
"inconclusive",
|
|
21309
|
+
"errored"
|
|
21310
|
+
]);
|
|
21311
|
+
var REGRESSION_TEST_POLL_INTERVAL_MS = 5e3;
|
|
21312
|
+
var REGRESSION_TEST_KICKOFF_RETRY_DELAY_MS = 5e3;
|
|
21313
|
+
var REGRESSION_TEST_RETRYABLE_KICKOFF_ERROR_CODE = "PATHWAY_CONTRACT_NOT_READY";
|
|
21314
|
+
function isRetryableRegressionTestKickoffError(error) {
|
|
21315
|
+
return error instanceof CliError && error.statusCode === 409 && error.apiErrorCode === REGRESSION_TEST_RETRYABLE_KICKOFF_ERROR_CODE;
|
|
21316
|
+
}
|
|
21317
|
+
function summarizeRegressionTestResult(result) {
|
|
21318
|
+
return {
|
|
21319
|
+
regressionTestId: result.regressionTest.id,
|
|
21320
|
+
status: result.regressionTest.status,
|
|
21321
|
+
startedAt: result.regressionTest.startedAt,
|
|
21322
|
+
finishedAt: result.regressionTest.finishedAt,
|
|
21323
|
+
pathways: result.pathways.map((pathway) => ({
|
|
21324
|
+
id: pathway.id,
|
|
21325
|
+
pathwayKey: pathway.pathwayKey,
|
|
21326
|
+
baselineLabel: pathway.baselineLabel,
|
|
21327
|
+
candidateLabel: pathway.candidateLabel,
|
|
21328
|
+
status: pathway.status,
|
|
21329
|
+
baselineRuns: pathway.baselineRuns.map((run) => ({
|
|
21330
|
+
id: run.id,
|
|
21331
|
+
iterationCounts: run.iterationCounts
|
|
21332
|
+
}))
|
|
21333
|
+
}))
|
|
21334
|
+
};
|
|
21335
|
+
}
|
|
21336
|
+
function summarizeRegressionTestPathway(result) {
|
|
21337
|
+
return {
|
|
21338
|
+
regressionTestId: result.regressionTest.id,
|
|
21339
|
+
status: result.regressionTest.status,
|
|
21340
|
+
pathway: {
|
|
21341
|
+
id: result.pathway.id,
|
|
21342
|
+
pathwayKey: result.pathway.pathwayKey,
|
|
21343
|
+
baselineLabel: result.pathway.baselineLabel,
|
|
21344
|
+
candidateLabel: result.pathway.candidateLabel,
|
|
21345
|
+
status: result.pathway.status,
|
|
21346
|
+
baselineRuns: result.pathway.baselineRuns.map((run) => ({
|
|
21347
|
+
baselineAgentRunId: run.baselineAgentRunId,
|
|
21348
|
+
replayCounts: run.replayCounts,
|
|
21349
|
+
baselineIterationCount: run.baselineIterations.length,
|
|
21350
|
+
failedIterations: run.failedIterations.map((fi) => ({
|
|
21351
|
+
baselineIterationId: fi.baselineIterationId,
|
|
21352
|
+
failedToolCalls: fi.failedToolCalls.map((ftc) => ({
|
|
21353
|
+
observedToolCall: ftc.observedToolCall,
|
|
21354
|
+
count: ftc.count
|
|
21355
|
+
}))
|
|
21356
|
+
}))
|
|
21357
|
+
}))
|
|
21358
|
+
}
|
|
21359
|
+
};
|
|
21360
|
+
}
|
|
21361
|
+
async function startRegressionTestWithRetry({
|
|
21362
|
+
dependencies,
|
|
21363
|
+
input,
|
|
21364
|
+
startRegressionTest
|
|
21365
|
+
}) {
|
|
21366
|
+
for (; ; ) {
|
|
21367
|
+
const result = await fromThrowable(
|
|
21368
|
+
startRegressionTest.bind(void 0, input),
|
|
21369
|
+
"regression-test-kickoff-failed"
|
|
21370
|
+
);
|
|
21371
|
+
if (!isErr(result)) {
|
|
21372
|
+
return result.value;
|
|
21373
|
+
}
|
|
21374
|
+
if (!isRetryableRegressionTestKickoffError(result.error.cause)) {
|
|
21375
|
+
throw result.error.cause;
|
|
21376
|
+
}
|
|
21377
|
+
dependencies.io.info("Contract generation in progress, retrying...");
|
|
21378
|
+
await sleep(REGRESSION_TEST_KICKOFF_RETRY_DELAY_MS);
|
|
21379
|
+
}
|
|
21380
|
+
}
|
|
21381
|
+
async function pollRegressionTestResult({
|
|
21382
|
+
dependencies,
|
|
21383
|
+
getRegressionTestResult,
|
|
21384
|
+
input,
|
|
21385
|
+
regressionTestId
|
|
21386
|
+
}) {
|
|
21387
|
+
for (; ; ) {
|
|
21388
|
+
await sleep(REGRESSION_TEST_POLL_INTERVAL_MS);
|
|
21389
|
+
const result = await getRegressionTestResult({
|
|
21390
|
+
...input,
|
|
21391
|
+
regressionTestId
|
|
21392
|
+
});
|
|
21393
|
+
if (REGRESSION_TEST_TERMINAL_STATUSES.has(result.regressionTest.status)) {
|
|
21394
|
+
return result;
|
|
21395
|
+
}
|
|
21396
|
+
dependencies.io.info(
|
|
21397
|
+
`Regression test ${regressionTestId}: ${result.regressionTest.status}...`
|
|
21398
|
+
);
|
|
21399
|
+
}
|
|
21400
|
+
}
|
|
21401
|
+
async function handleRegressionRunCommand({
|
|
21402
|
+
dependencies,
|
|
21403
|
+
helpers,
|
|
21404
|
+
options
|
|
21405
|
+
}) {
|
|
21406
|
+
const { accessToken, impersonatedOrganizationId, organization, state } = await helpers.withSelectedOrganizationAndAccessToken({
|
|
21407
|
+
dependencies,
|
|
21408
|
+
options
|
|
21409
|
+
});
|
|
21410
|
+
const startAgentVersionRegressionTest = helpers.requireApiClientMethod(
|
|
21411
|
+
dependencies.apiClient,
|
|
21412
|
+
"startAgentVersionRegressionTest"
|
|
21413
|
+
);
|
|
21414
|
+
const getAgentVersionRegressionTestResult = helpers.requireApiClientMethod(
|
|
21415
|
+
dependencies.apiClient,
|
|
21416
|
+
"getAgentVersionRegressionTestResult"
|
|
21417
|
+
);
|
|
21418
|
+
const authParams = {
|
|
21419
|
+
accessToken,
|
|
21420
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
21421
|
+
organizationId: organization.id
|
|
21422
|
+
};
|
|
21423
|
+
const kickoffResult = await startRegressionTestWithRetry({
|
|
21424
|
+
dependencies,
|
|
21425
|
+
input: {
|
|
21426
|
+
...authParams,
|
|
21427
|
+
agentVersionId: options.agentVersion,
|
|
21428
|
+
automationVersionId: options.automationVersion
|
|
21429
|
+
},
|
|
21430
|
+
startRegressionTest: startAgentVersionRegressionTest
|
|
21431
|
+
});
|
|
21432
|
+
const { regressionTestId } = kickoffResult;
|
|
21433
|
+
dependencies.io.info(`Regression test started: ${regressionTestId}`);
|
|
21434
|
+
const result = await pollRegressionTestResult({
|
|
21435
|
+
dependencies,
|
|
21436
|
+
getRegressionTestResult: getAgentVersionRegressionTestResult,
|
|
21437
|
+
input: authParams,
|
|
21438
|
+
regressionTestId
|
|
21439
|
+
});
|
|
21440
|
+
await helpers.saveLastUsedOrganization({
|
|
21441
|
+
dependencies,
|
|
21442
|
+
organizationId: organization.id,
|
|
21443
|
+
state
|
|
21444
|
+
});
|
|
21445
|
+
helpers.writeCommandOutput({
|
|
21446
|
+
dependencies,
|
|
21447
|
+
json: options.json,
|
|
21448
|
+
result: options.json ? result : summarizeRegressionTestResult(result)
|
|
21449
|
+
});
|
|
21450
|
+
}
|
|
21451
|
+
async function handleRegressionShowCommand({
|
|
21452
|
+
dependencies,
|
|
21453
|
+
helpers,
|
|
21454
|
+
options
|
|
21455
|
+
}) {
|
|
21456
|
+
const { accessToken, impersonatedOrganizationId, organization, state } = await helpers.withSelectedOrganizationAndAccessToken({
|
|
21457
|
+
dependencies,
|
|
21458
|
+
options
|
|
21459
|
+
});
|
|
21460
|
+
const authParams = {
|
|
21461
|
+
accessToken,
|
|
21462
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
21463
|
+
organizationId: organization.id
|
|
21464
|
+
};
|
|
21465
|
+
await helpers.saveLastUsedOrganization({
|
|
21466
|
+
dependencies,
|
|
21467
|
+
organizationId: organization.id,
|
|
21468
|
+
state
|
|
21469
|
+
});
|
|
21470
|
+
if (options.pathway) {
|
|
21471
|
+
const getAgentVersionRegressionTestPathway = helpers.requireApiClientMethod(
|
|
21472
|
+
dependencies.apiClient,
|
|
21473
|
+
"getAgentVersionRegressionTestPathway"
|
|
21474
|
+
);
|
|
21475
|
+
const result2 = await getAgentVersionRegressionTestPathway({
|
|
21476
|
+
...authParams,
|
|
21477
|
+
regressionTestId: options.testId,
|
|
21478
|
+
testPathwayId: options.pathway
|
|
21479
|
+
});
|
|
21480
|
+
helpers.writeCommandOutput({
|
|
21481
|
+
dependencies,
|
|
21482
|
+
json: options.json,
|
|
21483
|
+
result: options.json ? result2 : summarizeRegressionTestPathway(result2)
|
|
21484
|
+
});
|
|
21485
|
+
return;
|
|
21486
|
+
}
|
|
21487
|
+
const getAgentVersionRegressionTestResult = helpers.requireApiClientMethod(
|
|
21488
|
+
dependencies.apiClient,
|
|
21489
|
+
"getAgentVersionRegressionTestResult"
|
|
21490
|
+
);
|
|
21491
|
+
const result = await getAgentVersionRegressionTestResult({
|
|
21492
|
+
...authParams,
|
|
21493
|
+
regressionTestId: options.testId
|
|
21494
|
+
});
|
|
21495
|
+
helpers.writeCommandOutput({
|
|
21496
|
+
dependencies,
|
|
21497
|
+
json: options.json,
|
|
21498
|
+
result: options.json ? result : summarizeRegressionTestResult(result)
|
|
21499
|
+
});
|
|
21500
|
+
}
|
|
21501
|
+
function addRegressionCommands({
|
|
21502
|
+
dependencies,
|
|
21503
|
+
helpers,
|
|
21504
|
+
program: program2
|
|
21505
|
+
}) {
|
|
21506
|
+
const regressionCommand = configureCommandPresentation(
|
|
21507
|
+
new Command2("regression").description(
|
|
21508
|
+
"Run and inspect agent version regression tests."
|
|
21509
|
+
)
|
|
21510
|
+
).helpGroup("Workspace:").addHelpText(
|
|
21511
|
+
"after",
|
|
21512
|
+
`
|
|
21513
|
+
${formatExamples("Examples", [
|
|
21514
|
+
"mgcl regression run --automation-version <id> --agent-version <id>",
|
|
21515
|
+
"mgcl regression show <testId>",
|
|
21516
|
+
"mgcl regression show <testId> --pathway <pathwayId>"
|
|
21517
|
+
])}`
|
|
21518
|
+
);
|
|
21519
|
+
regressionCommand.command("run").description(
|
|
21520
|
+
"Start a regression test, poll until complete, and return the summary."
|
|
21521
|
+
).addOption(
|
|
21522
|
+
new Option2(
|
|
21523
|
+
"--org <org>",
|
|
21524
|
+
"Organization ID or exact organization name to use."
|
|
21525
|
+
).helpGroup("Shared options:")
|
|
21526
|
+
).addOption(
|
|
21527
|
+
new Option2(
|
|
21528
|
+
"--automation-version <id>",
|
|
21529
|
+
"Automation version to test against."
|
|
21530
|
+
).helpGroup("Regression options:").makeOptionMandatory(true)
|
|
21531
|
+
).addOption(
|
|
21532
|
+
new Option2("--agent-version <id>", "Agent version to test.").helpGroup("Regression options:").makeOptionMandatory(true)
|
|
21533
|
+
).action(async function() {
|
|
21534
|
+
await handleRegressionRunCommand({
|
|
21535
|
+
dependencies,
|
|
21536
|
+
helpers,
|
|
21537
|
+
options: this.optsWithGlobals()
|
|
21538
|
+
});
|
|
21539
|
+
});
|
|
21540
|
+
regressionCommand.command("show <testId>").description("Show regression test results.").addOption(
|
|
21541
|
+
new Option2(
|
|
21542
|
+
"--org <org>",
|
|
21543
|
+
"Organization ID or exact organization name to use."
|
|
21544
|
+
).helpGroup("Shared options:")
|
|
21545
|
+
).addOption(
|
|
21546
|
+
new Option2(
|
|
21547
|
+
"--pathway <pathwayId>",
|
|
21548
|
+
"Show detail for a specific pathway."
|
|
21549
|
+
).helpGroup("Regression options:")
|
|
21550
|
+
).action(async function(testId) {
|
|
21551
|
+
await handleRegressionShowCommand({
|
|
21552
|
+
dependencies,
|
|
21553
|
+
helpers,
|
|
21554
|
+
options: {
|
|
21555
|
+
...this.optsWithGlobals(),
|
|
21556
|
+
testId
|
|
21557
|
+
}
|
|
21558
|
+
});
|
|
21559
|
+
});
|
|
21560
|
+
program2.addCommand(regressionCommand);
|
|
21561
|
+
}
|
|
21562
|
+
|
|
20479
21563
|
// src/self-update.ts
|
|
20480
21564
|
import { spawn as spawn2 } from "node:child_process";
|
|
20481
21565
|
import fs2 from "node:fs";
|
|
@@ -20640,7 +21724,7 @@ async function selfUpdateInstalledCli({
|
|
|
20640
21724
|
}
|
|
20641
21725
|
|
|
20642
21726
|
// src/settings-command.ts
|
|
20643
|
-
import { Command as
|
|
21727
|
+
import { Command as Command3, InvalidArgumentError, Option as Option3 } from "commander";
|
|
20644
21728
|
function writeJsonOutput2(io, value) {
|
|
20645
21729
|
io.info(JSON.stringify(value, null, 2));
|
|
20646
21730
|
}
|
|
@@ -20718,7 +21802,7 @@ async function handleSettingsEnvBaseUrl(dependencies, rawBaseUrl, options) {
|
|
|
20718
21802
|
}
|
|
20719
21803
|
function createSettingsCommand(dependencies) {
|
|
20720
21804
|
const settingsCommand = configureCommandPresentation(
|
|
20721
|
-
new
|
|
21805
|
+
new Command3("settings").description("Manage persisted CLI settings.")
|
|
20722
21806
|
).helpGroup("Workspace:").addHelpText(
|
|
20723
21807
|
"after",
|
|
20724
21808
|
`
|
|
@@ -20728,7 +21812,7 @@ ${formatExamples("Examples", [
|
|
|
20728
21812
|
])}`
|
|
20729
21813
|
);
|
|
20730
21814
|
const settingsEnvCommand = settingsCommand.command("env").description("Manage persisted environment overrides.");
|
|
20731
|
-
settingsEnvCommand.command("base-url [url]").description("Set or clear the persisted Magical API base URL override.").addOption(new
|
|
21815
|
+
settingsEnvCommand.command("base-url [url]").description("Set or clear the persisted Magical API base URL override.").addOption(new Option3("--reset", "Clear the persisted base URL override.")).action(async function(baseUrl) {
|
|
20732
21816
|
await handleSettingsEnvBaseUrl(
|
|
20733
21817
|
dependencies,
|
|
20734
21818
|
baseUrl,
|
|
@@ -21556,7 +22640,7 @@ var accessTokenClaimsSchema = z34.object({
|
|
|
21556
22640
|
});
|
|
21557
22641
|
function createWorkosAuthClient({
|
|
21558
22642
|
fetchFn = fetch,
|
|
21559
|
-
sleep:
|
|
22643
|
+
sleep: sleep3 = async (milliseconds) => {
|
|
21560
22644
|
await new Promise((resolve) => {
|
|
21561
22645
|
setTimeout(resolve, milliseconds);
|
|
21562
22646
|
});
|
|
@@ -21650,12 +22734,12 @@ function createWorkosAuthClient({
|
|
|
21650
22734
|
);
|
|
21651
22735
|
}
|
|
21652
22736
|
if (parsedError.data.error === "authorization_pending") {
|
|
21653
|
-
await
|
|
22737
|
+
await sleep3(nextIntervalMilliseconds);
|
|
21654
22738
|
return poll(nextIntervalMilliseconds);
|
|
21655
22739
|
}
|
|
21656
22740
|
if (parsedError.data.error === "slow_down") {
|
|
21657
22741
|
const slowedIntervalMilliseconds = nextIntervalMilliseconds + 5e3;
|
|
21658
|
-
await
|
|
22742
|
+
await sleep3(slowedIntervalMilliseconds);
|
|
21659
22743
|
return poll(slowedIntervalMilliseconds);
|
|
21660
22744
|
}
|
|
21661
22745
|
throw new CliError(
|
|
@@ -21739,7 +22823,7 @@ function parseCommandOptionValue(rawValue, optionSpec) {
|
|
|
21739
22823
|
function createCliCommanderOption(optionSpec, helpGroup) {
|
|
21740
22824
|
const optionFlags = optionSpec.valueType === "boolean" ? `--${optionSpec.flagName}` : `--${optionSpec.flagName} <value>`;
|
|
21741
22825
|
const optionDescription = optionSpec.valueHint ? `${optionSpec.description} (${optionSpec.valueHint})` : optionSpec.description;
|
|
21742
|
-
const nextOption = new
|
|
22826
|
+
const nextOption = new Option4(optionFlags, optionDescription).helpGroup(
|
|
21743
22827
|
helpGroup
|
|
21744
22828
|
);
|
|
21745
22829
|
if (optionSpec.valueType === "boolean") {
|
|
@@ -21759,7 +22843,7 @@ function parsePositiveIntegerOption(rawValue) {
|
|
|
21759
22843
|
}
|
|
21760
22844
|
return parsedValue;
|
|
21761
22845
|
}
|
|
21762
|
-
function
|
|
22846
|
+
function isRecord6(value) {
|
|
21763
22847
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21764
22848
|
}
|
|
21765
22849
|
function resolveOrganizationBySelector({
|
|
@@ -21836,7 +22920,7 @@ function parseOperationVariables(operationSpec, variables) {
|
|
|
21836
22920
|
parsedVariables.error.issues[0]?.message ?? "Invalid command input."
|
|
21837
22921
|
);
|
|
21838
22922
|
}
|
|
21839
|
-
if (!
|
|
22923
|
+
if (!isRecord6(parsedVariables.data)) {
|
|
21840
22924
|
throw new CliError("Invalid command input.");
|
|
21841
22925
|
}
|
|
21842
22926
|
return parsedVariables.data;
|
|
@@ -21934,13 +23018,17 @@ async function handleOperationCommand(dependencies, operationSpec, commandOption
|
|
|
21934
23018
|
...state,
|
|
21935
23019
|
lastUsedOrgId: organization.id
|
|
21936
23020
|
});
|
|
23021
|
+
const humanReadableFormatter = getBranchMergeFormatter(
|
|
23022
|
+
operationSpec.operationName
|
|
23023
|
+
);
|
|
21937
23024
|
writeCommandOutput({
|
|
21938
23025
|
dependencies,
|
|
23026
|
+
...humanReadableFormatter ? { humanReadableFormatter } : {},
|
|
21939
23027
|
json: commandOptions.json,
|
|
21940
23028
|
result
|
|
21941
23029
|
});
|
|
21942
23030
|
assertBranchMergeApplied(operationSpec, result);
|
|
21943
|
-
if (operationSpec.operationName === "ViewAutomationReview" && commandOptions["open"] &&
|
|
23031
|
+
if (operationSpec.operationName === "ViewAutomationReview" && commandOptions["open"] && isRecord6(result) && typeof result["reportUrl"] === "string") {
|
|
21944
23032
|
await dependencies.openExternalUrl(result["reportUrl"]).catch((error) => {
|
|
21945
23033
|
dependencies.io.error(
|
|
21946
23034
|
`Warning: Failed to open the automation review in the default browser: ${getErrorMessage(error)}`
|
|
@@ -21948,13 +23036,6 @@ async function handleOperationCommand(dependencies, operationSpec, commandOption
|
|
|
21948
23036
|
});
|
|
21949
23037
|
}
|
|
21950
23038
|
}
|
|
21951
|
-
function assertBranchMergeApplied(operationSpec, result) {
|
|
21952
|
-
if (operationSpec.operationName === "MergeAutomationBranch" && (!isRecord5(result) || result["status"] !== "merged")) {
|
|
21953
|
-
throw new CliError(
|
|
21954
|
-
"Merge not applied. Review the merge output, resolve any conflicts, then merge again."
|
|
21955
|
-
);
|
|
21956
|
-
}
|
|
21957
|
-
}
|
|
21958
23039
|
function getOperation(operationName) {
|
|
21959
23040
|
const operationSpec = operationSpecs.find(
|
|
21960
23041
|
(candidate) => candidate.operationName === operationName
|
|
@@ -22127,12 +23208,12 @@ function addSkillsWorkingCopyCommands({
|
|
|
22127
23208
|
skillsCommand
|
|
22128
23209
|
}) {
|
|
22129
23210
|
skillsCommand.command("pull <skill>").description("Download a root-level skill into ./skills/<skill-name>.").addOption(
|
|
22130
|
-
new
|
|
23211
|
+
new Option4(
|
|
22131
23212
|
"--org <org>",
|
|
22132
23213
|
"Organization ID or exact organization name to use."
|
|
22133
23214
|
).helpGroup("Shared options:")
|
|
22134
23215
|
).addOption(
|
|
22135
|
-
new
|
|
23216
|
+
new Option4(
|
|
22136
23217
|
"--force",
|
|
22137
23218
|
"Replace existing files or local edits with the remote bundle."
|
|
22138
23219
|
)
|
|
@@ -22151,7 +23232,7 @@ ${formatExamples("Examples", [
|
|
|
22151
23232
|
);
|
|
22152
23233
|
});
|
|
22153
23234
|
skillsCommand.command("diff <skill>").description("Preview local skill changes against the pulled bundle.").addOption(
|
|
22154
|
-
new
|
|
23235
|
+
new Option4(
|
|
22155
23236
|
"--org <org>",
|
|
22156
23237
|
"Organization ID or exact organization name to use."
|
|
22157
23238
|
).helpGroup("Shared options:")
|
|
@@ -22170,12 +23251,12 @@ ${formatExamples("Examples", [
|
|
|
22170
23251
|
);
|
|
22171
23252
|
});
|
|
22172
23253
|
skillsCommand.command("push <skill>").description("Atomically push local changes for one root-level skill.").addOption(
|
|
22173
|
-
new
|
|
23254
|
+
new Option4(
|
|
22174
23255
|
"--org <org>",
|
|
22175
23256
|
"Organization ID or exact organization name to use."
|
|
22176
23257
|
).helpGroup("Shared options:")
|
|
22177
23258
|
).addOption(
|
|
22178
|
-
new
|
|
23259
|
+
new Option4("--message <message>", "Commit message for the skill update.")
|
|
22179
23260
|
).addHelpText(
|
|
22180
23261
|
"after",
|
|
22181
23262
|
`
|
|
@@ -22216,6 +23297,7 @@ async function withSelectedOrganizationAndAccessToken({
|
|
|
22216
23297
|
}
|
|
22217
23298
|
function writeCommandOutput({
|
|
22218
23299
|
dependencies,
|
|
23300
|
+
humanReadableFormatter = formatHumanReadableOutput,
|
|
22219
23301
|
json,
|
|
22220
23302
|
result
|
|
22221
23303
|
}) {
|
|
@@ -22223,7 +23305,7 @@ function writeCommandOutput({
|
|
|
22223
23305
|
writeJsonOutput3(dependencies.io, result);
|
|
22224
23306
|
return;
|
|
22225
23307
|
}
|
|
22226
|
-
dependencies.io.info(
|
|
23308
|
+
dependencies.io.info(humanReadableFormatter(result));
|
|
22227
23309
|
}
|
|
22228
23310
|
async function handleNangoIntegrationsListCommand(dependencies, options) {
|
|
22229
23311
|
const { accessToken, impersonatedOrganizationId, organization, state } = await withSelectedOrganizationAndAccessToken({ dependencies, options });
|
|
@@ -22607,7 +23689,7 @@ async function retryCaptureRequest({
|
|
|
22607
23689
|
throw error;
|
|
22608
23690
|
}
|
|
22609
23691
|
onRetry(error, retryDelay);
|
|
22610
|
-
await
|
|
23692
|
+
await sleep2(retryDelay, void 0, { signal }).catch(
|
|
22611
23693
|
(sleepError) => {
|
|
22612
23694
|
throw new CliError("Capture wait interrupted.", { cause: sleepError });
|
|
22613
23695
|
}
|
|
@@ -22857,7 +23939,7 @@ function configureOperationalCommand(command, dependencies, operationSpec) {
|
|
|
22857
23939
|
command.description(operationSpec.cli.description);
|
|
22858
23940
|
if (operationSpec.scope !== "global") {
|
|
22859
23941
|
command.addOption(
|
|
22860
|
-
new
|
|
23942
|
+
new Option4(
|
|
22861
23943
|
"--org <org>",
|
|
22862
23944
|
"Organization ID or exact organization name to use."
|
|
22863
23945
|
).helpGroup("Shared options:")
|
|
@@ -22938,14 +24020,14 @@ function createDefaultDependencies() {
|
|
|
22938
24020
|
}
|
|
22939
24021
|
function buildProgram(dependencies) {
|
|
22940
24022
|
const program2 = configureCommandPresentation(
|
|
22941
|
-
new
|
|
22942
|
-
).addOption(new
|
|
22943
|
-
new
|
|
24023
|
+
new Command4().name("mgcl").description("Run Magical operations from the command line.")
|
|
24024
|
+
).addOption(new Option4("--json", "Render JSON output.")).addOption(
|
|
24025
|
+
new Option4(
|
|
22944
24026
|
"--branch-id <id>",
|
|
22945
24027
|
'Target a supported automation command at one branch; omit it to target main. "Branch-aware commands" below lists the commands that accept it.'
|
|
22946
24028
|
)
|
|
22947
24029
|
).version(CLI_VERSION, "--version", `Display mgcl version (${CLI_VERSION}).`).addOption(
|
|
22948
|
-
new
|
|
24030
|
+
new Option4(
|
|
22949
24031
|
"--update",
|
|
22950
24032
|
"Update mgcl to the latest published npm release."
|
|
22951
24033
|
)
|
|
@@ -22971,7 +24053,7 @@ function buildProgram(dependencies) {
|
|
|
22971
24053
|
this.outputHelp();
|
|
22972
24054
|
});
|
|
22973
24055
|
const authCommand = configureCommandPresentation(
|
|
22974
|
-
new
|
|
24056
|
+
new Command4("auth").description("Manage CLI authentication.")
|
|
22975
24057
|
).helpGroup("Workspace:").addHelpText(
|
|
22976
24058
|
"after",
|
|
22977
24059
|
`
|
|
@@ -22986,7 +24068,7 @@ ${formatExamples("Examples", ["mgcl auth login", "mgcl auth logout"])}`
|
|
|
22986
24068
|
program2.addCommand(authCommand);
|
|
22987
24069
|
program2.addCommand(createSettingsCommand(dependencies));
|
|
22988
24070
|
const orgCommand = configureCommandPresentation(
|
|
22989
|
-
new
|
|
24071
|
+
new Command4("org").description("Manage organization selection.")
|
|
22990
24072
|
).helpGroup("Workspace:").addHelpText(
|
|
22991
24073
|
"after",
|
|
22992
24074
|
`
|
|
@@ -23007,7 +24089,7 @@ ${formatExamples("Examples", [
|
|
|
23007
24089
|
});
|
|
23008
24090
|
program2.addCommand(orgCommand);
|
|
23009
24091
|
const pathwayRegressionCommand = configureCommandPresentation(
|
|
23010
|
-
new
|
|
24092
|
+
new Command4("pathway-regression").description(
|
|
23011
24093
|
"Preview, start, and inspect pathway regression runs."
|
|
23012
24094
|
)
|
|
23013
24095
|
).helpGroup("Workspace:").addHelpText(
|
|
@@ -23021,20 +24103,20 @@ ${formatExamples("Examples", [
|
|
|
23021
24103
|
])}`
|
|
23022
24104
|
);
|
|
23023
24105
|
const addPathwayRegressionAgentVersionOptions = (command) => command.addOption(
|
|
23024
|
-
new
|
|
24106
|
+
new Option4(
|
|
23025
24107
|
"--org <org>",
|
|
23026
24108
|
"Organization ID or exact organization name to use."
|
|
23027
24109
|
).helpGroup("Shared options:")
|
|
23028
24110
|
).addOption(
|
|
23029
|
-
new
|
|
24111
|
+
new Option4(
|
|
23030
24112
|
"--automation-version-id <id>",
|
|
23031
24113
|
"Automation version to test against."
|
|
23032
24114
|
).helpGroup("Pathway regression options:").makeOptionMandatory(true)
|
|
23033
24115
|
).addOption(
|
|
23034
|
-
new
|
|
24116
|
+
new Option4("--agent-version-id <id>", "Agent version to test.").helpGroup("Pathway regression options:").makeOptionMandatory(true)
|
|
23035
24117
|
);
|
|
23036
24118
|
const addPathwayRegressionPreviewOptions = (command) => addPathwayRegressionAgentVersionOptions(command).addOption(
|
|
23037
|
-
new
|
|
24119
|
+
new Option4(
|
|
23038
24120
|
"--runs-per-path <count>",
|
|
23039
24121
|
"Number of historical runs to use per pathway. Defaults to the service value."
|
|
23040
24122
|
).helpGroup("Pathway regression options:").argParser(parsePositiveIntegerOption)
|
|
@@ -23056,12 +24138,12 @@ ${formatExamples("Examples", [
|
|
|
23056
24138
|
);
|
|
23057
24139
|
});
|
|
23058
24140
|
pathwayRegressionCommand.command("results").description("Read a pathway regression run result.").addOption(
|
|
23059
|
-
new
|
|
24141
|
+
new Option4(
|
|
23060
24142
|
"--org <org>",
|
|
23061
24143
|
"Organization ID or exact organization name to use."
|
|
23062
24144
|
).helpGroup("Shared options:")
|
|
23063
24145
|
).addOption(
|
|
23064
|
-
new
|
|
24146
|
+
new Option4(
|
|
23065
24147
|
"--regression-run-id <id>",
|
|
23066
24148
|
"Pathway regression run ID to inspect."
|
|
23067
24149
|
).helpGroup("Pathway regression options:").makeOptionMandatory(true)
|
|
@@ -23072,12 +24154,12 @@ ${formatExamples("Examples", [
|
|
|
23072
24154
|
);
|
|
23073
24155
|
});
|
|
23074
24156
|
pathwayRegressionCommand.command("check-results").description("Read detailed check attempts for one replay iteration.").addOption(
|
|
23075
|
-
new
|
|
24157
|
+
new Option4(
|
|
23076
24158
|
"--org <org>",
|
|
23077
24159
|
"Organization ID or exact organization name to use."
|
|
23078
24160
|
).helpGroup("Shared options:")
|
|
23079
24161
|
).addOption(
|
|
23080
|
-
new
|
|
24162
|
+
new Option4(
|
|
23081
24163
|
"--regression-replay-iteration-id <id>",
|
|
23082
24164
|
"Pathway regression replay iteration ID to inspect."
|
|
23083
24165
|
).helpGroup("Pathway regression options:").makeOptionMandatory(true)
|
|
@@ -23088,19 +24170,29 @@ ${formatExamples("Examples", [
|
|
|
23088
24170
|
);
|
|
23089
24171
|
});
|
|
23090
24172
|
program2.addCommand(pathwayRegressionCommand);
|
|
24173
|
+
addRegressionCommands({
|
|
24174
|
+
dependencies,
|
|
24175
|
+
helpers: {
|
|
24176
|
+
requireApiClientMethod,
|
|
24177
|
+
saveLastUsedOrganization,
|
|
24178
|
+
withSelectedOrganizationAndAccessToken,
|
|
24179
|
+
writeCommandOutput
|
|
24180
|
+
},
|
|
24181
|
+
program: program2
|
|
24182
|
+
});
|
|
23091
24183
|
const pathwaysCommand = configureCommandPresentation(
|
|
23092
|
-
new
|
|
24184
|
+
new Command4("pathways").description("Inspect pathways.")
|
|
23093
24185
|
).helpGroup("Workspace:");
|
|
23094
24186
|
const pathwaySignaturesCommand = configureCommandPresentation(
|
|
23095
|
-
new
|
|
24187
|
+
new Command4("signatures").description("Inspect agent-run signatures.")
|
|
23096
24188
|
);
|
|
23097
24189
|
pathwaySignaturesCommand.command("get").description("Read an agent-run pathway signature.").addOption(
|
|
23098
|
-
new
|
|
24190
|
+
new Option4(
|
|
23099
24191
|
"--org <org>",
|
|
23100
24192
|
"Organization ID or exact organization name to use."
|
|
23101
24193
|
).helpGroup("Shared options:")
|
|
23102
24194
|
).addOption(
|
|
23103
|
-
new
|
|
24195
|
+
new Option4("--agent-run-id <id>", "Agent run ID to inspect.").helpGroup("Pathway signature options:").makeOptionMandatory(true)
|
|
23104
24196
|
).action(async function() {
|
|
23105
24197
|
await handlePathwaySignatureGetCommand(
|
|
23106
24198
|
dependencies,
|
|
@@ -23110,7 +24202,7 @@ ${formatExamples("Examples", [
|
|
|
23110
24202
|
pathwaysCommand.addCommand(pathwaySignaturesCommand);
|
|
23111
24203
|
program2.addCommand(pathwaysCommand);
|
|
23112
24204
|
const nangoCommand = configureCommandPresentation(
|
|
23113
|
-
new
|
|
24205
|
+
new Command4("nango").description(
|
|
23114
24206
|
"Inspect Nango integrations and org-scoped authentications."
|
|
23115
24207
|
)
|
|
23116
24208
|
).helpGroup("Workspace:").addHelpText(
|
|
@@ -23122,10 +24214,10 @@ ${formatExamples("Examples", [
|
|
|
23122
24214
|
])}`
|
|
23123
24215
|
);
|
|
23124
24216
|
const nangoIntegrationsCommand = configureCommandPresentation(
|
|
23125
|
-
new
|
|
24217
|
+
new Command4("integrations").description("Work with Nango integrations.")
|
|
23126
24218
|
);
|
|
23127
24219
|
nangoIntegrationsCommand.command("list").description("List Nango integrations available in the current workspace.").addOption(
|
|
23128
|
-
new
|
|
24220
|
+
new Option4(
|
|
23129
24221
|
"--org <org>",
|
|
23130
24222
|
"Organization ID or exact organization name to use."
|
|
23131
24223
|
).helpGroup("Shared options:")
|
|
@@ -23137,22 +24229,22 @@ ${formatExamples("Examples", [
|
|
|
23137
24229
|
});
|
|
23138
24230
|
nangoCommand.addCommand(nangoIntegrationsCommand);
|
|
23139
24231
|
const nangoAuthsCommand = configureCommandPresentation(
|
|
23140
|
-
new
|
|
24232
|
+
new Command4("auths").alias("authentications").description("Work with org-scoped Nango authentications.")
|
|
23141
24233
|
);
|
|
23142
24234
|
nangoAuthsCommand.command("list").description(
|
|
23143
24235
|
"List org-scoped Nango authentications and their connection IDs."
|
|
23144
24236
|
).addOption(
|
|
23145
|
-
new
|
|
24237
|
+
new Option4(
|
|
23146
24238
|
"--org <org>",
|
|
23147
24239
|
"Organization ID or exact organization name to use."
|
|
23148
24240
|
).helpGroup("Shared options:")
|
|
23149
24241
|
).addOption(
|
|
23150
|
-
new
|
|
24242
|
+
new Option4(
|
|
23151
24243
|
"--integration <integration>",
|
|
23152
24244
|
"Optional integration key to filter Nango authentications."
|
|
23153
24245
|
)
|
|
23154
24246
|
).addOption(
|
|
23155
|
-
new
|
|
24247
|
+
new Option4(
|
|
23156
24248
|
"--connection-id <connectionId>",
|
|
23157
24249
|
"Optional connection ID to filter Nango authentications."
|
|
23158
24250
|
)
|
|
@@ -23170,7 +24262,7 @@ ${formatExamples("Examples", [
|
|
|
23170
24262
|
nangoCommand.addCommand(nangoAuthsCommand);
|
|
23171
24263
|
program2.addCommand(nangoCommand);
|
|
23172
24264
|
const updateCommand = configureCommandPresentation(
|
|
23173
|
-
new
|
|
24265
|
+
new Command4("update").description(
|
|
23174
24266
|
"Update mgcl to the latest published npm release."
|
|
23175
24267
|
)
|
|
23176
24268
|
).helpGroup("Workspace:").addHelpText(
|