@getmagical/cli 0.9.1 → 0.10.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/dist/index.js CHANGED
@@ -1897,13 +1897,13 @@ var require_ast = __commonJS({
1897
1897
  helperExpression: function helperExpression(node) {
1898
1898
  return node.type === "SubExpression" || (node.type === "MustacheStatement" || node.type === "BlockStatement") && !!(node.params && node.params.length || node.hash);
1899
1899
  },
1900
- scopedId: function scopedId(path21) {
1901
- return /^\.|this\b/.test(path21.original);
1900
+ scopedId: function scopedId(path22) {
1901
+ return /^\.|this\b/.test(path22.original);
1902
1902
  },
1903
1903
  // an ID is simple if it only has one part, and that part is not
1904
1904
  // `..` or `this`.
1905
- simpleId: function simpleId(path21) {
1906
- return path21.parts.length === 1 && !AST.helpers.scopedId(path21) && !path21.depth;
1905
+ simpleId: function simpleId(path22) {
1906
+ return path22.parts.length === 1 && !AST.helpers.scopedId(path22) && !path22.depth;
1907
1907
  }
1908
1908
  }
1909
1909
  };
@@ -2973,12 +2973,12 @@ var require_helpers2 = __commonJS({
2973
2973
  loc
2974
2974
  };
2975
2975
  }
2976
- function prepareMustache(path21, params, hash, open2, strip, locInfo) {
2976
+ function prepareMustache(path22, params, hash, open2, strip, locInfo) {
2977
2977
  var escapeFlag = open2.charAt(3) || open2.charAt(2), escaped = escapeFlag !== "{" && escapeFlag !== "&";
2978
2978
  var decorator = /\*/.test(open2);
2979
2979
  return {
2980
2980
  type: decorator ? "Decorator" : "MustacheStatement",
2981
- path: path21,
2981
+ path: path22,
2982
2982
  params,
2983
2983
  hash,
2984
2984
  escaped,
@@ -3296,9 +3296,9 @@ var require_compiler = __commonJS({
3296
3296
  },
3297
3297
  DecoratorBlock: function DecoratorBlock(decorator) {
3298
3298
  var program2 = decorator.program && this.compileProgram(decorator.program);
3299
- var params = this.setupFullMustacheParams(decorator, program2, void 0), path21 = decorator.path;
3299
+ var params = this.setupFullMustacheParams(decorator, program2, void 0), path22 = decorator.path;
3300
3300
  this.useDecorators = true;
3301
- this.opcode("registerDecorator", params.length, path21.original);
3301
+ this.opcode("registerDecorator", params.length, path22.original);
3302
3302
  },
3303
3303
  PartialStatement: function PartialStatement(partial) {
3304
3304
  this.usePartial = true;
@@ -3362,46 +3362,46 @@ var require_compiler = __commonJS({
3362
3362
  }
3363
3363
  },
3364
3364
  ambiguousSexpr: function ambiguousSexpr(sexpr, program2, inverse) {
3365
- var path21 = sexpr.path, name = path21.parts[0], isBlock = program2 != null || inverse != null;
3366
- this.opcode("getContext", path21.depth);
3365
+ var path22 = sexpr.path, name = path22.parts[0], isBlock = program2 != null || inverse != null;
3366
+ this.opcode("getContext", path22.depth);
3367
3367
  this.opcode("pushProgram", program2);
3368
3368
  this.opcode("pushProgram", inverse);
3369
- path21.strict = true;
3370
- this.accept(path21);
3369
+ path22.strict = true;
3370
+ this.accept(path22);
3371
3371
  this.opcode("invokeAmbiguous", name, isBlock);
3372
3372
  },
3373
3373
  simpleSexpr: function simpleSexpr(sexpr) {
3374
- var path21 = sexpr.path;
3375
- path21.strict = true;
3376
- this.accept(path21);
3374
+ var path22 = sexpr.path;
3375
+ path22.strict = true;
3376
+ this.accept(path22);
3377
3377
  this.opcode("resolvePossibleLambda");
3378
3378
  },
3379
3379
  helperSexpr: function helperSexpr(sexpr, program2, inverse) {
3380
- var params = this.setupFullMustacheParams(sexpr, program2, inverse), path21 = sexpr.path, name = path21.parts[0];
3380
+ var params = this.setupFullMustacheParams(sexpr, program2, inverse), path22 = sexpr.path, name = path22.parts[0];
3381
3381
  if (this.options.knownHelpers[name]) {
3382
3382
  this.opcode("invokeKnownHelper", params.length, name);
3383
3383
  } else if (this.options.knownHelpersOnly) {
3384
3384
  throw new _exception2["default"]("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
3385
3385
  } else {
3386
- path21.strict = true;
3387
- path21.falsy = true;
3388
- this.accept(path21);
3389
- this.opcode("invokeHelper", params.length, path21.original, _ast2["default"].helpers.simpleId(path21));
3386
+ path22.strict = true;
3387
+ path22.falsy = true;
3388
+ this.accept(path22);
3389
+ this.opcode("invokeHelper", params.length, path22.original, _ast2["default"].helpers.simpleId(path22));
3390
3390
  }
3391
3391
  },
3392
- PathExpression: function PathExpression(path21) {
3393
- this.addDepth(path21.depth);
3394
- this.opcode("getContext", path21.depth);
3395
- var name = path21.parts[0], scoped = _ast2["default"].helpers.scopedId(path21), blockParamId = !path21.depth && !scoped && this.blockParamIndex(name);
3392
+ PathExpression: function PathExpression(path22) {
3393
+ this.addDepth(path22.depth);
3394
+ this.opcode("getContext", path22.depth);
3395
+ var name = path22.parts[0], scoped = _ast2["default"].helpers.scopedId(path22), blockParamId = !path22.depth && !scoped && this.blockParamIndex(name);
3396
3396
  if (blockParamId) {
3397
- this.opcode("lookupBlockParam", blockParamId, path21.parts);
3397
+ this.opcode("lookupBlockParam", blockParamId, path22.parts);
3398
3398
  } else if (!name) {
3399
3399
  this.opcode("pushContext");
3400
- } else if (path21.data) {
3400
+ } else if (path22.data) {
3401
3401
  this.options.data = true;
3402
- this.opcode("lookupData", path21.depth, path21.parts, path21.strict);
3402
+ this.opcode("lookupData", path22.depth, path22.parts, path22.strict);
3403
3403
  } else {
3404
- this.opcode("lookupOnContext", path21.parts, path21.falsy, path21.strict, scoped);
3404
+ this.opcode("lookupOnContext", path22.parts, path22.falsy, path22.strict, scoped);
3405
3405
  }
3406
3406
  },
3407
3407
  StringLiteral: function StringLiteral(string) {
@@ -3751,16 +3751,16 @@ var require_util = __commonJS({
3751
3751
  }
3752
3752
  exports.urlGenerate = urlGenerate;
3753
3753
  function normalize(aPath) {
3754
- var path21 = aPath;
3754
+ var path22 = aPath;
3755
3755
  var url = urlParse(aPath);
3756
3756
  if (url) {
3757
3757
  if (!url.path) {
3758
3758
  return aPath;
3759
3759
  }
3760
- path21 = url.path;
3760
+ path22 = url.path;
3761
3761
  }
3762
- var isAbsolute = exports.isAbsolute(path21);
3763
- var parts = path21.split(/\/+/);
3762
+ var isAbsolute = exports.isAbsolute(path22);
3763
+ var parts = path22.split(/\/+/);
3764
3764
  for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
3765
3765
  part = parts[i];
3766
3766
  if (part === ".") {
@@ -3777,15 +3777,15 @@ var require_util = __commonJS({
3777
3777
  }
3778
3778
  }
3779
3779
  }
3780
- path21 = parts.join("/");
3781
- if (path21 === "") {
3782
- path21 = isAbsolute ? "/" : ".";
3780
+ path22 = parts.join("/");
3781
+ if (path22 === "") {
3782
+ path22 = isAbsolute ? "/" : ".";
3783
3783
  }
3784
3784
  if (url) {
3785
- url.path = path21;
3785
+ url.path = path22;
3786
3786
  return urlGenerate(url);
3787
3787
  }
3788
- return path21;
3788
+ return path22;
3789
3789
  }
3790
3790
  exports.normalize = normalize;
3791
3791
  function join(aRoot, aPath) {
@@ -6568,8 +6568,8 @@ var require_printer = __commonJS({
6568
6568
  return this.accept(sexpr.path) + " " + params + hash;
6569
6569
  };
6570
6570
  PrintVisitor.prototype.PathExpression = function(id) {
6571
- var path21 = id.parts.join("/");
6572
- return (id.data ? "@" : "") + "PATH:" + path21;
6571
+ var path22 = id.parts.join("/");
6572
+ return (id.data ? "@" : "") + "PATH:" + path22;
6573
6573
  };
6574
6574
  PrintVisitor.prototype.StringLiteral = function(string) {
6575
6575
  return '"' + string.value + '"';
@@ -7219,7 +7219,7 @@ function getErrorMessage(error) {
7219
7219
 
7220
7220
  // src/program.ts
7221
7221
  import { randomUUID as randomUUID7 } from "node:crypto";
7222
- import path20 from "node:path";
7222
+ import path21 from "node:path";
7223
7223
  import { setTimeout as sleep2 } from "node:timers/promises";
7224
7224
 
7225
7225
  // ../common/dist/src/stdlib/json.util.js
@@ -7889,6 +7889,53 @@ function safeJsonParseWithoutLogging(json) {
7889
7889
  }
7890
7890
  }
7891
7891
 
7892
+ // ../common/dist/src/constants/agent-node-presets.js
7893
+ var AGENT_NODE_PRESET_TYPES = {
7894
+ minimal: "minimal",
7895
+ browser: "browser",
7896
+ desktop: "desktop",
7897
+ voice: "voice"
7898
+ };
7899
+ var agentNodePresetOrder = [
7900
+ AGENT_NODE_PRESET_TYPES.minimal,
7901
+ AGENT_NODE_PRESET_TYPES.browser,
7902
+ AGENT_NODE_PRESET_TYPES.desktop,
7903
+ AGENT_NODE_PRESET_TYPES.voice
7904
+ ];
7905
+ var presetToEnvironmentMap = {
7906
+ [AGENT_NODE_PRESET_TYPES.minimal]: ["minimal"],
7907
+ [AGENT_NODE_PRESET_TYPES.browser]: ["browser", "browserCoordinates"],
7908
+ [AGENT_NODE_PRESET_TYPES.desktop]: ["desktop", "desktopApp"],
7909
+ [AGENT_NODE_PRESET_TYPES.voice]: ["voice"]
7910
+ };
7911
+ var environmentToPresetMap = {
7912
+ minimal: AGENT_NODE_PRESET_TYPES.minimal,
7913
+ browser: AGENT_NODE_PRESET_TYPES.browser,
7914
+ browserCoordinates: AGENT_NODE_PRESET_TYPES.browser,
7915
+ desktop: AGENT_NODE_PRESET_TYPES.desktop,
7916
+ desktopApp: AGENT_NODE_PRESET_TYPES.desktop,
7917
+ voice: AGENT_NODE_PRESET_TYPES.voice
7918
+ };
7919
+
7920
+ // ../common/dist/src/constants/agents.js
7921
+ var defaultAgentNamesByType = {
7922
+ trigger: "Trigger Agent",
7923
+ worker: "Worker Agent",
7924
+ specialist: "Specialist Agent",
7925
+ asset: "Library Asset",
7926
+ code: "Code Agent",
7927
+ extract: "Extract Agent",
7928
+ branch: "Decision Agent",
7929
+ api: "API Agent",
7930
+ specialized: "Specialized Agent",
7931
+ [AGENT_NODE_PRESET_TYPES.minimal]: "Orchestrate Agent",
7932
+ [AGENT_NODE_PRESET_TYPES.browser]: "Browser Agent",
7933
+ [AGENT_NODE_PRESET_TYPES.desktop]: "Desktop Agent",
7934
+ [AGENT_NODE_PRESET_TYPES.voice]: "Voice Agent"
7935
+ };
7936
+ var PATHWAY_REGRESSION_RUNS_PER_PATH_DEFAULT = 2;
7937
+ var PATHWAY_REGRESSION_MAX_RUNS_PER_PATH = 20;
7938
+
7892
7939
  // ../common/dist/src/constants/automation.js
7893
7940
  var AUTOMATION_BRANCH_NAME_MAX_LENGTH = 100;
7894
7941
  var AUTOMATION_BRANCH_NAME_MAX_LENGTH_MESSAGE = `Branch name must be ${AUTOMATION_BRANCH_NAME_MAX_LENGTH} characters or fewer.`;
@@ -12394,8 +12441,8 @@ var RENDER_TEMPLATE_ERROR_REASON_CATALOG = defineErrorReasonCatalog()([
12394
12441
  ]);
12395
12442
  var storeReferencePathPattern = String.raw`store(?:\.[$A-Z_a-z][\w$]*)*`;
12396
12443
  var storeReferenceMarkdownLinkTemplateRegex = new RegExp(String.raw`(?<open>\{\{\{?)\s*\[(?<path>${storeReferencePathPattern})\]\(\s*<?https?:\/\/\k<path>>?\s*\)\s*(?<close>\}\}\}?)`, "gu");
12397
- function normalizeAutomationStoreTemplateLinkMatch([_match, open2, path21]) {
12398
- return open2 === "{{{" ? `{{{${path21}}}}` : `{{${path21}}}`;
12444
+ function normalizeAutomationStoreTemplateLinkMatch([_match, open2, path22]) {
12445
+ return open2 === "{{{" ? `{{{${path22}}}}` : `{{${path22}}}`;
12399
12446
  }
12400
12447
  function normalizeAutomationStoreTemplateLinks(template) {
12401
12448
  return template.replaceAll(storeReferenceMarkdownLinkTemplateRegex, (...args) => normalizeAutomationStoreTemplateLinkMatch(args));
@@ -12465,12 +12512,14 @@ function renderOutcomeList(outcomes) {
12465
12512
  function formatCaseHeading(label, description) {
12466
12513
  return `* **Case ${label}**: ${description}`;
12467
12514
  }
12468
- import_handlebars.default.registerHelper("renderIfElseList", (rawCases, rawElse) => {
12515
+ import_handlebars.default.registerHelper("renderIfElseList", (rawCases, rawElse, options) => {
12469
12516
  const cases = z7.array(ConditionCaseSchema).min(1).parse(rawCases);
12470
12517
  const elseOutcome = OutcomeType.optional().parse(rawElse);
12471
12518
  const hasElseOutcomes = elseOutcome !== void 0 && elseOutcome.length > 0;
12472
12519
  const totalOptions = cases.length + (hasElseOutcomes ? 1 : 0);
12473
- const preamble = `You now have ${totalOptions} option${totalOptions === 1 ? "" : "s"}:`;
12520
+ const literalStoreReferences = options.data?.literalStoreReferences === true;
12521
+ const preamble = literalStoreReferences ? `Conditional instruction: ${totalOptions} mutually exclusive case${totalOptions === 1 ? "" : "s"} (select once on entry).` : `You now have ${totalOptions} option${totalOptions === 1 ? "" : "s"}:`;
12522
+ const executionRules = "These cases are mutually exclusive alternatives, not sequential steps. Before evaluating a condition, check prior tool calls and results for outcomes already executed on this visit. If a case has begun, continue its unfinished outcomes without checking the conditions again. A successful tool result completes that outcome; when the selected case's final outcome succeeds, this entire conditional is complete and execution continues with the next instruction. Only on first entry, select the first matching case, or Otherwise if present and no condition matched. Otherwise never applies because a selected case changed its own condition. Retry failed actions within the selected case. Reevaluate only when an explicit loop or return instruction enters this conditional again.";
12474
12523
  const ifBlocks = cases.map((c, idx) => {
12475
12524
  const heading = formatCaseHeading(indexToLetters(idx), c.condition);
12476
12525
  const outcomes = renderOutcomeList(c.outcome.map((o) => o.preview));
@@ -12480,7 +12529,13 @@ ${outcomes}`;
12480
12529
  const elseHeading = formatCaseHeading(indexToLetters(cases.length), "Otherwise");
12481
12530
  const elseBlock = hasElseOutcomes ? [elseHeading, renderOutcomeList(elseOutcome.map((o) => o.preview))] : [];
12482
12531
  const fallthroughBlock = hasElseOutcomes ? [] : ["If no case matches, continue to the next instruction."];
12483
- const result = [preamble, ifBlocks, ...elseBlock, ...fallthroughBlock].join("\n");
12532
+ const result = [
12533
+ preamble,
12534
+ ...literalStoreReferences ? [executionRules] : [],
12535
+ ifBlocks,
12536
+ ...elseBlock,
12537
+ ...fallthroughBlock
12538
+ ].join("\n");
12484
12539
  return new import_handlebars.default.SafeString(result);
12485
12540
  });
12486
12541
  function isPathExpression(expr) {
@@ -13232,7 +13287,7 @@ var magicalBaseModels = [
13232
13287
  ];
13233
13288
  var DEFAULT_MODEL = "gemini-2.5-flash";
13234
13289
  var modelOptionsSchema = z11.object({
13235
- reasoningEffort: z11.enum(["low", "medium", "high", "xhigh"]).optional().describe("Reasoning effort level for models that support it. Higher effort may produce better results but takes longer. The xhigh level is available on supported OpenAI models."),
13290
+ reasoningEffort: z11.enum(["low", "medium", "high", "xhigh", "max"]).optional().describe("Reasoning effort level for models that support it. Higher effort may produce better results but takes longer. The xhigh and max levels are available on supported OpenAI models."),
13236
13291
  temperature: z11.number().min(0).max(2).optional().describe("Controls randomness in model output. 0 is deterministic, higher values (up to 2) increase creativity and randomness."),
13237
13292
  timeoutMs: z11.number().int().min(1).optional().describe("Maximum time to wait for an LLM provider request before failing through the normal result path.")
13238
13293
  });
@@ -13884,18 +13939,18 @@ var specialCommands = {
13884
13939
  // ../common/dist/src/utils/automation-store-path.util.js
13885
13940
  var AUTOMATION_STORE_ROOT_PATH = "store";
13886
13941
  var relativeStorePathRegex = /^[$A-Z_a-z][\w$]*(?:\.[$A-Z_a-z][\w$]*)*$/u;
13887
- function normalizeStoreMutationPath(path21) {
13888
- const trimmedPath = path21.trim();
13942
+ function normalizeStoreMutationPath(path22) {
13943
+ const trimmedPath = path22.trim();
13889
13944
  const rootPrefix = `${AUTOMATION_STORE_ROOT_PATH}.`;
13890
13945
  const relativePath = trimmedPath.startsWith(rootPrefix) ? trimmedPath.slice(rootPrefix.length) : trimmedPath;
13891
13946
  if (!relativeStorePathRegex.test(relativePath)) {
13892
13947
  return Err({
13893
13948
  type: "invalid-automation-store-path",
13894
- path: path21,
13949
+ path: path22,
13895
13950
  categories: ["customer_usage"],
13896
13951
  statusCode: 400,
13897
13952
  nonRetryable: true,
13898
- message: `Automation store path "${path21}" is invalid.`,
13953
+ message: `Automation store path "${path22}" is invalid.`,
13899
13954
  suggestedAction: "Use a dot path relative to the automation store, such as patient.name or provider.clinic."
13900
13955
  });
13901
13956
  }
@@ -13908,16 +13963,16 @@ function findAutomationStorePathOverlap(paths) {
13908
13963
  ...new Set(paths.map(getCanonicalAutomationStoreMutationPath))
13909
13964
  ].toSorted((left, right) => (left === AUTOMATION_STORE_ROOT_PATH ? 0 : left.split(".").length) - (right === AUTOMATION_STORE_ROOT_PATH ? 0 : right.split(".").length));
13910
13965
  for (const [index, ancestorPath] of canonicalPaths.entries()) {
13911
- const descendantPath = canonicalPaths.slice(index + 1).find((path21) => ancestorPath === AUTOMATION_STORE_ROOT_PATH || path21.startsWith(`${ancestorPath}.`));
13966
+ const descendantPath = canonicalPaths.slice(index + 1).find((path22) => ancestorPath === AUTOMATION_STORE_ROOT_PATH || path22.startsWith(`${ancestorPath}.`));
13912
13967
  if (descendantPath !== void 0) {
13913
13968
  return { ancestorPath, descendantPath };
13914
13969
  }
13915
13970
  }
13916
13971
  return void 0;
13917
13972
  }
13918
- function getCanonicalAutomationStoreMutationPath(path21) {
13919
- const normalizedPath = normalizeStoreMutationPath(path21);
13920
- return normalizedPath._tag === "Ok" ? normalizedPath.value : path21.trim();
13973
+ function getCanonicalAutomationStoreMutationPath(path22) {
13974
+ const normalizedPath = normalizeStoreMutationPath(path22);
13975
+ return normalizedPath._tag === "Ok" ? normalizedPath.value : path22.trim();
13921
13976
  }
13922
13977
 
13923
13978
  // ../common/dist/src/constants/tool-declarations.js
@@ -14066,6 +14121,15 @@ var baseToolDeclarations = {
14066
14121
  ...reportStopDataSchema.shape
14067
14122
  })
14068
14123
  },
14124
+ handOff: {
14125
+ id: "handOff",
14126
+ description: "Hand off this work item to another root agent of the same automation and end this run.",
14127
+ parameters: z16.object({
14128
+ [COMMON_PARAMETERS_KEY]: DEFAULT_COMMON_PARAMETERS,
14129
+ agentId: z16.string(),
14130
+ input: z16.record(z16.string(), z16.unknown()).optional()
14131
+ })
14132
+ },
14069
14133
  terminateRun: {
14070
14134
  id: "terminateRun",
14071
14135
  description: "End the whole run early using a configured termination code. This stops every agent in the run, not just the current one, and marks the run as early-terminated.",
@@ -14096,9 +14160,9 @@ var baseToolDeclarations = {
14096
14160
  path: []
14097
14161
  });
14098
14162
  }
14099
- const canonicalUpdatePaths = updates.map(({ path: path21 }) => getCanonicalAutomationStoreMutationPath(path21));
14163
+ const canonicalUpdatePaths = updates.map(({ path: path22 }) => getCanonicalAutomationStoreMutationPath(path22));
14100
14164
  const canonicalClearPathSet = new Set(clears.map(getCanonicalAutomationStoreMutationPath));
14101
- const conflictedUpdatePath = canonicalUpdatePaths.find((path21) => canonicalClearPathSet.has(path21));
14165
+ const conflictedUpdatePath = canonicalUpdatePaths.find((path22) => canonicalClearPathSet.has(path22));
14102
14166
  if (conflictedUpdatePath !== void 0) {
14103
14167
  context.addIssue({
14104
14168
  code: "custom",
@@ -14631,9 +14695,9 @@ var magicalApiKeyPermissionPresets = [
14631
14695
  import { z as z25 } from "zod";
14632
14696
 
14633
14697
  // ../common/dist/src/utils/agent-knowledge-base-assets.util.js
14634
- function getIsKnowledgeBaseAssetPathAllowed(path21) {
14635
- const pathSegments = path21.split("/");
14636
- if (path21.length === 0 || pathSegments.some((segment) => segment.length === 0)) {
14698
+ function getIsKnowledgeBaseAssetPathAllowed(path22) {
14699
+ const pathSegments = path22.split("/");
14700
+ if (path22.length === 0 || pathSegments.some((segment) => segment.length === 0)) {
14637
14701
  return false;
14638
14702
  }
14639
14703
  const isTopLevelAssetPath = pathSegments[0] === "assets";
@@ -14688,29 +14752,29 @@ var ApiEmbeddedFileContentTypes = [
14688
14752
  ];
14689
14753
  var API_EMBEDDED_FILE_PATH_PATTERN = /^(?:\[\*\]|[A-Za-z_$][\w$-]*)(?:\[\*\]|\.[A-Za-z_$][\w$-]*)*$/u;
14690
14754
  var API_EMBEDDED_FILE_PATH_SEGMENT_PATTERN = /\[\*\]|[A-Za-z_$][\w$-]*/gu;
14691
- function parseApiEmbeddedFilePath(path21) {
14692
- if (!API_EMBEDDED_FILE_PATH_PATTERN.test(path21)) {
14755
+ function parseApiEmbeddedFilePath(path22) {
14756
+ if (!API_EMBEDDED_FILE_PATH_PATTERN.test(path22)) {
14693
14757
  return void 0;
14694
14758
  }
14695
- return [...path21.matchAll(API_EMBEDDED_FILE_PATH_SEGMENT_PATTERN)].map(([segment]) => segment === "[*]" ? { type: "arrayWildcard" } : { key: segment, type: "property" });
14759
+ return [...path22.matchAll(API_EMBEDDED_FILE_PATH_SEGMENT_PATTERN)].map(([segment]) => segment === "[*]" ? { type: "arrayWildcard" } : { key: segment, type: "property" });
14696
14760
  }
14697
14761
  var apiAgentEmbeddedFileSchema = z17.object({
14698
- path: z17.string().trim().min(1, "Embedded file path is required.").refine((path21) => parseApiEmbeddedFilePath(path21) !== void 0, {
14762
+ path: z17.string().trim().min(1, "Embedded file path is required.").refine((path22) => parseApiEmbeddedFilePath(path22) !== void 0, {
14699
14763
  message: "Embedded file path must use object properties and [*] array wildcards."
14700
14764
  }).describe("Path to a Base64 value relative to the projected API response. Supports object properties and [*] array wildcards."),
14701
14765
  contentType: z17.enum(ApiEmbeddedFileContentTypes).describe("File type of the decoded Base64 value. Use auto to detect PDF, PNG, or JPEG from each file\u2019s contents. Unrecognized files are skipped.")
14702
14766
  }).strict();
14703
14767
  var apiAgentEmbeddedFilesSchema = z17.array(apiAgentEmbeddedFileSchema).superRefine((embeddedFiles, context) => {
14704
14768
  const paths = /* @__PURE__ */ new Set();
14705
- for (const [index, { path: path21 }] of embeddedFiles.entries()) {
14706
- if (paths.has(path21)) {
14769
+ for (const [index, { path: path22 }] of embeddedFiles.entries()) {
14770
+ if (paths.has(path22)) {
14707
14771
  context.addIssue({
14708
14772
  code: z17.ZodIssueCode.custom,
14709
- message: `Embedded file path "${path21}" can only be configured once.`,
14773
+ message: `Embedded file path "${path22}" can only be configured once.`,
14710
14774
  path: [index, "path"]
14711
14775
  });
14712
14776
  }
14713
- paths.add(path21);
14777
+ paths.add(path22);
14714
14778
  }
14715
14779
  }).describe("Base64 values to decode, upload as permanent files, and replace with file references in the projected API response.");
14716
14780
 
@@ -14720,13 +14784,13 @@ var API_REQUEST_FILE_PATH_PATTERN = /^[A-Za-z_$][\w$-]*(?:\.[A-Za-z_$][\w$-]*)*$
14720
14784
  var API_REQUEST_BASE64_FILE_HELPER_PATTERN = /^\s*\{\{\s*base64File\s+(?<sourceInput>[^{}\s]+)\s*\}\}\s*$/u;
14721
14785
  var API_REQUEST_BASE64_FILE_HELPER_USAGE_PATTERN = /\{\{\s*base64File\b/u;
14722
14786
  var API_REQUEST_BASE64_FILE_HELPER_EXAMPLE = "{{base64File fileInput}}";
14723
- function parseApiRequestFilePath(path21) {
14724
- if (!API_REQUEST_FILE_PATH_PATTERN.test(path21)) {
14787
+ function parseApiRequestFilePath(path22) {
14788
+ if (!API_REQUEST_FILE_PATH_PATTERN.test(path22)) {
14725
14789
  return void 0;
14726
14790
  }
14727
- return path21.split(".");
14791
+ return path22.split(".");
14728
14792
  }
14729
- function inspectApiRequestBase64FileHelperValue({ path: path21, value }) {
14793
+ function inspectApiRequestBase64FileHelperValue({ path: path22, value }) {
14730
14794
  const match = API_REQUEST_BASE64_FILE_HELPER_PATTERN.exec(value);
14731
14795
  if (match === null) {
14732
14796
  return API_REQUEST_BASE64_FILE_HELPER_USAGE_PATTERN.test(value) ? {
@@ -14734,7 +14798,7 @@ function inspectApiRequestBase64FileHelperValue({ path: path21, value }) {
14734
14798
  issues: [
14735
14799
  {
14736
14800
  message: `Use ${API_REQUEST_BASE64_FILE_HELPER_EXAMPLE} as the entire JSON field value.`,
14737
- path: path21
14801
+ path: path22
14738
14802
  }
14739
14803
  ]
14740
14804
  } : { helpers: [], issues: [] };
@@ -14746,24 +14810,24 @@ function inspectApiRequestBase64FileHelperValue({ path: path21, value }) {
14746
14810
  issues: [
14747
14811
  {
14748
14812
  message: "Base64 file helper input must use an object property path.",
14749
- path: path21
14813
+ path: path22
14750
14814
  }
14751
14815
  ]
14752
14816
  };
14753
14817
  }
14754
14818
  return {
14755
- helpers: [{ destinationPath: path21, sourceInput }],
14819
+ helpers: [{ destinationPath: path22, sourceInput }],
14756
14820
  issues: []
14757
14821
  };
14758
14822
  }
14759
- function inspectApiRequestBase64FileHelpers(body, path21 = []) {
14823
+ function inspectApiRequestBase64FileHelpers(body, path22 = []) {
14760
14824
  if (typeof body === "string") {
14761
- return inspectApiRequestBase64FileHelperValue({ path: path21, value: body });
14825
+ return inspectApiRequestBase64FileHelperValue({ path: path22, value: body });
14762
14826
  }
14763
14827
  if (Array.isArray(body)) {
14764
14828
  return body.reduce((inspection, value, index) => {
14765
14829
  const nestedInspection = inspectApiRequestBase64FileHelpers(value, [
14766
- ...path21,
14830
+ ...path22,
14767
14831
  index
14768
14832
  ]);
14769
14833
  return {
@@ -14777,7 +14841,7 @@ function inspectApiRequestBase64FileHelpers(body, path21 = []) {
14777
14841
  }
14778
14842
  return Object.entries(body).reduce((inspection, [key, value]) => {
14779
14843
  const nestedInspection = inspectApiRequestBase64FileHelpers(value, [
14780
- ...path21,
14844
+ ...path22,
14781
14845
  key
14782
14846
  ]);
14783
14847
  return {
@@ -14821,10 +14885,10 @@ function validateApiRequestBase64FileHelpers({ body, bodyType, context, supports
14821
14885
  }
14822
14886
  }
14823
14887
  var apiAgentRequestFileEncodingSchema = z18.object({
14824
- sourceInput: z18.string().trim().min(1, "File input is required.").refine((path21) => parseApiRequestFilePath(path21) !== void 0, {
14888
+ sourceInput: z18.string().trim().min(1, "File input is required.").refine((path22) => parseApiRequestFilePath(path22) !== void 0, {
14825
14889
  message: "File input must use an object property path."
14826
14890
  }).describe("API Agent input containing the file reference to encode."),
14827
- destinationPath: z18.string().trim().min(1, "Request field is required.").refine((path21) => parseApiRequestFilePath(path21) !== void 0, {
14891
+ destinationPath: z18.string().trim().min(1, "Request field is required.").refine((path22) => parseApiRequestFilePath(path22) !== void 0, {
14828
14892
  message: "Request field must use an object property path."
14829
14893
  }).describe("JSON request body path where the encoded value is inserted."),
14830
14894
  encoding: z18.literal("base64").describe("Encoding applied to the source file before insertion.")
@@ -15076,6 +15140,7 @@ var browserSOMEnvironmentOptionsSchema = z25.object({
15076
15140
  environment: z25.literal("browser").describe("Browser environment using Set of Marks (SOM) for element identification."),
15077
15141
  maxMediaToIncludeInMemory: z25.number().min(1).optional().describe("Maximum number of screenshots/media items to keep in the agent memory context."),
15078
15142
  somFilter: somFilterConfigSchema.optional().describe("Default SOM overlay filter to apply for each browser iteration until the somFilter tool sets or clears a session filter."),
15143
+ somFrameTimeoutMs: z25.number().int().positive().optional().describe("Timeout in milliseconds for processing each child frame during SOM generation. Defaults to REMOTE_SESSION_SOM_FRAME_TIMEOUT_MS (7000 ms) when omitted. The overall 40000 ms SOM generation limit still applies."),
15079
15144
  saveAuthCookiesAfterRun: z25.boolean().optional().describe("Whether to save authentication cookies after the run completes for reuse in future runs."),
15080
15145
  suppressNativePrint: z25.boolean().optional().describe("Suppress native window.print dialogs for the whole browser session while still recording print calls."),
15081
15146
  startingUrl: startingUrlSchema.describe("Initial URL to navigate to when the agent starts. Accepts a valid URL or a Handlebars template with agent inputs. If not provided, uses the current URL of the browser; if this is the first agent, it will be a blank page."),
@@ -15121,7 +15186,8 @@ var environmentOptionsSchema = z25.discriminatedUnion("environment", [
15121
15186
  minimalEnvironmentOptionsSchema
15122
15187
  ]).describe("Environment configuration for the agent. Determines the execution context.");
15123
15188
  var runSettingsBrowserSOMEnvironmentOptionsSchema = browserSOMEnvironmentOptionsSchema.omit({
15124
- somFilter: true
15189
+ somFilter: true,
15190
+ somFrameTimeoutMs: true
15125
15191
  }).describe("Browser environment configuration using Set of Marks (SOM) for element identification. This is the recommended browser mode for most use cases.");
15126
15192
  var runSettingsEnvironmentOptionsSchema = z25.discriminatedUnion("environment", [
15127
15193
  runSettingsBrowserSOMEnvironmentOptionsSchema,
@@ -15182,30 +15248,30 @@ function hasControlCharacter(value) {
15182
15248
  }
15183
15249
  return false;
15184
15250
  }
15185
- function isNormalizedRepoPath(path21) {
15186
- if (path21 === "/") {
15251
+ function isNormalizedRepoPath(path22) {
15252
+ if (path22 === "/") {
15187
15253
  return true;
15188
15254
  }
15189
- if (path21.length === 0 || path21.startsWith("/") || path21.startsWith("\\") || path21.includes("\\") || hasControlCharacter(path21) || windowsAbsolutePathPattern.test(path21)) {
15255
+ if (path22.length === 0 || path22.startsWith("/") || path22.startsWith("\\") || path22.includes("\\") || hasControlCharacter(path22) || windowsAbsolutePathPattern.test(path22)) {
15190
15256
  return false;
15191
15257
  }
15192
- return path21.split("/").every((segment) => segment.length > 0 && segment !== "." && segment !== ".." && segment !== ".git");
15258
+ return path22.split("/").every((segment) => segment.length > 0 && segment !== "." && segment !== ".." && segment !== ".git");
15193
15259
  }
15194
- function normalizeRepoPath(path21) {
15195
- if (path21 === "/") {
15196
- return path21;
15260
+ function normalizeRepoPath(path22) {
15261
+ if (path22 === "/") {
15262
+ return path22;
15197
15263
  }
15198
- return path21.replaceAll(/\/+$/gu, "");
15264
+ return path22.replaceAll(/\/+$/gu, "");
15199
15265
  }
15200
15266
  var skillPathPattern = /^(?:skills\/.+|automations\/[^/]+\/skills\/.+|automations\/[^/]+\/agents\/[^/]+\/skills\/.+)$/u;
15201
15267
  var skillRootPathPattern = /^(?:skills\/[^/]+|automations\/[^/]+\/skills\/[^/]+|automations\/[^/]+\/agents\/[^/]+\/skills\/[^/]+)$/u;
15202
15268
  var repoPathSchema = z25.string().min(1).transform(normalizeRepoPath).refine(isNormalizedRepoPath, {
15203
15269
  message: "Path must be a normalized repository-relative path."
15204
15270
  });
15205
- var registeredSkillPathSchema = repoPathSchema.refine((path21) => skillPathPattern.test(path21), {
15271
+ var registeredSkillPathSchema = repoPathSchema.refine((path22) => skillPathPattern.test(path22), {
15206
15272
  message: "Skill paths must be under root, automation, or automation-agent skills."
15207
15273
  });
15208
- var registeredSkillRootPathSchema = registeredSkillPathSchema.refine((path21) => skillRootPathPattern.test(path21) && !path21.endsWith("/SKILL.md"), {
15274
+ var registeredSkillRootPathSchema = registeredSkillPathSchema.refine((path22) => skillRootPathPattern.test(path22) && !path22.endsWith("/SKILL.md"), {
15209
15275
  message: "Registered skill paths must identify a skill root directory."
15210
15276
  });
15211
15277
  var knowledgeBasePluginPermissionSchema = z25.object({
@@ -15256,6 +15322,7 @@ var baseAgentConfigFieldsSchema = z25.object({
15256
15322
  taskQueue: z25.string().optional().describe("Temporal task queue name for this agent. If specified, queued child agents run on this queue instead of the parent queue."),
15257
15323
  waitUponQueueing: z25.boolean().optional().default(false).describe("If true, wait for queued child agents to complete before proceeding."),
15258
15324
  queueableAgentIds: z25.array(brandedStringValidator("agentId")).optional().default(() => []).describe("List of agent IDs that this agent can queue using the queueAgents tool. Enables the agent to run a new automation with a different agent as the starting point."),
15325
+ handOffAgentIds: z25.array(brandedStringValidator("agentId")).optional().describe("Other root agents in this automation that can receive this agent\u2019s work item through handOff. Requires root agent handoff to be enabled; targets always use the latest version."),
15259
15326
  callableAgentIds: z25.array(brandedStringValidator("agentId")).optional().describe("List of external root agent IDs that this agent can call using the callSpecializedAgent tool. Same-automation callable agents continue to be configured by graph connections."),
15260
15327
  queuedAgentVariables: z25.record(brandedStringValidator("agentId"), z25.record(z25.string(), z25.unknown())).optional().describe("Static automation variable values to pass when this agent queues another automation by target agent ID."),
15261
15328
  checkpoint: z25.object({
@@ -15266,7 +15333,7 @@ var baseAgentConfigFieldsSchema = z25.object({
15266
15333
  additionalSystemPrompt: z25.string().optional().describe("Additional instructions appended to the system prompt for this agent. Combined with automation-level additionalSystemPrompt."),
15267
15334
  // Backlinking metadata for imported agents
15268
15335
  importedFrom: z25.object({
15269
- automationId: brandedStringValidator("draftAutomationId").describe("ID of the source automation from which this agent was imported."),
15336
+ automationId: brandedStringValidator("automationId").describe("ID of the source automation from which this agent was imported."),
15270
15337
  originalAgentId: brandedStringValidator("agentId").describe("Original agent ID in the source automation.")
15271
15338
  }).optional().describe("Metadata for agents imported from another automation. Used for traceability and updates."),
15272
15339
  ignoreUnstableSessionState: z25.boolean().optional().describe("When true, skips screenshot consistency checks before tool execution. Overrides the automation-level ignoreUnstableSessionState setting."),
@@ -15340,10 +15407,11 @@ var OutcomePayloadSchema = z25.object({
15340
15407
  input: z25.record(z25.string(), z25.unknown()).describe("Input data for the outcome. Maps parameter keys to values."),
15341
15408
  preview: z25.string().describe("Rendered text representation of the outcome.")
15342
15409
  });
15410
+ var decisionIncludeScreenshotDescription = "Requires screenshot context from the calling agent. Every way this Decision can be invoked must provide one.";
15343
15411
  var branchAgentConfigSchema = baseAgentConfigFieldsSchema.safeExtend({
15344
15412
  type: z25.literal("branch").describe("Decision agent type - makes decisions to route to different agents."),
15345
15413
  model: agentModelConfigSchema.describe("LLM model configuration for this decision agent."),
15346
- includeScreenshot: z25.boolean().optional().describe("Whether to include the previous agent's screen state in this decision agent's decision context."),
15414
+ includeScreenshot: z25.boolean().optional().describe(decisionIncludeScreenshotDescription),
15347
15415
  conditionsAndOutcomes: z25.object({
15348
15416
  if: z25.array(z25.object({
15349
15417
  caseName: z25.string().describe("Name of the condition case."),
@@ -15356,7 +15424,7 @@ var branchAgentConfigSchema = baseAgentConfigFieldsSchema.safeExtend({
15356
15424
  var draftBranchAgentConfigSchema = baseAgentConfigFieldsSchema.safeExtend({
15357
15425
  type: z25.literal("branch").describe("Decision agent draft configuration. Allows incomplete conditions and outcomes while the agent is still being authored."),
15358
15426
  model: agentModelConfigSchema.describe("LLM model configuration for this decision agent."),
15359
- includeScreenshot: z25.boolean().optional().describe("Whether to include the previous agent's screen state in this decision agent's decision context."),
15427
+ includeScreenshot: z25.boolean().optional().describe(decisionIncludeScreenshotDescription),
15360
15428
  conditionsAndOutcomes: z25.object({
15361
15429
  if: z25.array(z25.object({
15362
15430
  caseName: z25.string().describe("Name of the condition case."),
@@ -15589,6 +15657,13 @@ var automationRunConfigBaseSchema = z27.object({
15589
15657
  captureActions: z27.boolean().default(false).describe("When true, attach an action recording while a draft run is paused in takeover mode."),
15590
15658
  runDraftQueuedAgents: z27.boolean().optional().describe("Draft-run-only option. When false, queue-agent actions in the draft run report success without starting downstream queued draft child runs. Omit or true preserves queueing."),
15591
15659
  allowPointOfNoReturnOverride: z27.boolean().optional().describe("Internal rerun authorization. When true, the rerun and its queued descendants may proceed past a point-of-no-return crossing owned by an earlier run."),
15660
+ rootAgentHandoffEnabled: z27.literal(true).optional().describe("Infrastructure-owned capability captured when a work-item-backed run is created. Only these runs can hand off to another root agent."),
15661
+ rootAgentHandoff: z27.object({
15662
+ automationBranchId: z27.uuid().optional().describe("Draft branch captured at run creation. Draft handoffs resolve the current head of this branch."),
15663
+ sourceAutomationRunId: z27.uuid().optional().describe("Predecessor run for an admitted handoff. This run executes the latest version resolved at admission."),
15664
+ successorAutomationRunId: z27.uuid().optional().describe("Accepted handoff receipt. The source can no longer mutate the shared Store once this is recorded."),
15665
+ stopRequestedAt: z27.iso.datetime().optional().describe("Time a stop request was recorded, preventing subsequent handoff admission.")
15666
+ }).optional().describe("Infrastructure-owned durable handoff receipt and stop-intent fence. Updated only while holding the source run lock."),
15592
15667
  pointOfNoReturnGateEnabled: z27.literal(true).optional().describe("Infrastructure-owned rollout marker. PONR is enforced only for run trees created after the gate rollout."),
15593
15668
  sla: automationRunSlaSchema.optional(),
15594
15669
  networkTrafficCapture: networkTrafficCaptureSchema.optional(),
@@ -15622,7 +15697,9 @@ var automationRunStartConfigSchema = automationRunConfigBaseSchema.omit({
15622
15697
  queueResourcePools: true,
15623
15698
  resolvedRunSettings: true,
15624
15699
  resolvedRunSettingsSource: true,
15625
- pointOfNoReturnGateEnabled: true
15700
+ pointOfNoReturnGateEnabled: true,
15701
+ rootAgentHandoffEnabled: true,
15702
+ rootAgentHandoff: true
15626
15703
  }).extend({
15627
15704
  networkTrafficCapture: networkTrafficCaptureSchema.nullable().optional().describe("Network traffic capture preference for this run. Omit to apply the implicit recording policy, pass null to explicitly disable capture, or pass a record/replay config to explicitly enable capture.")
15628
15705
  });
@@ -15843,13 +15920,13 @@ function getMentionedStandardCommand(instructions) {
15843
15920
  const normalizedInstructions = instructions.toLowerCase();
15844
15921
  return STANDARD_COMMAND_NAMES.find((commandName) => normalizedInstructions.includes(commandName.toLowerCase())) ?? null;
15845
15922
  }
15846
- function assertCustomInstructionsCommand({ commands, path: path21 }) {
15847
- const customCommands = commands.flatMap((command, commandIndex) => command["commandName"] === "custom" ? [{ command, path: `${path21}[${commandIndex.toString()}]` }] : []);
15923
+ function assertCustomInstructionsCommand({ commands, path: path22 }) {
15924
+ const customCommands = commands.flatMap((command, commandIndex) => command["commandName"] === "custom" ? [{ command, path: `${path22}[${commandIndex.toString()}]` }] : []);
15848
15925
  if (customCommands.length === 0) {
15849
15926
  return;
15850
15927
  }
15851
15928
  if (customCommands.length > MAX_CUSTOM_COMMAND_COUNT) {
15852
- throw createInvalidValueError(`${path21} contains ${customCommands.length.toString()} custom commands. Use at most ${MAX_CUSTOM_COMMAND_COUNT.toString()} short custom commands per agent. Split policy, decision, outreach, and multi-step work into catalog commands or child agents instead.`);
15929
+ throw createInvalidValueError(`${path22} contains ${customCommands.length.toString()} custom commands. Use at most ${MAX_CUSTOM_COMMAND_COUNT.toString()} short custom commands per agent. Split policy, decision, outreach, and multi-step work into catalog commands or child agents instead.`);
15853
15930
  }
15854
15931
  for (const customCommand of customCommands) {
15855
15932
  const instructions = getCustomInstructions(customCommand.command);
@@ -16231,7 +16308,7 @@ function isRecord3(value) {
16231
16308
  function validateCustomInstructionsCommands({
16232
16309
  commands,
16233
16310
  ctx,
16234
- path: path21
16311
+ path: path22
16235
16312
  }) {
16236
16313
  if (!Array.isArray(commands)) {
16237
16314
  return;
@@ -16239,14 +16316,14 @@ function validateCustomInstructionsCommands({
16239
16316
  const validationResult = fromThrowable(() => {
16240
16317
  assertCustomInstructionsCommand({
16241
16318
  commands: commands.map((command) => isRecord3(command) ? command : {}),
16242
- path: path21.join(".").replaceAll(/\.(?<index>\d+)/gu, "[$<index>]")
16319
+ path: path22.join(".").replaceAll(/\.(?<index>\d+)/gu, "[$<index>]")
16243
16320
  });
16244
16321
  }, "invalid-custom-instructions-command");
16245
16322
  if (isErr(validationResult)) {
16246
16323
  ctx.addIssue({
16247
16324
  code: "custom",
16248
16325
  message: `${getErrorMessage2(validationResult.error.cause)} Run mgcl catalog commands to find the standard command for this work.`,
16249
- path: path21
16326
+ path: path22
16250
16327
  });
16251
16328
  }
16252
16329
  }
@@ -16329,6 +16406,27 @@ var runDraftConfigInputSchema = automationRunStartConfigSchema.partial().omit({
16329
16406
  networkTrafficCapture: runDraftNetworkTrafficCaptureInputSchema.nullable().optional()
16330
16407
  }).strict();
16331
16408
  var COMMAND_CATALOG_HELP = "When authoring raw instructionsCommands, run mgcl catalog commands and prefer a standard command.";
16409
+ var LIBRARY_ASSET_WORKBENCH_SELECTION = `libraryEntityId
16410
+ rootAgentId
16411
+ currentVersionId
16412
+ updatedAt
16413
+ summary {
16414
+ name
16415
+ agentCount
16416
+ edgeCount
16417
+ rootAgentIds
16418
+ agents {
16419
+ id
16420
+ name
16421
+ type
16422
+ kind
16423
+ description
16424
+ instructions
16425
+ tools
16426
+ childAgentIds
16427
+ parentAgentIds
16428
+ }
16429
+ }`;
16332
16430
  var apiKeyAccessPolicies = {
16333
16431
  baseline: { type: "baseline" },
16334
16432
  automationRead: {
@@ -16373,6 +16471,10 @@ var apiKeyAccessPolicies = {
16373
16471
  type: "allOf",
16374
16472
  permissions: ["runs:execute", "runs:read", "store:write"]
16375
16473
  },
16474
+ libraryDenied: {
16475
+ type: "denied",
16476
+ reason: "Shared library operations do not have a public API-key permission."
16477
+ },
16376
16478
  skillsRead: {
16377
16479
  type: "allOf",
16378
16480
  permissions: ["skills:read"]
@@ -16483,6 +16585,7 @@ var agentEnvironmentOptionsSelection = ` environmentOptions {
16483
16585
  ... on AgentConfig_environmentOptions_Browser {
16484
16586
  environment
16485
16587
  somFilter
16588
+ somFrameTimeoutMs
16486
16589
  maxMediaToIncludeInMemory
16487
16590
  saveAuthCookiesAfterRun
16488
16591
  startingUrl
@@ -16961,6 +17064,320 @@ query GetCaptureContext($automationId: ID, $recordingId: ID) {
16961
17064
  metadata
16962
17065
  rawEvents
16963
17066
  }
17067
+ }`
17068
+ }),
17069
+ createOperationSpec({
17070
+ operationName: "ExportAgents",
17071
+ apiKeyAccess: {
17072
+ type: "denied",
17073
+ reason: "Agent transfer requires user login; shared library access has no API-key permission."
17074
+ },
17075
+ kind: "query",
17076
+ inputSchema: z28.object({
17077
+ ids: z28.array(z28.string().min(1)).min(1),
17078
+ libraryEntityId: z28.string().min(1).optional(),
17079
+ automationVersionId: z28.string().min(1).optional()
17080
+ }).refine(
17081
+ (input) => Boolean(input.libraryEntityId) !== Boolean(input.automationVersionId),
17082
+ {
17083
+ message: "Provide exactly one of --library-entity-id or --automation-version-id."
17084
+ }
17085
+ ),
17086
+ cli: {
17087
+ name: "export-agents",
17088
+ path: ["agents", "export"],
17089
+ description: "Export complete selected agents as portable JSON. Use --json > agents.json. Requires user login.",
17090
+ resultKey: "exportAgents",
17091
+ options: [
17092
+ stringArrayOption({
17093
+ inputKey: "ids",
17094
+ flagName: "ids",
17095
+ description: "Agent IDs, including their dependencies.",
17096
+ required: true
17097
+ }),
17098
+ stringOption({
17099
+ inputKey: "libraryEntityId",
17100
+ flagName: "library-entity-id",
17101
+ description: "Source library asset ID (exclusive with --automation-version-id)."
17102
+ }),
17103
+ stringOption({
17104
+ inputKey: "automationVersionId",
17105
+ flagName: "automation-version-id",
17106
+ description: "Source saved automation version ID."
17107
+ })
17108
+ ]
17109
+ },
17110
+ mcp: { fileName: "exportAgents.graphql" },
17111
+ document: `query ExportAgents($ids: [ID!]!, $libraryEntityId: ID, $automationVersionId: ID) {
17112
+ exportAgents(ids: $ids, libraryEntityId: $libraryEntityId, automationVersionId: $automationVersionId)
17113
+ }`
17114
+ }),
17115
+ createOperationSpec({
17116
+ operationName: "ImportAgents",
17117
+ apiKeyAccess: {
17118
+ type: "denied",
17119
+ reason: "Agent transfer requires user login; shared library access has no API-key permission."
17120
+ },
17121
+ kind: "mutation",
17122
+ inputSchema: z28.object({
17123
+ automationId: z28.string().min(1),
17124
+ baseVersionId: z28.string().min(1),
17125
+ data: z28.unknown().refine((value) => value !== void 0, {
17126
+ message: "Agent export data is required."
17127
+ })
17128
+ }),
17129
+ cli: {
17130
+ name: "import-agents",
17131
+ path: ["agents", "import"],
17132
+ description: "Append independent copies from an agent export file to a same-workspace draft. Keeps destination settings. Requires user login.",
17133
+ resultKey: "importAgents",
17134
+ options: [
17135
+ stringOption({
17136
+ inputKey: "automationId",
17137
+ flagName: "automation-id",
17138
+ description: "Destination draft automation ID.",
17139
+ required: true
17140
+ }),
17141
+ stringOption({
17142
+ inputKey: "baseVersionId",
17143
+ flagName: "base-version-id",
17144
+ description: "Current draftVersionId from a fresh automation fetch.",
17145
+ required: true
17146
+ }),
17147
+ stringOption({
17148
+ inputKey: "file",
17149
+ flagName: "file",
17150
+ description: "JSON file produced by agents export --json.",
17151
+ required: true,
17152
+ clientOnly: true
17153
+ })
17154
+ ]
17155
+ },
17156
+ mcp: { fileName: "importAgents.graphql" },
17157
+ document: `mutation ImportAgents($automationId: ID!, $baseVersionId: ID!, $data: JSON!) {
17158
+ importAgents(automationId: $automationId, baseVersionId: $baseVersionId, data: $data)
17159
+ }`
17160
+ }),
17161
+ createOperationSpec({
17162
+ operationName: "LibraryAssetSearch",
17163
+ apiKeyAccess: apiKeyAccessPolicies.libraryDenied,
17164
+ kind: "query",
17165
+ inputSchema: z28.object({
17166
+ query: z28.string().min(1).optional(),
17167
+ limit: z28.number().int().min(1).max(50).optional()
17168
+ }),
17169
+ cli: {
17170
+ name: "library-asset-search",
17171
+ path: ["library", "search"],
17172
+ description: "Find shared library assets in the current workspace by name. Omit --query to list recent assets. Requires user login.",
17173
+ resultKey: "libraryAssetSearch",
17174
+ options: [
17175
+ stringOption({
17176
+ inputKey: "query",
17177
+ flagName: "query",
17178
+ description: "Case-insensitive substring of the asset name."
17179
+ }),
17180
+ numberOption({
17181
+ inputKey: "limit",
17182
+ flagName: "limit",
17183
+ description: "Maximum assets to return (1-50, default 20)."
17184
+ })
17185
+ ]
17186
+ },
17187
+ mcp: { fileName: "libraryAssetSearch.graphql" },
17188
+ document: `query LibraryAssetSearch($query: String, $limit: Int) {
17189
+ libraryAssetSearch(query: $query, limit: $limit) {
17190
+ libraryEntityId
17191
+ rootAgentId
17192
+ name
17193
+ description
17194
+ currentVersionId
17195
+ updatedAt
17196
+ }
17197
+ }`
17198
+ }),
17199
+ createOperationSpec({
17200
+ operationName: "LibraryAssetWorkbench",
17201
+ apiKeyAccess: apiKeyAccessPolicies.libraryDenied,
17202
+ kind: "query",
17203
+ inputSchema: z28.object({
17204
+ libraryEntityId: z28.string().min(1)
17205
+ }),
17206
+ cli: {
17207
+ name: "library-asset-get",
17208
+ path: ["library", "get"],
17209
+ description: "Fetch a shared library asset and its agent tree. Requires user login.",
17210
+ resultKey: "libraryAssetWorkbench",
17211
+ options: [
17212
+ stringOption({
17213
+ inputKey: "libraryEntityId",
17214
+ flagName: "library-entity-id",
17215
+ description: "Library asset ID.",
17216
+ required: true
17217
+ })
17218
+ ]
17219
+ },
17220
+ mcp: { fileName: "libraryAssetWorkbench.graphql" },
17221
+ document: `query LibraryAssetWorkbench($libraryEntityId: ID!) {
17222
+ libraryAssetWorkbench(libraryEntityId: $libraryEntityId) {
17223
+ ${LIBRARY_ASSET_WORKBENCH_SELECTION}
17224
+ }
17225
+ }`
17226
+ }),
17227
+ createOperationSpec({
17228
+ operationName: "CreateLibraryAsset",
17229
+ apiKeyAccess: apiKeyAccessPolicies.libraryDenied,
17230
+ kind: "mutation",
17231
+ inputSchema: z28.object({
17232
+ assetName: z28.string().trim().min(1).optional()
17233
+ }),
17234
+ cli: {
17235
+ name: "create-library-asset",
17236
+ path: ["library", "create"],
17237
+ description: "Create an empty shared library asset with a single root agent. Requires user login.",
17238
+ resultKey: "createLibraryAsset",
17239
+ options: [
17240
+ stringOption({
17241
+ inputKey: "assetName",
17242
+ flagName: "name",
17243
+ description: 'Asset name. Defaults to "New Asset".'
17244
+ })
17245
+ ]
17246
+ },
17247
+ mcp: { fileName: "createLibraryAsset.graphql" },
17248
+ document: `mutation CreateLibraryAsset($assetName: String) {
17249
+ createLibraryAsset(assetName: $assetName) {
17250
+ ${LIBRARY_ASSET_WORKBENCH_SELECTION}
17251
+ }
17252
+ }`
17253
+ }),
17254
+ createOperationSpec({
17255
+ operationName: "ConvertAutomationSubtreeToLibraryAsset",
17256
+ apiKeyAccess: apiKeyAccessPolicies.libraryDenied,
17257
+ kind: "mutation",
17258
+ inputSchema: z28.object({
17259
+ draftAutomationId: z28.string().min(1),
17260
+ rootAgentId: z28.string().min(1),
17261
+ baseVersionId: z28.string().min(1),
17262
+ assetName: z28.string().trim().min(1).optional()
17263
+ }),
17264
+ cli: {
17265
+ name: "convert-to-library-asset",
17266
+ path: ["library", "convert"],
17267
+ description: "Convert an agent and its descendants in a draft automation into a new shared library asset. Requires user login.",
17268
+ resultKey: "convertAutomationSubtreeToLibraryAsset",
17269
+ options: [
17270
+ stringOption({
17271
+ inputKey: "draftAutomationId",
17272
+ flagName: "draft-automation-id",
17273
+ description: "Draft automation ID.",
17274
+ required: true
17275
+ }),
17276
+ stringOption({
17277
+ inputKey: "rootAgentId",
17278
+ flagName: "root-agent-id",
17279
+ description: "Agent that becomes the asset root.",
17280
+ required: true
17281
+ }),
17282
+ stringOption({
17283
+ inputKey: "baseVersionId",
17284
+ flagName: "base-version-id",
17285
+ description: "Current draftVersionId from a fresh automation fetch.",
17286
+ required: true
17287
+ }),
17288
+ stringOption({
17289
+ inputKey: "assetName",
17290
+ flagName: "name",
17291
+ description: "Asset name. Renames the root agent; defaults to its current name."
17292
+ })
17293
+ ]
17294
+ },
17295
+ mcp: { fileName: "convertAutomationSubtreeToLibraryAsset.graphql" },
17296
+ document: `mutation ConvertAutomationSubtreeToLibraryAsset(
17297
+ $draftAutomationId: ID!
17298
+ $rootAgentId: ID!
17299
+ $baseVersionId: ID!
17300
+ $assetName: String
17301
+ ) {
17302
+ convertAutomationSubtreeToLibraryAsset(
17303
+ draftAutomationId: $draftAutomationId
17304
+ rootAgentId: $rootAgentId
17305
+ baseVersionId: $baseVersionId
17306
+ assetName: $assetName
17307
+ ) {
17308
+ automationId
17309
+ rootAgentId
17310
+ libraryEntityId
17311
+ libraryEntityVersionId
17312
+ convertedAgentIds
17313
+ draftVersionId
17314
+ lastSavedAt
17315
+ }
17316
+ }`
17317
+ }),
17318
+ createOperationSpec({
17319
+ operationName: "ImportLibraryAssetToAutomation",
17320
+ apiKeyAccess: apiKeyAccessPolicies.libraryDenied,
17321
+ kind: "mutation",
17322
+ inputSchema: z28.object({
17323
+ draftAutomationId: z28.string().min(1),
17324
+ libraryEntityId: z28.string().min(1),
17325
+ baseVersionId: z28.string().min(1),
17326
+ parentAgentId: z28.string().min(1).optional()
17327
+ }),
17328
+ cli: {
17329
+ name: "import-library-asset",
17330
+ path: ["library", "import"],
17331
+ description: "Import a shared library asset into a draft automation, optionally under a parent agent. The automation stays linked to the asset. Requires user login.",
17332
+ resultKey: "importLibraryAssetToAutomation",
17333
+ options: [
17334
+ stringOption({
17335
+ inputKey: "draftAutomationId",
17336
+ flagName: "draft-automation-id",
17337
+ description: "Draft automation ID.",
17338
+ required: true
17339
+ }),
17340
+ stringOption({
17341
+ inputKey: "libraryEntityId",
17342
+ flagName: "library-entity-id",
17343
+ description: "Library asset ID.",
17344
+ required: true
17345
+ }),
17346
+ stringOption({
17347
+ inputKey: "baseVersionId",
17348
+ flagName: "base-version-id",
17349
+ description: "Current draftVersionId from a fresh automation fetch.",
17350
+ required: true
17351
+ }),
17352
+ stringOption({
17353
+ inputKey: "parentAgentId",
17354
+ flagName: "parent-agent-id",
17355
+ description: "Existing agent to attach the asset under. Omit to add it top-level."
17356
+ })
17357
+ ]
17358
+ },
17359
+ mcp: { fileName: "importLibraryAssetToAutomation.graphql" },
17360
+ document: `mutation ImportLibraryAssetToAutomation(
17361
+ $draftAutomationId: ID!
17362
+ $libraryEntityId: ID!
17363
+ $baseVersionId: ID!
17364
+ $parentAgentId: ID
17365
+ ) {
17366
+ importLibraryAssetToAutomation(
17367
+ draftAutomationId: $draftAutomationId
17368
+ libraryEntityId: $libraryEntityId
17369
+ baseVersionId: $baseVersionId
17370
+ parentAgentId: $parentAgentId
17371
+ ) {
17372
+ automationId
17373
+ parentAgentId
17374
+ rootAgentId
17375
+ libraryEntityId
17376
+ libraryEntityVersionId
17377
+ importedAgentIds
17378
+ draftVersionId
17379
+ lastSavedAt
17380
+ }
16964
17381
  }`
16965
17382
  }),
16966
17383
  createOperationSpec({
@@ -20700,7 +21117,7 @@ ${evalRunExportSelection}
20700
21117
  ];
20701
21118
 
20702
21119
  // src/program.ts
20703
- import { Command as Command6, InvalidArgumentError as InvalidArgumentError2, Option as Option7 } from "commander";
21120
+ import { Command as Command6, InvalidArgumentError as InvalidArgumentError3, Option as Option7 } from "commander";
20704
21121
 
20705
21122
  // src/api.ts
20706
21123
  import { randomUUID } from "node:crypto";
@@ -21469,18 +21886,18 @@ async function downloadAuthenticatedFileFromApi({
21469
21886
  organizationId,
21470
21887
  outputPath,
21471
21888
  overwrite = false,
21472
- path: path21,
21889
+ path: path22,
21473
21890
  resolveApiBaseUrl,
21474
21891
  timeoutMs
21475
21892
  }) {
21476
- if (!path21.startsWith("/") || path21.startsWith("//")) {
21893
+ if (!path22.startsWith("/") || path22.startsWith("//")) {
21477
21894
  throw new CliError(
21478
21895
  "Authenticated file download path must be relative to the configured Magical API."
21479
21896
  );
21480
21897
  }
21481
21898
  const normalizedApiBaseUrl = trimTrailingSlash(await resolveApiBaseUrl());
21482
21899
  const apiBaseResult = safeUrlConstructor(`${normalizedApiBaseUrl}/`);
21483
- const urlResult = safeUrlConstructor(`${normalizedApiBaseUrl}${path21}`);
21900
+ const urlResult = safeUrlConstructor(`${normalizedApiBaseUrl}${path22}`);
21484
21901
  if (isErr(apiBaseResult) || isErr(urlResult) || urlResult.value.origin !== apiBaseResult.value.origin || !urlResult.value.pathname.startsWith(apiBaseResult.value.pathname)) {
21485
21902
  throw new CliError(
21486
21903
  "Authenticated file download path must stay within the configured Magical API."
@@ -21577,16 +21994,16 @@ function buildPathwayRegressionAgentVersionPath({
21577
21994
  leafPath,
21578
21995
  runsPerPath
21579
21996
  }) {
21580
- const path21 = `/pathway-regression/automation-versions/${encodeURIComponent(
21997
+ const path22 = `/pathway-regression/automation-versions/${encodeURIComponent(
21581
21998
  automationVersionId
21582
21999
  )}/agent-versions/${encodeURIComponent(agentVersionId)}/${leafPath}`;
21583
22000
  if (runsPerPath === void 0) {
21584
- return path21;
22001
+ return path22;
21585
22002
  }
21586
22003
  const queryParams = new URLSearchParams({
21587
22004
  runsPerPath: String(runsPerPath)
21588
22005
  });
21589
- return `${path21}?${queryParams.toString()}`;
22006
+ return `${path22}?${queryParams.toString()}`;
21590
22007
  }
21591
22008
  function applyAuthenticationHeaders({
21592
22009
  accessToken,
@@ -21622,11 +22039,11 @@ function createFetchJson({
21622
22039
  accessToken,
21623
22040
  impersonatedOrganizationId,
21624
22041
  allowOttoAuthorization,
21625
- path: path21,
22042
+ path: path22,
21626
22043
  init,
21627
22044
  organizationId
21628
22045
  }) {
21629
- const url = `${trimTrailingSlash(await resolveApiBaseUrl())}${path21}`;
22046
+ const url = `${trimTrailingSlash(await resolveApiBaseUrl())}${path22}`;
21630
22047
  const usesWorkOSApiKey = isWorkOSApiKey(accessToken);
21631
22048
  const headers = new Headers(init?.headers);
21632
22049
  applyAuthenticationHeaders({
@@ -21826,7 +22243,7 @@ function createMagicalApiClient({
21826
22243
  organizationId,
21827
22244
  outputPath,
21828
22245
  overwrite = false,
21829
- path: path21,
22246
+ path: path22,
21830
22247
  timeoutMs
21831
22248
  }) {
21832
22249
  await downloadAuthenticatedFileFromApi({
@@ -21839,7 +22256,7 @@ function createMagicalApiClient({
21839
22256
  ...maxSizeBytes === void 0 ? {} : { maxSizeBytes },
21840
22257
  outputPath,
21841
22258
  overwrite,
21842
- path: path21,
22259
+ path: path22,
21843
22260
  resolveApiBaseUrl,
21844
22261
  ...timeoutMs === void 0 ? {} : { timeoutMs }
21845
22262
  });
@@ -22145,8 +22562,12 @@ function createMagicalApiClient({
22145
22562
  agentVersionId,
22146
22563
  automationVersionId,
22147
22564
  impersonatedOrganizationId,
22148
- organizationId
22565
+ organizationId,
22566
+ runsPerPath
22149
22567
  }) {
22568
+ const query = new URLSearchParams(
22569
+ runsPerPath === void 0 ? {} : { runsPerPath: String(runsPerPath) }
22570
+ );
22150
22571
  const parsedResponse = regressionTestKickoffResponseSchema.safeParse(
22151
22572
  await fetchJson({
22152
22573
  accessToken,
@@ -22155,7 +22576,7 @@ function createMagicalApiClient({
22155
22576
  ...organizationId ? { organizationId } : {},
22156
22577
  path: `/pathway-regression/tests/automation-versions/${encodeURIComponent(
22157
22578
  automationVersionId
22158
- )}/agent-versions/${encodeURIComponent(agentVersionId)}/run`,
22579
+ )}/agent-versions/${encodeURIComponent(agentVersionId)}/run${query.size > 0 ? `?${query.toString()}` : ""}`,
22159
22580
  init: {
22160
22581
  method: "POST"
22161
22582
  }
@@ -27943,14 +28364,14 @@ async function prepareFileUpload(inputPath, workingDirectory) {
27943
28364
  );
27944
28365
  }
27945
28366
  const checksum = await (async () => {
27946
- let value = 0;
28367
+ let value = void 0;
27947
28368
  for await (const chunk of createReadStream2(filePath)) {
27948
28369
  if (!(chunk instanceof Uint8Array)) {
27949
28370
  throw new CliError("Upload file stream returned invalid bytes.");
27950
28371
  }
27951
28372
  value = updateS3Crc32Checksum(chunk, value);
27952
28373
  }
27953
- return value;
28374
+ return value ?? updateS3Crc32Checksum(new Uint8Array());
27954
28375
  })().catch((error) => {
27955
28376
  throw new CliError(`Failed to checksum upload file "${filePath}".`, {
27956
28377
  cause: error
@@ -28968,6 +29389,55 @@ function resolveOpenCommand(url) {
28968
29389
  return { executable: "xdg-open", args: [url] };
28969
29390
  }
28970
29391
 
29392
+ // src/operation-variables.ts
29393
+ import { readFile as readFile5 } from "node:fs/promises";
29394
+ import path16 from "node:path";
29395
+ function parseOperationVariables(operationSpec, variables) {
29396
+ const parsedVariables = operationSpec.inputSchema.safeParse(variables);
29397
+ if (!parsedVariables.success) {
29398
+ throw new CliError(
29399
+ parsedVariables.error.issues[0]?.message ?? "Invalid command input."
29400
+ );
29401
+ }
29402
+ if (!isStringKeyedRecord(parsedVariables.data)) {
29403
+ throw new CliError("Invalid command input.");
29404
+ }
29405
+ return parsedVariables.data;
29406
+ }
29407
+ async function resolveOperationVariables({
29408
+ operationSpec,
29409
+ variables,
29410
+ options,
29411
+ workingDirectory = process.cwd()
29412
+ }) {
29413
+ return parseOperationVariables(
29414
+ operationSpec,
29415
+ operationSpec.operationName === "ImportAgents" ? {
29416
+ ...variables,
29417
+ data: await readAgentImportFile(options["file"], workingDirectory)
29418
+ } : variables
29419
+ );
29420
+ }
29421
+ async function readAgentImportFile(file, workingDirectory) {
29422
+ if (typeof file !== "string" || !file.trim()) {
29423
+ throw new CliError(
29424
+ "Provide --file with the JSON file produced by agents export --json."
29425
+ );
29426
+ }
29427
+ const contents = await fromThrowable(
29428
+ async () => readFile5(path16.resolve(workingDirectory, file), "utf8"),
29429
+ "read-file-error"
29430
+ );
29431
+ if (isErr(contents)) {
29432
+ throw new CliError(`Could not read agent import file: ${file}`);
29433
+ }
29434
+ const parsed = safeJsonParseWithoutLogging(contents.value);
29435
+ if (isErr(parsed)) {
29436
+ throw new CliError("Agent import file is not valid JSON.");
29437
+ }
29438
+ return parsed.value;
29439
+ }
29440
+
28971
29441
  // src/program-command-types.ts
28972
29442
  var SESSION_ONLY_API_KEY_MANAGEMENT_COMMANDS = /* @__PURE__ */ new Set([
28973
29443
  "auth keys list",
@@ -28977,7 +29447,7 @@ var SESSION_ONLY_API_KEY_MANAGEMENT_COMMANDS = /* @__PURE__ */ new Set([
28977
29447
 
28978
29448
  // src/regression-commands.ts
28979
29449
  import { setTimeout as sleep } from "node:timers/promises";
28980
- import { Command as Command4, Option as Option4 } from "commander";
29450
+ import { Command as Command4, InvalidArgumentError as InvalidArgumentError2, Option as Option4 } from "commander";
28981
29451
  var REGRESSION_TEST_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
28982
29452
  "matched",
28983
29453
  "deviated",
@@ -29104,7 +29574,8 @@ async function handleRegressionRunCommand({
29104
29574
  input: {
29105
29575
  ...authParams,
29106
29576
  agentVersionId: options.agentVersion,
29107
- automationVersionId: options.automationVersion
29577
+ automationVersionId: options.automationVersion,
29578
+ ...options.runsPerPath === void 0 ? {} : { runsPerPath: options.runsPerPath }
29108
29579
  },
29109
29580
  startRegressionTest: startAgentVersionRegressionTest
29110
29581
  });
@@ -29191,6 +29662,7 @@ function addRegressionCommands({
29191
29662
  `
29192
29663
  ${formatExamples("Examples", [
29193
29664
  "mgcl regression run --automation-version <id> --agent-version <id>",
29665
+ "mgcl regression run --automation-version <id> --agent-version <id> --runs-per-path 5",
29194
29666
  "mgcl regression show <testId>",
29195
29667
  "mgcl regression show <testId> --pathway <pathwayId>"
29196
29668
  ])}`
@@ -29209,6 +29681,19 @@ ${formatExamples("Examples", [
29209
29681
  ).helpGroup("Regression options:").makeOptionMandatory(true)
29210
29682
  ).addOption(
29211
29683
  new Option4("--agent-version <id>", "Agent version to test.").helpGroup("Regression options:").makeOptionMandatory(true)
29684
+ ).addOption(
29685
+ new Option4(
29686
+ "--runs-per-path <count>",
29687
+ `Maximum historical baseline runs per pathway (1\u2013${PATHWAY_REGRESSION_MAX_RUNS_PER_PATH}; default: ${PATHWAY_REGRESSION_RUNS_PER_PATH_DEFAULT}). Applies only to new tests; existing tests are reused unchanged.`
29688
+ ).helpGroup("Regression options:").argParser((rawValue) => {
29689
+ const count = Number(rawValue);
29690
+ if (!Number.isInteger(count) || count < 1 || count > PATHWAY_REGRESSION_MAX_RUNS_PER_PATH) {
29691
+ throw new InvalidArgumentError2(
29692
+ `Expected an integer from 1 to ${PATHWAY_REGRESSION_MAX_RUNS_PER_PATH}.`
29693
+ );
29694
+ }
29695
+ return count;
29696
+ })
29212
29697
  ).action(async function() {
29213
29698
  await handleRegressionRunCommand({
29214
29699
  dependencies,
@@ -29691,7 +30176,7 @@ function addRunEvidenceCommands({
29691
30176
  // src/self-update.ts
29692
30177
  import { spawn as spawn3 } from "node:child_process";
29693
30178
  import fs2 from "node:fs";
29694
- import path16 from "node:path";
30179
+ import path17 from "node:path";
29695
30180
  import { fileURLToPath as fileURLToPath3 } from "node:url";
29696
30181
  var CLI_PACKAGE_NAME = "@getmagical/cli";
29697
30182
  var DEFAULT_CLI_DIST_TAG2 = "latest";
@@ -29702,9 +30187,9 @@ function resolveInstalledPackageRoot({
29702
30187
  packageName
29703
30188
  }) {
29704
30189
  const packagePathSegments = packageName.split("/");
29705
- let currentPath = path16.dirname(entryFilePath);
30190
+ let currentPath = path17.dirname(entryFilePath);
29706
30191
  for (; ; ) {
29707
- const currentPathSegments = currentPath.split(path16.sep).filter(Boolean);
30192
+ const currentPathSegments = currentPath.split(path17.sep).filter(Boolean);
29708
30193
  const currentPackageSegments = currentPathSegments.slice(
29709
30194
  -packagePathSegments.length
29710
30195
  );
@@ -29713,7 +30198,7 @@ function resolveInstalledPackageRoot({
29713
30198
  )) {
29714
30199
  return currentPath;
29715
30200
  }
29716
- const parentPath = path16.dirname(currentPath);
30201
+ const parentPath = path17.dirname(currentPath);
29717
30202
  if (parentPath === currentPath) {
29718
30203
  return null;
29719
30204
  }
@@ -29723,14 +30208,14 @@ function resolveInstalledPackageRoot({
29723
30208
  function resolveInstallPrefixFromPackageRoot(packageRootPath) {
29724
30209
  let currentPath = packageRootPath;
29725
30210
  for (; ; ) {
29726
- if (path16.basename(currentPath) === "node_modules") {
29727
- const nodeModulesParentPath = path16.dirname(currentPath);
29728
- if (path16.basename(nodeModulesParentPath) === "lib") {
29729
- return path16.dirname(nodeModulesParentPath);
30211
+ if (path17.basename(currentPath) === "node_modules") {
30212
+ const nodeModulesParentPath = path17.dirname(currentPath);
30213
+ if (path17.basename(nodeModulesParentPath) === "lib") {
30214
+ return path17.dirname(nodeModulesParentPath);
29730
30215
  }
29731
30216
  return nodeModulesParentPath;
29732
30217
  }
29733
- const parentPath = path16.dirname(currentPath);
30218
+ const parentPath = path17.dirname(currentPath);
29734
30219
  if (parentPath === currentPath) {
29735
30220
  return null;
29736
30221
  }
@@ -29747,13 +30232,13 @@ function resolveManagedNpmCommand(installPrefix) {
29747
30232
  if (process.platform === "win32") {
29748
30233
  return null;
29749
30234
  }
29750
- const managedNodeExecutable = path16.join(
30235
+ const managedNodeExecutable = path17.join(
29751
30236
  installPrefix,
29752
30237
  MANAGED_NODE_SUBPATH,
29753
30238
  "bin",
29754
30239
  "node"
29755
30240
  );
29756
- const managedNpmCli = path16.join(
30241
+ const managedNpmCli = path17.join(
29757
30242
  installPrefix,
29758
30243
  MANAGED_NODE_SUBPATH,
29759
30244
  "lib",
@@ -29852,8 +30337,8 @@ async function selfUpdateInstalledCli({
29852
30337
  }
29853
30338
 
29854
30339
  // src/settings.ts
29855
- import { mkdir as mkdir4, readFile as readFile5, rm as rm4, writeFile as writeFile2 } from "node:fs/promises";
29856
- import path17 from "node:path";
30340
+ import { mkdir as mkdir4, readFile as readFile6, rm as rm4, writeFile as writeFile2 } from "node:fs/promises";
30341
+ import path18 from "node:path";
29857
30342
  import { z as z44 } from "zod";
29858
30343
  var cliSettingsSchema = z44.object({
29859
30344
  env: z44.object({
@@ -29872,13 +30357,13 @@ function hasCliSettingsOverrides(settings) {
29872
30357
  return Object.values(settings.env).some((value) => value !== void 0);
29873
30358
  }
29874
30359
  function resolveSettingsFilePath(stateFilePath) {
29875
- return path17.join(path17.dirname(stateFilePath), CLI_SETTINGS_FILE_NAME);
30360
+ return path18.join(path18.dirname(stateFilePath), CLI_SETTINGS_FILE_NAME);
29876
30361
  }
29877
30362
  function createFileSettingsStore(stateFilePath) {
29878
30363
  const settingsFilePath = resolveSettingsFilePath(stateFilePath);
29879
30364
  return {
29880
30365
  async load() {
29881
- const fileContents = await readFile5(settingsFilePath, "utf8").catch(
30366
+ const fileContents = await readFile6(settingsFilePath, "utf8").catch(
29882
30367
  (error) => {
29883
30368
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
29884
30369
  return null;
@@ -29908,7 +30393,7 @@ function createFileSettingsStore(stateFilePath) {
29908
30393
  await rm4(settingsFilePath, { force: true });
29909
30394
  return;
29910
30395
  }
29911
- await mkdir4(path17.dirname(settingsFilePath), { recursive: true });
30396
+ await mkdir4(path18.dirname(settingsFilePath), { recursive: true });
29912
30397
  await writeFile2(
29913
30398
  settingsFilePath,
29914
30399
  `${JSON.stringify(settings, null, 2)}
@@ -30076,14 +30561,14 @@ import {
30076
30561
  lstat as lstat2,
30077
30562
  mkdir as mkdir5,
30078
30563
  mkdtemp as mkdtemp2,
30079
- readFile as readFile6,
30564
+ readFile as readFile7,
30080
30565
  readdir,
30081
30566
  rename as rename4,
30082
30567
  rm as rm5,
30083
30568
  writeFile as writeFile3
30084
30569
  } from "node:fs/promises";
30085
30570
  import os3 from "node:os";
30086
- import path18 from "node:path";
30571
+ import path19 from "node:path";
30087
30572
  import { z as z45 } from "zod";
30088
30573
  var SKILLS_ROOT_PATH = "skills";
30089
30574
  var METADATA_DIRECTORY_NAME = "skill-working-copies";
@@ -30154,12 +30639,12 @@ function normalizeRootSkillPath(skill) {
30154
30639
  return `${SKILLS_ROOT_PATH}/${skillName}`;
30155
30640
  }
30156
30641
  function resolveWorkingCopyPath(workingDirectory, skillPath) {
30157
- return path18.resolve(workingDirectory, ...skillPath.split("/"));
30642
+ return path19.resolve(workingDirectory, ...skillPath.split("/"));
30158
30643
  }
30159
30644
  function resolveMetadataPath(stateFilePath, workingCopyPath) {
30160
30645
  const key = createHash3("sha256").update(workingCopyPath).digest("hex");
30161
- return path18.join(
30162
- path18.dirname(stateFilePath),
30646
+ return path19.join(
30647
+ path19.dirname(stateFilePath),
30163
30648
  METADATA_DIRECTORY_NAME,
30164
30649
  `${key}.json`
30165
30650
  );
@@ -30187,7 +30672,7 @@ function metadataFilesToSnapshot(files) {
30187
30672
  );
30188
30673
  }
30189
30674
  async function loadMetadata(metadataPath) {
30190
- const fileContents = await readFile6(metadataPath, "utf8").catch(
30675
+ const fileContents = await readFile7(metadataPath, "utf8").catch(
30191
30676
  (error) => {
30192
30677
  if (isMissingFileError3(error)) {
30193
30678
  return null;
@@ -30211,7 +30696,7 @@ async function loadMetadata(metadataPath) {
30211
30696
  return parsed.data;
30212
30697
  }
30213
30698
  async function saveMetadata(metadataPath, metadata) {
30214
- await mkdir5(path18.dirname(metadataPath), { recursive: true });
30699
+ await mkdir5(path19.dirname(metadataPath), { recursive: true });
30215
30700
  const temporaryPath = `${metadataPath}.${randomUUID6()}.tmp`;
30216
30701
  await writeFile3(temporaryPath, `${JSON.stringify(metadata, null, 2)}
30217
30702
  `, {
@@ -30288,7 +30773,7 @@ async function readDirectorySnapshot({
30288
30773
  const nextSegments = [...segments, entry.name];
30289
30774
  const relativePath = nextSegments.join("/");
30290
30775
  assertSafeRelativeFilePath(relativePath);
30291
- const filePath = path18.join(currentDirectory, entry.name);
30776
+ const filePath = path19.join(currentDirectory, entry.name);
30292
30777
  if (entry.isDirectory()) {
30293
30778
  return await visit(filePath, nextSegments);
30294
30779
  }
@@ -30297,7 +30782,7 @@ async function readDirectorySnapshot({
30297
30782
  `Skill working copy contains unsupported entry "${filePath}". Only regular files and directories are allowed.`
30298
30783
  );
30299
30784
  }
30300
- return [[`${skillPath}/${relativePath}`, await readFile6(filePath)]];
30785
+ return [[`${skillPath}/${relativePath}`, await readFile7(filePath)]];
30301
30786
  })
30302
30787
  );
30303
30788
  return nestedEntries.flat();
@@ -30323,8 +30808,8 @@ async function writeSnapshotContents(rootPath, snapshot, prefix) {
30323
30808
  [...snapshot.entries()].map(async ([filePath, content]) => {
30324
30809
  const relativePath = prefix === null ? filePath : filePath.slice(`${prefix}/`.length);
30325
30810
  assertSafeRelativeFilePath(relativePath);
30326
- const targetPath = path18.join(rootPath, ...relativePath.split("/"));
30327
- await mkdir5(path18.dirname(targetPath), { recursive: true });
30811
+ const targetPath = path19.join(rootPath, ...relativePath.split("/"));
30812
+ await mkdir5(path19.dirname(targetPath), { recursive: true });
30328
30813
  await writeFile3(targetPath, content);
30329
30814
  })
30330
30815
  );
@@ -30334,11 +30819,11 @@ async function replaceWorkingCopy({
30334
30819
  skillPath,
30335
30820
  workingCopyPath
30336
30821
  }) {
30337
- const parentPath = path18.dirname(workingCopyPath);
30822
+ const parentPath = path19.dirname(workingCopyPath);
30338
30823
  await mkdir5(parentPath, { recursive: true });
30339
- const temporaryPath = path18.join(
30824
+ const temporaryPath = path19.join(
30340
30825
  parentPath,
30341
- `.mgcl-${path18.basename(workingCopyPath)}-${randomUUID6()}.tmp`
30826
+ `.mgcl-${path19.basename(workingCopyPath)}-${randomUUID6()}.tmp`
30342
30827
  );
30343
30828
  const backupPath = `${workingCopyPath}.${randomUUID6()}.bak`;
30344
30829
  await mkdir5(temporaryPath);
@@ -30409,7 +30894,7 @@ async function clearDirectoryExceptGit(directoryPath) {
30409
30894
  const entries = await readdir(directoryPath);
30410
30895
  await Promise.all(
30411
30896
  entries.filter((entry) => entry !== ".git").map(async (entry) => {
30412
- await rm5(path18.join(directoryPath, entry), {
30897
+ await rm5(path19.join(directoryPath, entry), {
30413
30898
  force: true,
30414
30899
  recursive: true
30415
30900
  });
@@ -30421,7 +30906,7 @@ async function createPatch(before, after) {
30421
30906
  return "";
30422
30907
  }
30423
30908
  const repositoryPath = await mkdtemp2(
30424
- path18.join(os3.tmpdir(), "mgcl-skills-diff-")
30909
+ path19.join(os3.tmpdir(), "mgcl-skills-diff-")
30425
30910
  );
30426
30911
  const patchResult = await fromThrowable(async () => {
30427
30912
  await runGit(["init", "--quiet"], repositoryPath);
@@ -30743,8 +31228,8 @@ async function pushSkillWorkingCopy({
30743
31228
  }
30744
31229
 
30745
31230
  // src/state.ts
30746
- import { mkdir as mkdir6, readFile as readFile7, rm as rm6, writeFile as writeFile4 } from "node:fs/promises";
30747
- import path19 from "node:path";
31231
+ import { mkdir as mkdir6, readFile as readFile8, rm as rm6, writeFile as writeFile4 } from "node:fs/promises";
31232
+ import path20 from "node:path";
30748
31233
  import { z as z46 } from "zod";
30749
31234
  var cliAccountSchema = z46.object({
30750
31235
  clientId: z46.string().min(1),
@@ -30771,7 +31256,7 @@ function createFileStateStore(stateFilePath) {
30771
31256
  },
30772
31257
  async load() {
30773
31258
  try {
30774
- const fileContents = await readFile7(stateFilePath, "utf8");
31259
+ const fileContents = await readFile8(stateFilePath, "utf8");
30775
31260
  const parsed = cliStateSchema.safeParse(JSON.parse(fileContents));
30776
31261
  if (!parsed.success) {
30777
31262
  throw new CliError("Stored CLI state is invalid.");
@@ -30788,7 +31273,7 @@ function createFileStateStore(stateFilePath) {
30788
31273
  }
30789
31274
  },
30790
31275
  async save(state) {
30791
- await mkdir6(path19.dirname(stateFilePath), { recursive: true });
31276
+ await mkdir6(path20.dirname(stateFilePath), { recursive: true });
30792
31277
  await writeFile4(stateFilePath, `${JSON.stringify(state, null, 2)}
30793
31278
  `);
30794
31279
  }
@@ -30797,7 +31282,7 @@ function createFileStateStore(stateFilePath) {
30797
31282
  function createFileRefreshTokenStore(refreshTokenFilePath) {
30798
31283
  async function loadRefreshTokens() {
30799
31284
  try {
30800
- const fileContents = await readFile7(refreshTokenFilePath, "utf8");
31285
+ const fileContents = await readFile8(refreshTokenFilePath, "utf8");
30801
31286
  const parsed = refreshTokenFileSchema.safeParse(JSON.parse(fileContents));
30802
31287
  if (!parsed.success) {
30803
31288
  throw new CliError("Stored refresh tokens are invalid.");
@@ -30816,7 +31301,7 @@ function createFileRefreshTokenStore(refreshTokenFilePath) {
30816
31301
  }
30817
31302
  }
30818
31303
  async function saveRefreshTokens(refreshTokens) {
30819
- await mkdir6(path19.dirname(refreshTokenFilePath), { recursive: true });
31304
+ await mkdir6(path20.dirname(refreshTokenFilePath), { recursive: true });
30820
31305
  await writeFile4(
30821
31306
  refreshTokenFilePath,
30822
31307
  `${JSON.stringify(refreshTokens, null, 2)}
@@ -31053,7 +31538,7 @@ function parseCommandOptionValue(rawValue, optionSpec) {
31053
31538
  case "number": {
31054
31539
  const parsedNumber = Number(rawValue);
31055
31540
  if (Number.isNaN(parsedNumber)) {
31056
- throw new InvalidArgumentError2(
31541
+ throw new InvalidArgumentError3(
31057
31542
  `Expected a number for --${optionSpec.flagName}.`
31058
31543
  );
31059
31544
  }
@@ -31065,7 +31550,7 @@ function parseCommandOptionValue(rawValue, optionSpec) {
31065
31550
  case "json": {
31066
31551
  const parsedJson = safeJsonParse(rawValue);
31067
31552
  if (isErr(parsedJson)) {
31068
- throw new InvalidArgumentError2(
31553
+ throw new InvalidArgumentError3(
31069
31554
  `Expected valid JSON for --${optionSpec.flagName}.`
31070
31555
  );
31071
31556
  }
@@ -31098,7 +31583,7 @@ function createCliCommanderOption(optionSpec, helpGroup) {
31098
31583
  function parsePositiveIntegerOption(rawValue) {
31099
31584
  const parsedValue = Number(rawValue);
31100
31585
  if (!Number.isInteger(parsedValue) || parsedValue < 1) {
31101
- throw new InvalidArgumentError2("Expected a positive integer.");
31586
+ throw new InvalidArgumentError3("Expected a positive integer.");
31102
31587
  }
31103
31588
  return parsedValue;
31104
31589
  }
@@ -31148,18 +31633,6 @@ function collectOperationVariableInput(operationSpec, options) {
31148
31633
  }
31149
31634
  return variables;
31150
31635
  }
31151
- function parseOperationVariables(operationSpec, variables) {
31152
- const parsedVariables = operationSpec.inputSchema.safeParse(variables);
31153
- if (!parsedVariables.success) {
31154
- throw new CliError(
31155
- parsedVariables.error.issues[0]?.message ?? "Invalid command input."
31156
- );
31157
- }
31158
- if (!isRecord7(parsedVariables.data)) {
31159
- throw new CliError("Invalid command input.");
31160
- }
31161
- return parsedVariables.data;
31162
- }
31163
31636
  async function handleSelfUpdate(dependencies, options) {
31164
31637
  const { selfUpdateCli } = dependencies;
31165
31638
  if (!selfUpdateCli) {
@@ -31204,7 +31677,12 @@ async function handleOperationCommand(dependencies, operationSpec, commandOption
31204
31677
  runtime: dependencies.classifyCommandRuntime,
31205
31678
  workingDirectory: dependencies.workingDirectory ?? process.cwd()
31206
31679
  });
31207
- const variables = parseOperationVariables(operationSpec, operationVariables);
31680
+ const variables = await resolveOperationVariables({
31681
+ operationSpec,
31682
+ variables: operationVariables,
31683
+ options: commandOptions,
31684
+ workingDirectory: dependencies.workingDirectory
31685
+ });
31208
31686
  const apiKeyEnvironment = getApiKeyEnvironment(
31209
31687
  dependencies,
31210
31688
  commandOptions.apiKey
@@ -32237,12 +32715,12 @@ function createDefaultDependencies() {
32237
32715
  return resolveDeploymentTarget({ savedEnv: settings.env, selectors });
32238
32716
  };
32239
32717
  const resolveApiBaseUrl = () => deploymentTargetContext.get().apiUrl;
32240
- const accessTokenFilePath = runtimeConfig.accessTokenFilePath ?? path20.join(
32241
- path20.dirname(runtimeConfig.stateFilePath),
32718
+ const accessTokenFilePath = runtimeConfig.accessTokenFilePath ?? path21.join(
32719
+ path21.dirname(runtimeConfig.stateFilePath),
32242
32720
  CLI_ACCESS_TOKEN_FILE_NAME
32243
32721
  );
32244
- const refreshTokenFilePath = runtimeConfig.refreshTokenFilePath ?? path20.join(
32245
- path20.dirname(runtimeConfig.stateFilePath),
32722
+ const refreshTokenFilePath = runtimeConfig.refreshTokenFilePath ?? path21.join(
32723
+ path21.dirname(runtimeConfig.stateFilePath),
32246
32724
  CLI_REFRESH_TOKEN_FILE_NAME
32247
32725
  );
32248
32726
  const selfUpdateOptions = {
@@ -32260,8 +32738,8 @@ function createDefaultDependencies() {
32260
32738
  io: createConsoleIo(),
32261
32739
  openExternalUrl,
32262
32740
  orgPreferencesStore: createFileOrgPreferencesStore(
32263
- path20.join(
32264
- path20.dirname(runtimeConfig.stateFilePath),
32741
+ path21.join(
32742
+ path21.dirname(runtimeConfig.stateFilePath),
32265
32743
  "organization-preferences"
32266
32744
  )
32267
32745
  ),